From d7d66d7d4523b904c8ccc6aea3709dc0d5aa5bdc Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 19 Apr 2018 06:28:01 +0200 Subject: bsps: Move console drivers to bsps This patch is a part of the BSP source reorganization. Update #3285. --- bsps/arm/altera-cyclone-v/console/console-config.c | 158 + bsps/arm/atsam/console/console.c | 526 +++ bsps/arm/atsam/console/debug-console.c | 52 + bsps/arm/beagle/console/console-config.c | 152 + bsps/arm/csb336/console/uart.c | 476 ++ bsps/arm/csb337/console/dbgu.c | 223 + bsps/arm/csb337/console/fbcons.c | 125 + bsps/arm/csb337/console/sed1356.c | 461 ++ bsps/arm/csb337/console/uarts.c | 243 + bsps/arm/csb337/console/usart.c | 261 ++ bsps/arm/edb7312/console/uart.c | 169 + bsps/arm/gdbarmsim/console/console-io.c | 58 + bsps/arm/gumstix/console/ffuart.c | 227 + bsps/arm/gumstix/console/uarts.c | 66 + bsps/arm/imx/console/console-config.c | 382 ++ bsps/arm/lm3s69xx/console/console-config.c | 78 + bsps/arm/lm3s69xx/console/uart.c | 167 + bsps/arm/lpc176x/console/console-config.c | 192 + bsps/arm/lpc24xx/console/console-config.c | 134 + bsps/arm/lpc24xx/console/uart-probe-1.c | 40 + bsps/arm/lpc24xx/console/uart-probe-2.c | 40 + bsps/arm/lpc24xx/console/uart-probe-3.c | 40 + bsps/arm/lpc32xx/console/console-config.c | 225 + bsps/arm/lpc32xx/console/hsu.c | 208 + bsps/arm/raspberrypi/console/console-config.c | 68 + bsps/arm/raspberrypi/console/console_select.c | 114 + bsps/arm/raspberrypi/console/fb.c | 437 ++ bsps/arm/raspberrypi/console/fbcons.c | 177 + bsps/arm/raspberrypi/console/font_data.h | 4639 ++++++++++++++++++++ bsps/arm/raspberrypi/console/outch.c | 463 ++ bsps/arm/raspberrypi/console/usart.c | 167 + bsps/arm/realview-pbx-a9/console/console-config.c | 74 + bsps/arm/rtl22xx/console/lpc22xx_uart.h | 187 + bsps/arm/rtl22xx/console/uart.c | 283 ++ bsps/arm/smdk2410/console/uart.c | 242 + bsps/arm/stm32f4/console/console-config.c | 109 + bsps/arm/stm32f4/console/usart.c | 214 + bsps/arm/tms570/console/printk-support.c | 126 + bsps/arm/tms570/console/tms570-sci.c | 642 +++ bsps/arm/xilinx-zynq/console/console-config.c | 62 + bsps/arm/xilinx-zynq/console/debug-console.c | 64 + bsps/arm/xilinx-zynq/console/zynq-uart.c | 315 ++ bsps/bfin/TLL6527M/console/console.c | 181 + bsps/bfin/bf537Stamp/console/console.c | 141 + bsps/bfin/eZKit533/console/console-io.c | 126 + bsps/epiphany/epiphany_sim/console/console-io.c | 104 + bsps/i386/pc386/console/conscfg.c | 198 + bsps/i386/pc386/console/console_control.c | 71 + bsps/i386/pc386/console/console_select.c | 250 ++ bsps/i386/pc386/console/defkeymap.c | 262 ++ bsps/i386/pc386/console/exar17d15x.c | 224 + bsps/i386/pc386/console/fb_cirrus.c | 766 ++++ bsps/i386/pc386/console/fb_vesa_rm.c | 1004 +++++ bsps/i386/pc386/console/fb_vga.c | 245 ++ bsps/i386/pc386/console/gdb_select.c | 170 + bsps/i386/pc386/console/i386kbd.h | 192 + bsps/i386/pc386/console/inch.c | 300 ++ bsps/i386/pc386/console/kbd_parser.c | 47 + bsps/i386/pc386/console/keyboard.c | 881 ++++ bsps/i386/pc386/console/outch.c | 328 ++ bsps/i386/pc386/console/pc_keyb.c | 627 +++ bsps/i386/pc386/console/printk_support.c | 84 + bsps/i386/pc386/console/ps2_mouse.c | 562 +++ bsps/i386/pc386/console/ps2_mouse.h | 151 + bsps/i386/pc386/console/rtd316.c | 109 + bsps/i386/pc386/console/serial_mouse_config.c | 48 + bsps/i386/pc386/console/uart_bus_pci.c | 477 ++ bsps/i386/pc386/console/vgacons.c | 191 + bsps/i386/pc386/console/vgainit.c | 757 ++++ bsps/i386/pc386/console/videoAsm.S | 48 + bsps/i386/pc386/console/vt.c | 348 ++ bsps/lm32/shared/console/console.c | 178 + bsps/lm32/shared/console/uart.c | 73 + bsps/lm32/shared/console/uart.h | 102 + bsps/m32c/m32cbsp/console/console-io.c | 65 + bsps/m32c/m32cbsp/console/syscalls.S | 43 + bsps/m68k/av5282/console/console.c | 711 +++ bsps/m68k/csb360/console/console-io.c | 97 + bsps/m68k/gen68340/console/console.c | 690 +++ bsps/m68k/gen68340/console/m340uart.c | 311 ++ bsps/m68k/gen68360/console/console.c | 390 ++ bsps/m68k/genmcf548x/console/console.c | 843 ++++ bsps/m68k/mcf5206elite/console/console.c | 431 ++ bsps/m68k/mcf52235/console/console.c | 656 +++ bsps/m68k/mcf52235/console/debugio.c | 32 + bsps/m68k/mcf5225x/console/console.c | 689 +++ bsps/m68k/mcf5225x/console/debugio.c | 35 + bsps/m68k/mcf5235/console/console.c | 745 ++++ bsps/m68k/mcf5329/console/console.c | 668 +++ bsps/m68k/mrm332/console/console.c | 155 + bsps/m68k/mrm332/console/sci.c | 1586 +++++++ bsps/m68k/mrm332/console/sci.h | 233 + bsps/m68k/mvme147/console/console.c | 203 + bsps/m68k/mvme162/console/console.c | 277 ++ bsps/m68k/mvme167/console/console-recording.h | 572 +++ bsps/m68k/mvme167/console/console.c | 1676 +++++++ bsps/m68k/uC5282/console/console.c | 774 ++++ bsps/mips/csb350/console/console-io.c | 85 + bsps/mips/hurricane/console/console.c | 212 + bsps/mips/jmr3904/console/console-io.c | 123 + bsps/mips/malta/console/conscfg.c | 158 + bsps/mips/malta/console/printk_support.c | 54 + bsps/mips/rbtx4925/console/console-io.c | 206 + bsps/mips/rbtx4938/console/console-io.c | 209 + bsps/mips/rbtx4938/console/yamon_api.h | 631 +++ bsps/moxie/moxiesim/console/console-io.c | 69 + bsps/moxie/moxiesim/console/syscalls.S | 15 + bsps/nios2/nios2_iss/console/console.c | 98 + bsps/no_cpu/no_bsp/console/console.c | 217 + bsps/or1k/generic_or1k/console/console-config.c | 55 + bsps/or1k/generic_or1k/console/uart.c | 152 + bsps/powerpc/gen5200/console/console.c | 835 ++++ bsps/powerpc/gen83xx/console/console-config.c | 107 + bsps/powerpc/mpc55xxevb/console/console-config.c | 41 + bsps/powerpc/mpc55xxevb/console/console-esci.c | 354 ++ bsps/powerpc/mpc55xxevb/console/console-generic.c | 168 + bsps/powerpc/mpc55xxevb/console/console-linflex.c | 417 ++ bsps/powerpc/mpc8260ads/console/console.c | 458 ++ bsps/powerpc/psim/console/console-io.c | 78 + bsps/powerpc/psim/console/consupp.S | 33 + bsps/powerpc/qemuppc/console/console-io.c | 77 + bsps/powerpc/qoriq/console/console-config.c | 330 ++ bsps/powerpc/qoriq/console/uart-bridge-master.c | 181 + bsps/powerpc/qoriq/console/uart-bridge-slave.c | 195 + bsps/powerpc/shared/console/console.c | 314 ++ bsps/powerpc/shared/console/uart.c | 781 ++++ bsps/powerpc/ss555/console/console.c | 371 ++ bsps/powerpc/t32mppc/console/console.c | 128 + bsps/powerpc/tqm8xx/console/console.c | 1115 +++++ bsps/powerpc/virtex/console/consolelite.c | 425 ++ bsps/riscv/riscv_generic/console/console-io.c | 177 + bsps/sh/gensh1/console/sci.c | 358 ++ bsps/sh/gensh2/console/config.c | 130 + bsps/sh/gensh2/console/sci.c | 554 +++ bsps/sh/gensh2/console/sci_termios.c | 449 ++ bsps/sh/gensh4/console/console.c | 469 ++ bsps/sh/gensh4/console/sh4uart.c | 910 ++++ bsps/sh/shsim/console/console-debugio.c | 33 + bsps/sh/shsim/console/console-io.c | 57 + bsps/sh/shsim/console/console-support.S | 18 + bsps/shared/dev/serial/console-output-char.c | 44 + bsps/shared/dev/serial/console-polled.c | 143 + bsps/shared/dev/serial/console-termios-init.c | 65 + bsps/shared/dev/serial/console-termios.c | 81 + bsps/shared/dev/serial/getserialmouseps2.c | 26 + bsps/shared/dev/serial/printk-dummy.c | 31 + bsps/sparc/erc32/console/debugputs.c | 83 + bsps/sparc/erc32/console/erc32_console.c | 337 ++ bsps/sparc/leon2/console/console.c | 437 ++ bsps/sparc/leon2/console/debugputs.c | 87 + bsps/sparc/leon3/console/console.c | 160 + bsps/sparc/leon3/console/printk_support.c | 119 + bsps/sparc64/shared/console/conscfg.c | 115 + bsps/v850/gdbv850sim/console/console-io.c | 62 + c/src/lib/libbsp/arm/altera-cyclone-v/Makefile.am | 6 +- .../arm/altera-cyclone-v/console/console-config.c | 158 - c/src/lib/libbsp/arm/atsam/Makefile.am | 6 +- c/src/lib/libbsp/arm/atsam/console/console.c | 526 --- c/src/lib/libbsp/arm/atsam/console/debug-console.c | 52 - c/src/lib/libbsp/arm/beagle/Makefile.am | 2 +- .../lib/libbsp/arm/beagle/console/console-config.c | 152 - c/src/lib/libbsp/arm/csb336/Makefile.am | 2 +- c/src/lib/libbsp/arm/csb336/console/uart.c | 476 -- c/src/lib/libbsp/arm/csb337/Makefile.am | 10 +- c/src/lib/libbsp/arm/csb337/console/dbgu.c | 223 - c/src/lib/libbsp/arm/csb337/console/fbcons.c | 125 - c/src/lib/libbsp/arm/csb337/console/sed1356.c | 461 -- c/src/lib/libbsp/arm/csb337/console/uarts.c | 243 - c/src/lib/libbsp/arm/csb337/console/usart.c | 261 -- c/src/lib/libbsp/arm/edb7312/Makefile.am | 2 +- c/src/lib/libbsp/arm/edb7312/console/uart.c | 169 - c/src/lib/libbsp/arm/gdbarmsim/Makefile.am | 4 +- .../lib/libbsp/arm/gdbarmsim/console/console-io.c | 58 - c/src/lib/libbsp/arm/gumstix/Makefile.am | 4 +- c/src/lib/libbsp/arm/gumstix/console/ffuart.c | 227 - c/src/lib/libbsp/arm/gumstix/console/uarts.c | 66 - c/src/lib/libbsp/arm/imx/Makefile.am | 4 +- c/src/lib/libbsp/arm/imx/console/console-config.c | 382 -- c/src/lib/libbsp/arm/lm3s69xx/Makefile.am | 4 +- .../libbsp/arm/lm3s69xx/console/console-config.c | 78 - c/src/lib/libbsp/arm/lm3s69xx/console/uart.c | 167 - c/src/lib/libbsp/arm/lpc176x/Makefile.am | 6 +- .../libbsp/arm/lpc176x/console/console-config.c | 192 - c/src/lib/libbsp/arm/lpc24xx/Makefile.am | 12 +- .../libbsp/arm/lpc24xx/console/console-config.c | 134 - .../lib/libbsp/arm/lpc24xx/console/uart-probe-1.c | 40 - .../lib/libbsp/arm/lpc24xx/console/uart-probe-2.c | 40 - .../lib/libbsp/arm/lpc24xx/console/uart-probe-3.c | 40 - c/src/lib/libbsp/arm/lpc32xx/Makefile.am | 8 +- .../libbsp/arm/lpc32xx/console/console-config.c | 225 - c/src/lib/libbsp/arm/lpc32xx/console/hsu.c | 208 - c/src/lib/libbsp/arm/raspberrypi/Makefile.am | 14 +- .../arm/raspberrypi/console/console-config.c | 68 - .../arm/raspberrypi/console/console_select.c | 114 - c/src/lib/libbsp/arm/raspberrypi/console/fb.c | 437 -- c/src/lib/libbsp/arm/raspberrypi/console/fbcons.c | 177 - .../lib/libbsp/arm/raspberrypi/console/font_data.h | 4639 -------------------- c/src/lib/libbsp/arm/raspberrypi/console/outch.c | 463 -- c/src/lib/libbsp/arm/raspberrypi/console/usart.c | 167 - c/src/lib/libbsp/arm/realview-pbx-a9/Makefile.am | 8 +- .../arm/realview-pbx-a9/console/console-config.c | 74 - c/src/lib/libbsp/arm/rtl22xx/Makefile.am | 2 +- .../lib/libbsp/arm/rtl22xx/console/lpc22xx_uart.h | 187 - c/src/lib/libbsp/arm/rtl22xx/console/uart.c | 283 -- c/src/lib/libbsp/arm/smdk2410/Makefile.am | 2 +- c/src/lib/libbsp/arm/smdk2410/console/uart.c | 242 - c/src/lib/libbsp/arm/stm32f4/Makefile.am | 4 +- .../libbsp/arm/stm32f4/console/console-config.c | 109 - c/src/lib/libbsp/arm/stm32f4/console/usart.c | 214 - c/src/lib/libbsp/arm/tms570/Makefile.am | 6 +- .../lib/libbsp/arm/tms570/console/printk-support.c | 126 - c/src/lib/libbsp/arm/tms570/console/tms570-sci.c | 642 --- c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am | 8 +- .../arm/xilinx-zynq/console/console-config.c | 62 - .../libbsp/arm/xilinx-zynq/console/debug-console.c | 64 - .../lib/libbsp/arm/xilinx-zynq/console/zynq-uart.c | 315 -- c/src/lib/libbsp/bfin/TLL6527M/Makefile.am | 2 +- c/src/lib/libbsp/bfin/TLL6527M/console/console.c | 181 - c/src/lib/libbsp/bfin/bf537Stamp/Makefile.am | 2 +- c/src/lib/libbsp/bfin/bf537Stamp/console/console.c | 141 - c/src/lib/libbsp/bfin/eZKit533/Makefile.am | 2 +- .../lib/libbsp/bfin/eZKit533/console/console-io.c | 126 - c/src/lib/libbsp/epiphany/epiphany_sim/Makefile.am | 4 +- .../epiphany/epiphany_sim/console/console-io.c | 104 - c/src/lib/libbsp/i386/pc386/Makefile.am | 46 +- c/src/lib/libbsp/i386/pc386/console/conscfg.c | 198 - .../libbsp/i386/pc386/console/console_control.c | 71 - .../lib/libbsp/i386/pc386/console/console_select.c | 250 -- c/src/lib/libbsp/i386/pc386/console/defkeymap.c | 262 -- c/src/lib/libbsp/i386/pc386/console/exar17d15x.c | 224 - c/src/lib/libbsp/i386/pc386/console/fb_cirrus.c | 766 ---- c/src/lib/libbsp/i386/pc386/console/fb_vesa_rm.c | 1004 ----- c/src/lib/libbsp/i386/pc386/console/fb_vga.c | 245 -- c/src/lib/libbsp/i386/pc386/console/gdb_select.c | 170 - c/src/lib/libbsp/i386/pc386/console/i386kbd.h | 192 - c/src/lib/libbsp/i386/pc386/console/inch.c | 300 -- c/src/lib/libbsp/i386/pc386/console/kbd_parser.c | 47 - c/src/lib/libbsp/i386/pc386/console/keyboard.c | 881 ---- c/src/lib/libbsp/i386/pc386/console/outch.c | 328 -- c/src/lib/libbsp/i386/pc386/console/pc_keyb.c | 627 --- .../lib/libbsp/i386/pc386/console/printk_support.c | 84 - c/src/lib/libbsp/i386/pc386/console/ps2_mouse.c | 562 --- c/src/lib/libbsp/i386/pc386/console/ps2_mouse.h | 151 - c/src/lib/libbsp/i386/pc386/console/rtd316.c | 109 - .../i386/pc386/console/serial_mouse_config.c | 48 - c/src/lib/libbsp/i386/pc386/console/uart_bus_pci.c | 477 -- c/src/lib/libbsp/i386/pc386/console/vgacons.c | 191 - c/src/lib/libbsp/i386/pc386/console/vgainit.c | 757 ---- c/src/lib/libbsp/i386/pc386/console/videoAsm.S | 48 - c/src/lib/libbsp/i386/pc386/console/vt.c | 348 -- c/src/lib/libbsp/lm32/lm32_evr/Makefile.am | 4 +- c/src/lib/libbsp/lm32/shared/console/console.c | 178 - c/src/lib/libbsp/lm32/shared/console/uart.c | 73 - c/src/lib/libbsp/lm32/shared/console/uart.h | 102 - c/src/lib/libbsp/m32c/m32cbsp/Makefile.am | 6 +- c/src/lib/libbsp/m32c/m32cbsp/console/console-io.c | 65 - c/src/lib/libbsp/m32c/m32cbsp/console/syscalls.S | 43 - c/src/lib/libbsp/m68k/av5282/Makefile.am | 2 +- c/src/lib/libbsp/m68k/av5282/console/console.c | 711 --- c/src/lib/libbsp/m68k/csb360/Makefile.am | 4 +- c/src/lib/libbsp/m68k/csb360/console/console-io.c | 97 - c/src/lib/libbsp/m68k/gen68340/Makefile.am | 6 +- c/src/lib/libbsp/m68k/gen68340/console/console.c | 690 --- c/src/lib/libbsp/m68k/gen68340/console/m340uart.c | 311 -- c/src/lib/libbsp/m68k/gen68360/Makefile.am | 4 +- c/src/lib/libbsp/m68k/gen68360/console/console.c | 390 -- c/src/lib/libbsp/m68k/genmcf548x/Makefile.am | 2 +- c/src/lib/libbsp/m68k/genmcf548x/console/console.c | 843 ---- c/src/lib/libbsp/m68k/mcf5206elite/Makefile.am | 4 +- .../lib/libbsp/m68k/mcf5206elite/console/console.c | 431 -- c/src/lib/libbsp/m68k/mcf52235/Makefile.am | 4 +- c/src/lib/libbsp/m68k/mcf52235/console/console.c | 656 --- c/src/lib/libbsp/m68k/mcf52235/console/debugio.c | 32 - c/src/lib/libbsp/m68k/mcf5225x/Makefile.am | 4 +- c/src/lib/libbsp/m68k/mcf5225x/console/console.c | 689 --- c/src/lib/libbsp/m68k/mcf5225x/console/debugio.c | 35 - c/src/lib/libbsp/m68k/mcf5235/Makefile.am | 2 +- c/src/lib/libbsp/m68k/mcf5235/console/console.c | 745 ---- c/src/lib/libbsp/m68k/mcf5329/Makefile.am | 2 +- c/src/lib/libbsp/m68k/mcf5329/console/console.c | 668 --- c/src/lib/libbsp/m68k/mrm332/Makefile.am | 4 +- c/src/lib/libbsp/m68k/mrm332/console/console.c | 155 - c/src/lib/libbsp/m68k/mrm332/console/sci.c | 1586 ------- c/src/lib/libbsp/m68k/mrm332/console/sci.h | 233 - c/src/lib/libbsp/m68k/mvme147/Makefile.am | 4 +- c/src/lib/libbsp/m68k/mvme147/console/console.c | 203 - c/src/lib/libbsp/m68k/mvme147s/Makefile.am | 2 +- c/src/lib/libbsp/m68k/mvme162/Makefile.am | 2 +- c/src/lib/libbsp/m68k/mvme162/console/console.c | 277 -- c/src/lib/libbsp/m68k/mvme167/Makefile.am | 2 +- .../m68k/mvme167/console/console-recording.h | 572 --- c/src/lib/libbsp/m68k/mvme167/console/console.c | 1676 ------- c/src/lib/libbsp/m68k/uC5282/Makefile.am | 2 +- c/src/lib/libbsp/m68k/uC5282/console/console.c | 774 ---- c/src/lib/libbsp/mips/csb350/Makefile.am | 4 +- c/src/lib/libbsp/mips/csb350/console/console-io.c | 85 - c/src/lib/libbsp/mips/hurricane/Makefile.am | 2 +- c/src/lib/libbsp/mips/hurricane/console/console.c | 212 - c/src/lib/libbsp/mips/jmr3904/Makefile.am | 4 +- c/src/lib/libbsp/mips/jmr3904/console/console-io.c | 123 - c/src/lib/libbsp/mips/malta/Makefile.am | 4 +- c/src/lib/libbsp/mips/malta/console/conscfg.c | 158 - .../lib/libbsp/mips/malta/console/printk_support.c | 54 - c/src/lib/libbsp/mips/rbtx4925/Makefile.am | 2 +- .../lib/libbsp/mips/rbtx4925/console/console-io.c | 206 - c/src/lib/libbsp/mips/rbtx4938/Makefile.am | 2 +- .../lib/libbsp/mips/rbtx4938/console/console-io.c | 209 - c/src/lib/libbsp/mips/rbtx4938/console/yamon_api.h | 631 --- c/src/lib/libbsp/moxie/moxiesim/Makefile.am | 6 +- .../lib/libbsp/moxie/moxiesim/console/console-io.c | 69 - c/src/lib/libbsp/moxie/moxiesim/console/syscalls.S | 15 - c/src/lib/libbsp/nios2/nios2_iss/Makefile.am | 4 +- c/src/lib/libbsp/nios2/nios2_iss/console/console.c | 98 - c/src/lib/libbsp/no_cpu/no_bsp/Makefile.am | 2 +- c/src/lib/libbsp/no_cpu/no_bsp/console/console.c | 217 - c/src/lib/libbsp/or1k/generic_or1k/Makefile.am | 4 +- .../or1k/generic_or1k/console/console-config.c | 55 - c/src/lib/libbsp/or1k/generic_or1k/console/uart.c | 152 - c/src/lib/libbsp/powerpc/beatnik/Makefile.am | 4 +- c/src/lib/libbsp/powerpc/gen5200/Makefile.am | 2 +- c/src/lib/libbsp/powerpc/gen5200/console/console.c | 835 ---- c/src/lib/libbsp/powerpc/gen83xx/Makefile.am | 6 +- .../powerpc/gen83xx/console/console-config.c | 107 - c/src/lib/libbsp/powerpc/haleakala/Makefile.am | 4 +- .../libbsp/powerpc/motorola_powerpc/Makefile.am | 4 +- c/src/lib/libbsp/powerpc/mpc55xxevb/Makefile.am | 8 +- .../powerpc/mpc55xxevb/console/console-config.c | 41 - .../powerpc/mpc55xxevb/console/console-esci.c | 354 -- .../powerpc/mpc55xxevb/console/console-generic.c | 168 - .../powerpc/mpc55xxevb/console/console-linflex.c | 417 -- c/src/lib/libbsp/powerpc/mpc8260ads/Makefile.am | 2 +- .../libbsp/powerpc/mpc8260ads/console/console.c | 458 -- c/src/lib/libbsp/powerpc/mvme3100/Makefile.am | 4 +- c/src/lib/libbsp/powerpc/mvme5500/Makefile.am | 4 +- c/src/lib/libbsp/powerpc/psim/Makefile.am | 6 +- c/src/lib/libbsp/powerpc/psim/console/console-io.c | 78 - c/src/lib/libbsp/powerpc/psim/console/consupp.S | 33 - c/src/lib/libbsp/powerpc/qemuppc/Makefile.am | 4 +- .../libbsp/powerpc/qemuppc/console/console-io.c | 77 - c/src/lib/libbsp/powerpc/qoriq/Makefile.am | 10 +- .../libbsp/powerpc/qoriq/console/console-config.c | 330 -- .../powerpc/qoriq/console/uart-bridge-master.c | 181 - .../powerpc/qoriq/console/uart-bridge-slave.c | 195 - c/src/lib/libbsp/powerpc/shared/console/console.c | 314 -- c/src/lib/libbsp/powerpc/shared/console/uart.c | 781 ---- c/src/lib/libbsp/powerpc/ss555/Makefile.am | 2 +- c/src/lib/libbsp/powerpc/ss555/console/console.c | 371 -- c/src/lib/libbsp/powerpc/t32mppc/Makefile.am | 4 +- c/src/lib/libbsp/powerpc/t32mppc/console/console.c | 128 - c/src/lib/libbsp/powerpc/tqm8xx/Makefile.am | 2 +- c/src/lib/libbsp/powerpc/tqm8xx/console/console.c | 1115 ----- c/src/lib/libbsp/powerpc/virtex/Makefile.am | 2 +- .../libbsp/powerpc/virtex/console/consolelite.c | 425 -- c/src/lib/libbsp/powerpc/virtex4/Makefile.am | 2 +- c/src/lib/libbsp/powerpc/virtex5/Makefile.am | 2 +- c/src/lib/libbsp/riscv/riscv_generic/Makefile.am | 4 +- .../riscv/riscv_generic/console/console-io.c | 177 - c/src/lib/libbsp/sh/gensh1/Makefile.am | 4 +- c/src/lib/libbsp/sh/gensh1/console/sci.c | 358 -- c/src/lib/libbsp/sh/gensh2/Makefile.am | 8 +- c/src/lib/libbsp/sh/gensh2/console/config.c | 130 - c/src/lib/libbsp/sh/gensh2/console/sci.c | 554 --- c/src/lib/libbsp/sh/gensh2/console/sci_termios.c | 449 -- c/src/lib/libbsp/sh/gensh4/Makefile.am | 6 +- c/src/lib/libbsp/sh/gensh4/console/console.c | 469 -- c/src/lib/libbsp/sh/gensh4/console/sh4uart.c | 910 ---- c/src/lib/libbsp/sh/shsim/Makefile.am | 8 +- .../lib/libbsp/sh/shsim/console/console-debugio.c | 33 - c/src/lib/libbsp/sh/shsim/console/console-io.c | 57 - .../lib/libbsp/sh/shsim/console/console-support.S | 18 - c/src/lib/libbsp/shared/console-output-char.c | 44 - c/src/lib/libbsp/shared/console-polled.c | 143 - c/src/lib/libbsp/shared/console-termios-init.c | 65 - c/src/lib/libbsp/shared/console-termios.c | 81 - c/src/lib/libbsp/shared/dummy_printk_support.c | 31 - c/src/lib/libbsp/shared/get-serial-mouse-ps2.c | 26 - c/src/lib/libbsp/sparc/erc32/Makefile.am | 4 +- c/src/lib/libbsp/sparc/erc32/console/debugputs.c | 83 - .../lib/libbsp/sparc/erc32/console/erc32_console.c | 337 -- c/src/lib/libbsp/sparc/leon2/Makefile.am | 4 +- c/src/lib/libbsp/sparc/leon2/console/console.c | 437 -- c/src/lib/libbsp/sparc/leon2/console/debugputs.c | 87 - c/src/lib/libbsp/sparc/leon3/Makefile.am | 6 +- c/src/lib/libbsp/sparc/leon3/console/console.c | 160 - .../libbsp/sparc/leon3/console/printk_support.c | 119 - c/src/lib/libbsp/sparc64/niagara/Makefile.am | 2 +- c/src/lib/libbsp/sparc64/shared/console/conscfg.c | 115 - c/src/lib/libbsp/sparc64/usiii/Makefile.am | 2 +- c/src/lib/libbsp/v850/gdbv850sim/Makefile.am | 4 +- .../libbsp/v850/gdbv850sim/console/console-io.c | 62 - 390 files changed, 48044 insertions(+), 48044 deletions(-) create mode 100644 bsps/arm/altera-cyclone-v/console/console-config.c create mode 100644 bsps/arm/atsam/console/console.c create mode 100644 bsps/arm/atsam/console/debug-console.c create mode 100644 bsps/arm/beagle/console/console-config.c create mode 100644 bsps/arm/csb336/console/uart.c create mode 100644 bsps/arm/csb337/console/dbgu.c create mode 100644 bsps/arm/csb337/console/fbcons.c create mode 100644 bsps/arm/csb337/console/sed1356.c create mode 100644 bsps/arm/csb337/console/uarts.c create mode 100644 bsps/arm/csb337/console/usart.c create mode 100644 bsps/arm/edb7312/console/uart.c create mode 100644 bsps/arm/gdbarmsim/console/console-io.c create mode 100644 bsps/arm/gumstix/console/ffuart.c create mode 100644 bsps/arm/gumstix/console/uarts.c create mode 100644 bsps/arm/imx/console/console-config.c create mode 100644 bsps/arm/lm3s69xx/console/console-config.c create mode 100644 bsps/arm/lm3s69xx/console/uart.c create mode 100644 bsps/arm/lpc176x/console/console-config.c create mode 100644 bsps/arm/lpc24xx/console/console-config.c create mode 100644 bsps/arm/lpc24xx/console/uart-probe-1.c create mode 100644 bsps/arm/lpc24xx/console/uart-probe-2.c create mode 100644 bsps/arm/lpc24xx/console/uart-probe-3.c create mode 100644 bsps/arm/lpc32xx/console/console-config.c create mode 100644 bsps/arm/lpc32xx/console/hsu.c create mode 100644 bsps/arm/raspberrypi/console/console-config.c create mode 100644 bsps/arm/raspberrypi/console/console_select.c create mode 100644 bsps/arm/raspberrypi/console/fb.c create mode 100644 bsps/arm/raspberrypi/console/fbcons.c create mode 100644 bsps/arm/raspberrypi/console/font_data.h create mode 100644 bsps/arm/raspberrypi/console/outch.c create mode 100644 bsps/arm/raspberrypi/console/usart.c create mode 100644 bsps/arm/realview-pbx-a9/console/console-config.c create mode 100644 bsps/arm/rtl22xx/console/lpc22xx_uart.h create mode 100644 bsps/arm/rtl22xx/console/uart.c create mode 100644 bsps/arm/smdk2410/console/uart.c create mode 100644 bsps/arm/stm32f4/console/console-config.c create mode 100644 bsps/arm/stm32f4/console/usart.c create mode 100644 bsps/arm/tms570/console/printk-support.c create mode 100644 bsps/arm/tms570/console/tms570-sci.c create mode 100644 bsps/arm/xilinx-zynq/console/console-config.c create mode 100644 bsps/arm/xilinx-zynq/console/debug-console.c create mode 100644 bsps/arm/xilinx-zynq/console/zynq-uart.c create mode 100644 bsps/bfin/TLL6527M/console/console.c create mode 100644 bsps/bfin/bf537Stamp/console/console.c create mode 100644 bsps/bfin/eZKit533/console/console-io.c create mode 100644 bsps/epiphany/epiphany_sim/console/console-io.c create mode 100644 bsps/i386/pc386/console/conscfg.c create mode 100644 bsps/i386/pc386/console/console_control.c create mode 100644 bsps/i386/pc386/console/console_select.c create mode 100644 bsps/i386/pc386/console/defkeymap.c create mode 100644 bsps/i386/pc386/console/exar17d15x.c create mode 100644 bsps/i386/pc386/console/fb_cirrus.c create mode 100644 bsps/i386/pc386/console/fb_vesa_rm.c create mode 100644 bsps/i386/pc386/console/fb_vga.c create mode 100644 bsps/i386/pc386/console/gdb_select.c create mode 100644 bsps/i386/pc386/console/i386kbd.h create mode 100644 bsps/i386/pc386/console/inch.c create mode 100644 bsps/i386/pc386/console/kbd_parser.c create mode 100644 bsps/i386/pc386/console/keyboard.c create mode 100644 bsps/i386/pc386/console/outch.c create mode 100644 bsps/i386/pc386/console/pc_keyb.c create mode 100644 bsps/i386/pc386/console/printk_support.c create mode 100644 bsps/i386/pc386/console/ps2_mouse.c create mode 100644 bsps/i386/pc386/console/ps2_mouse.h create mode 100644 bsps/i386/pc386/console/rtd316.c create mode 100644 bsps/i386/pc386/console/serial_mouse_config.c create mode 100644 bsps/i386/pc386/console/uart_bus_pci.c create mode 100644 bsps/i386/pc386/console/vgacons.c create mode 100644 bsps/i386/pc386/console/vgainit.c create mode 100644 bsps/i386/pc386/console/videoAsm.S create mode 100644 bsps/i386/pc386/console/vt.c create mode 100644 bsps/lm32/shared/console/console.c create mode 100644 bsps/lm32/shared/console/uart.c create mode 100644 bsps/lm32/shared/console/uart.h create mode 100644 bsps/m32c/m32cbsp/console/console-io.c create mode 100644 bsps/m32c/m32cbsp/console/syscalls.S create mode 100644 bsps/m68k/av5282/console/console.c create mode 100644 bsps/m68k/csb360/console/console-io.c create mode 100644 bsps/m68k/gen68340/console/console.c create mode 100644 bsps/m68k/gen68340/console/m340uart.c create mode 100644 bsps/m68k/gen68360/console/console.c create mode 100644 bsps/m68k/genmcf548x/console/console.c create mode 100644 bsps/m68k/mcf5206elite/console/console.c create mode 100644 bsps/m68k/mcf52235/console/console.c create mode 100644 bsps/m68k/mcf52235/console/debugio.c create mode 100644 bsps/m68k/mcf5225x/console/console.c create mode 100644 bsps/m68k/mcf5225x/console/debugio.c create mode 100644 bsps/m68k/mcf5235/console/console.c create mode 100644 bsps/m68k/mcf5329/console/console.c create mode 100644 bsps/m68k/mrm332/console/console.c create mode 100644 bsps/m68k/mrm332/console/sci.c create mode 100644 bsps/m68k/mrm332/console/sci.h create mode 100644 bsps/m68k/mvme147/console/console.c create mode 100644 bsps/m68k/mvme162/console/console.c create mode 100644 bsps/m68k/mvme167/console/console-recording.h create mode 100644 bsps/m68k/mvme167/console/console.c create mode 100644 bsps/m68k/uC5282/console/console.c create mode 100644 bsps/mips/csb350/console/console-io.c create mode 100644 bsps/mips/hurricane/console/console.c create mode 100644 bsps/mips/jmr3904/console/console-io.c create mode 100644 bsps/mips/malta/console/conscfg.c create mode 100644 bsps/mips/malta/console/printk_support.c create mode 100644 bsps/mips/rbtx4925/console/console-io.c create mode 100644 bsps/mips/rbtx4938/console/console-io.c create mode 100644 bsps/mips/rbtx4938/console/yamon_api.h create mode 100644 bsps/moxie/moxiesim/console/console-io.c create mode 100644 bsps/moxie/moxiesim/console/syscalls.S create mode 100644 bsps/nios2/nios2_iss/console/console.c create mode 100644 bsps/no_cpu/no_bsp/console/console.c create mode 100644 bsps/or1k/generic_or1k/console/console-config.c create mode 100644 bsps/or1k/generic_or1k/console/uart.c create mode 100644 bsps/powerpc/gen5200/console/console.c create mode 100644 bsps/powerpc/gen83xx/console/console-config.c create mode 100644 bsps/powerpc/mpc55xxevb/console/console-config.c create mode 100644 bsps/powerpc/mpc55xxevb/console/console-esci.c create mode 100644 bsps/powerpc/mpc55xxevb/console/console-generic.c create mode 100644 bsps/powerpc/mpc55xxevb/console/console-linflex.c create mode 100644 bsps/powerpc/mpc8260ads/console/console.c create mode 100644 bsps/powerpc/psim/console/console-io.c create mode 100644 bsps/powerpc/psim/console/consupp.S create mode 100644 bsps/powerpc/qemuppc/console/console-io.c create mode 100644 bsps/powerpc/qoriq/console/console-config.c create mode 100644 bsps/powerpc/qoriq/console/uart-bridge-master.c create mode 100644 bsps/powerpc/qoriq/console/uart-bridge-slave.c create mode 100644 bsps/powerpc/shared/console/console.c create mode 100644 bsps/powerpc/shared/console/uart.c create mode 100644 bsps/powerpc/ss555/console/console.c create mode 100644 bsps/powerpc/t32mppc/console/console.c create mode 100644 bsps/powerpc/tqm8xx/console/console.c create mode 100644 bsps/powerpc/virtex/console/consolelite.c create mode 100644 bsps/riscv/riscv_generic/console/console-io.c create mode 100644 bsps/sh/gensh1/console/sci.c create mode 100644 bsps/sh/gensh2/console/config.c create mode 100644 bsps/sh/gensh2/console/sci.c create mode 100644 bsps/sh/gensh2/console/sci_termios.c create mode 100644 bsps/sh/gensh4/console/console.c create mode 100644 bsps/sh/gensh4/console/sh4uart.c create mode 100644 bsps/sh/shsim/console/console-debugio.c create mode 100644 bsps/sh/shsim/console/console-io.c create mode 100644 bsps/sh/shsim/console/console-support.S create mode 100644 bsps/shared/dev/serial/console-output-char.c create mode 100644 bsps/shared/dev/serial/console-polled.c create mode 100644 bsps/shared/dev/serial/console-termios-init.c create mode 100644 bsps/shared/dev/serial/console-termios.c create mode 100644 bsps/shared/dev/serial/getserialmouseps2.c create mode 100644 bsps/shared/dev/serial/printk-dummy.c create mode 100644 bsps/sparc/erc32/console/debugputs.c create mode 100644 bsps/sparc/erc32/console/erc32_console.c create mode 100644 bsps/sparc/leon2/console/console.c create mode 100644 bsps/sparc/leon2/console/debugputs.c create mode 100644 bsps/sparc/leon3/console/console.c create mode 100644 bsps/sparc/leon3/console/printk_support.c create mode 100644 bsps/sparc64/shared/console/conscfg.c create mode 100644 bsps/v850/gdbv850sim/console/console-io.c delete mode 100644 c/src/lib/libbsp/arm/altera-cyclone-v/console/console-config.c delete mode 100644 c/src/lib/libbsp/arm/atsam/console/console.c delete mode 100644 c/src/lib/libbsp/arm/atsam/console/debug-console.c delete mode 100644 c/src/lib/libbsp/arm/beagle/console/console-config.c delete mode 100644 c/src/lib/libbsp/arm/csb336/console/uart.c delete mode 100644 c/src/lib/libbsp/arm/csb337/console/dbgu.c delete mode 100644 c/src/lib/libbsp/arm/csb337/console/fbcons.c delete mode 100644 c/src/lib/libbsp/arm/csb337/console/sed1356.c delete mode 100644 c/src/lib/libbsp/arm/csb337/console/uarts.c delete mode 100644 c/src/lib/libbsp/arm/csb337/console/usart.c delete mode 100644 c/src/lib/libbsp/arm/edb7312/console/uart.c delete mode 100644 c/src/lib/libbsp/arm/gdbarmsim/console/console-io.c delete mode 100644 c/src/lib/libbsp/arm/gumstix/console/ffuart.c delete mode 100644 c/src/lib/libbsp/arm/gumstix/console/uarts.c delete mode 100644 c/src/lib/libbsp/arm/imx/console/console-config.c delete mode 100644 c/src/lib/libbsp/arm/lm3s69xx/console/console-config.c delete mode 100644 c/src/lib/libbsp/arm/lm3s69xx/console/uart.c delete mode 100644 c/src/lib/libbsp/arm/lpc176x/console/console-config.c delete mode 100644 c/src/lib/libbsp/arm/lpc24xx/console/console-config.c delete mode 100644 c/src/lib/libbsp/arm/lpc24xx/console/uart-probe-1.c delete mode 100644 c/src/lib/libbsp/arm/lpc24xx/console/uart-probe-2.c delete mode 100644 c/src/lib/libbsp/arm/lpc24xx/console/uart-probe-3.c delete mode 100644 c/src/lib/libbsp/arm/lpc32xx/console/console-config.c delete mode 100644 c/src/lib/libbsp/arm/lpc32xx/console/hsu.c delete mode 100644 c/src/lib/libbsp/arm/raspberrypi/console/console-config.c delete mode 100644 c/src/lib/libbsp/arm/raspberrypi/console/console_select.c delete mode 100644 c/src/lib/libbsp/arm/raspberrypi/console/fb.c delete mode 100644 c/src/lib/libbsp/arm/raspberrypi/console/fbcons.c delete mode 100644 c/src/lib/libbsp/arm/raspberrypi/console/font_data.h delete mode 100644 c/src/lib/libbsp/arm/raspberrypi/console/outch.c delete mode 100644 c/src/lib/libbsp/arm/raspberrypi/console/usart.c delete mode 100644 c/src/lib/libbsp/arm/realview-pbx-a9/console/console-config.c delete mode 100644 c/src/lib/libbsp/arm/rtl22xx/console/lpc22xx_uart.h delete mode 100644 c/src/lib/libbsp/arm/rtl22xx/console/uart.c delete mode 100644 c/src/lib/libbsp/arm/smdk2410/console/uart.c delete mode 100644 c/src/lib/libbsp/arm/stm32f4/console/console-config.c delete mode 100644 c/src/lib/libbsp/arm/stm32f4/console/usart.c delete mode 100644 c/src/lib/libbsp/arm/tms570/console/printk-support.c delete mode 100644 c/src/lib/libbsp/arm/tms570/console/tms570-sci.c delete mode 100644 c/src/lib/libbsp/arm/xilinx-zynq/console/console-config.c delete mode 100644 c/src/lib/libbsp/arm/xilinx-zynq/console/debug-console.c delete mode 100644 c/src/lib/libbsp/arm/xilinx-zynq/console/zynq-uart.c delete mode 100644 c/src/lib/libbsp/bfin/TLL6527M/console/console.c delete mode 100644 c/src/lib/libbsp/bfin/bf537Stamp/console/console.c delete mode 100644 c/src/lib/libbsp/bfin/eZKit533/console/console-io.c delete mode 100644 c/src/lib/libbsp/epiphany/epiphany_sim/console/console-io.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/conscfg.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/console_control.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/console_select.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/defkeymap.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/exar17d15x.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/fb_cirrus.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/fb_vesa_rm.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/fb_vga.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/gdb_select.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/i386kbd.h delete mode 100644 c/src/lib/libbsp/i386/pc386/console/inch.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/kbd_parser.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/keyboard.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/outch.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/pc_keyb.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/printk_support.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/ps2_mouse.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/ps2_mouse.h delete mode 100644 c/src/lib/libbsp/i386/pc386/console/rtd316.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/serial_mouse_config.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/uart_bus_pci.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/vgacons.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/vgainit.c delete mode 100644 c/src/lib/libbsp/i386/pc386/console/videoAsm.S delete mode 100644 c/src/lib/libbsp/i386/pc386/console/vt.c delete mode 100644 c/src/lib/libbsp/lm32/shared/console/console.c delete mode 100644 c/src/lib/libbsp/lm32/shared/console/uart.c delete mode 100644 c/src/lib/libbsp/lm32/shared/console/uart.h delete mode 100644 c/src/lib/libbsp/m32c/m32cbsp/console/console-io.c delete mode 100644 c/src/lib/libbsp/m32c/m32cbsp/console/syscalls.S delete mode 100644 c/src/lib/libbsp/m68k/av5282/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/csb360/console/console-io.c delete mode 100644 c/src/lib/libbsp/m68k/gen68340/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/gen68340/console/m340uart.c delete mode 100644 c/src/lib/libbsp/m68k/gen68360/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/genmcf548x/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/mcf5206elite/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/mcf52235/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/mcf52235/console/debugio.c delete mode 100644 c/src/lib/libbsp/m68k/mcf5225x/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/mcf5225x/console/debugio.c delete mode 100644 c/src/lib/libbsp/m68k/mcf5235/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/mcf5329/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/mrm332/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/mrm332/console/sci.c delete mode 100644 c/src/lib/libbsp/m68k/mrm332/console/sci.h delete mode 100644 c/src/lib/libbsp/m68k/mvme147/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/mvme162/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/mvme167/console/console-recording.h delete mode 100644 c/src/lib/libbsp/m68k/mvme167/console/console.c delete mode 100644 c/src/lib/libbsp/m68k/uC5282/console/console.c delete mode 100644 c/src/lib/libbsp/mips/csb350/console/console-io.c delete mode 100644 c/src/lib/libbsp/mips/hurricane/console/console.c delete mode 100644 c/src/lib/libbsp/mips/jmr3904/console/console-io.c delete mode 100644 c/src/lib/libbsp/mips/malta/console/conscfg.c delete mode 100644 c/src/lib/libbsp/mips/malta/console/printk_support.c delete mode 100644 c/src/lib/libbsp/mips/rbtx4925/console/console-io.c delete mode 100644 c/src/lib/libbsp/mips/rbtx4938/console/console-io.c delete mode 100644 c/src/lib/libbsp/mips/rbtx4938/console/yamon_api.h delete mode 100644 c/src/lib/libbsp/moxie/moxiesim/console/console-io.c delete mode 100644 c/src/lib/libbsp/moxie/moxiesim/console/syscalls.S delete mode 100644 c/src/lib/libbsp/nios2/nios2_iss/console/console.c delete mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/console/console.c delete mode 100644 c/src/lib/libbsp/or1k/generic_or1k/console/console-config.c delete mode 100644 c/src/lib/libbsp/or1k/generic_or1k/console/uart.c delete mode 100644 c/src/lib/libbsp/powerpc/gen5200/console/console.c delete mode 100644 c/src/lib/libbsp/powerpc/gen83xx/console/console-config.c delete mode 100644 c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-config.c delete mode 100644 c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-esci.c delete mode 100644 c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-generic.c delete mode 100644 c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-linflex.c delete mode 100644 c/src/lib/libbsp/powerpc/mpc8260ads/console/console.c delete mode 100644 c/src/lib/libbsp/powerpc/psim/console/console-io.c delete mode 100644 c/src/lib/libbsp/powerpc/psim/console/consupp.S delete mode 100644 c/src/lib/libbsp/powerpc/qemuppc/console/console-io.c delete mode 100644 c/src/lib/libbsp/powerpc/qoriq/console/console-config.c delete mode 100644 c/src/lib/libbsp/powerpc/qoriq/console/uart-bridge-master.c delete mode 100644 c/src/lib/libbsp/powerpc/qoriq/console/uart-bridge-slave.c delete mode 100644 c/src/lib/libbsp/powerpc/shared/console/console.c delete mode 100644 c/src/lib/libbsp/powerpc/shared/console/uart.c delete mode 100644 c/src/lib/libbsp/powerpc/ss555/console/console.c delete mode 100644 c/src/lib/libbsp/powerpc/t32mppc/console/console.c delete mode 100644 c/src/lib/libbsp/powerpc/tqm8xx/console/console.c delete mode 100644 c/src/lib/libbsp/powerpc/virtex/console/consolelite.c delete mode 100644 c/src/lib/libbsp/riscv/riscv_generic/console/console-io.c delete mode 100644 c/src/lib/libbsp/sh/gensh1/console/sci.c delete mode 100644 c/src/lib/libbsp/sh/gensh2/console/config.c delete mode 100644 c/src/lib/libbsp/sh/gensh2/console/sci.c delete mode 100644 c/src/lib/libbsp/sh/gensh2/console/sci_termios.c delete mode 100644 c/src/lib/libbsp/sh/gensh4/console/console.c delete mode 100644 c/src/lib/libbsp/sh/gensh4/console/sh4uart.c delete mode 100644 c/src/lib/libbsp/sh/shsim/console/console-debugio.c delete mode 100644 c/src/lib/libbsp/sh/shsim/console/console-io.c delete mode 100644 c/src/lib/libbsp/sh/shsim/console/console-support.S delete mode 100644 c/src/lib/libbsp/shared/console-output-char.c delete mode 100644 c/src/lib/libbsp/shared/console-polled.c delete mode 100644 c/src/lib/libbsp/shared/console-termios-init.c delete mode 100644 c/src/lib/libbsp/shared/console-termios.c delete mode 100644 c/src/lib/libbsp/shared/dummy_printk_support.c delete mode 100644 c/src/lib/libbsp/shared/get-serial-mouse-ps2.c delete mode 100644 c/src/lib/libbsp/sparc/erc32/console/debugputs.c delete mode 100644 c/src/lib/libbsp/sparc/erc32/console/erc32_console.c delete mode 100644 c/src/lib/libbsp/sparc/leon2/console/console.c delete mode 100644 c/src/lib/libbsp/sparc/leon2/console/debugputs.c delete mode 100644 c/src/lib/libbsp/sparc/leon3/console/console.c delete mode 100644 c/src/lib/libbsp/sparc/leon3/console/printk_support.c delete mode 100644 c/src/lib/libbsp/sparc64/shared/console/conscfg.c delete mode 100644 c/src/lib/libbsp/v850/gdbv850sim/console/console-io.c diff --git a/bsps/arm/altera-cyclone-v/console/console-config.c b/bsps/arm/altera-cyclone-v/console/console-config.c new file mode 100644 index 0000000000..e4dfec9f62 --- /dev/null +++ b/bsps/arm/altera-cyclone-v/console/console-config.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BSP_USE_UART_INTERRUPTS + #define DEVICE_FNS &ns16550_handler_interrupt +#else + #define DEVICE_FNS &ns16550_handler_polled +#endif + +static uint8_t altera_cyclone_v_uart_get_register(uintptr_t addr, uint8_t i) +{ + volatile uint32_t *reg = (volatile uint32_t *) addr; + + return (uint8_t) reg [i]; +} + +static void altera_cyclone_v_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val) +{ + volatile uint32_t *reg = (volatile uint32_t *) addr; + + reg [i] = val; +} + +static bool altera_cyclone_v_uart_probe( + rtems_termios_device_context *base, + uint32_t uart_set_mask +) +{ + ns16550_context *ctx = (ns16550_context *) base; + bool ret = true; + uint32_t ucr; + ALT_STATUS_CODE sc; + void* location = (void *) ctx->port; + + /* The ALT_CLK_L4_SP is required for all SoCFPGA UARTs. + * Check that it's enabled. */ + if ( alt_clk_is_enabled(ALT_CLK_L4_SP) != ALT_E_TRUE ) { + ret = false; + } + + if ( ret ) { + sc = alt_clk_freq_get(ALT_CLK_L4_SP, &ctx->clock); + if ( sc != ALT_E_SUCCESS ) { + ret = false; + } + } + + if ( ret ) { + // Bring UART out of reset. + alt_clrbits_word(ALT_RSTMGR_PERMODRST_ADDR, uart_set_mask); + + // Verify the UCR (UART Component Version) + ucr = alt_read_word( ALT_UART_UCV_ADDR( location ) ); + if ( ucr != ALT_UART_UCV_UART_COMPONENT_VER_RESET ) { + ret = false; + } + } + + if ( ret ) { + // Write SRR::UR (Shadow Reset Register :: UART Reset) + alt_write_word( ALT_UART_SRR_ADDR( location ), ALT_UART_SRR_UR_SET_MSK ); + + // Read the MSR to work around case:119085. + (void)alt_read_word( ALT_UART_MSR_ADDR( location ) ); + + ret = ns16550_probe( base ); + } + + return ret; +} + +#ifdef CYCLONE_V_CONFIG_CONSOLE +static bool altera_cyclone_v_uart_probe_0(rtems_termios_device_context *base) +{ + return altera_cyclone_v_uart_probe(base, ALT_RSTMGR_PERMODRST_UART0_SET_MSK); +} + +static ns16550_context altera_cyclone_v_uart_context_0 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"), + .get_reg = altera_cyclone_v_uart_get_register, + .set_reg = altera_cyclone_v_uart_set_register, + .port = (uintptr_t) ALT_UART0_ADDR, + .irq = ALT_INT_INTERRUPT_UART0, + .initial_baud = CYCLONE_V_UART_BAUD +}; +#endif + +#ifdef CYCLONE_V_CONFIG_UART_1 +static bool altera_cyclone_v_uart_probe_1(rtems_termios_device_context *base) +{ + return altera_cyclone_v_uart_probe(base, ALT_RSTMGR_PERMODRST_UART1_SET_MSK); +} + +static ns16550_context altera_cyclone_v_uart_context_1 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"), + .get_reg = altera_cyclone_v_uart_get_register, + .set_reg = altera_cyclone_v_uart_set_register, + .port = (uintptr_t) ALT_UART1_ADDR, + .irq = ALT_INT_INTERRUPT_UART1, + .initial_baud = CYCLONE_V_UART_BAUD +}; +#endif + +const console_device console_device_table[] = { + #ifdef CYCLONE_V_CONFIG_CONSOLE + { + .device_file = "/dev/ttyS0", + .probe = altera_cyclone_v_uart_probe_0, + .handler = DEVICE_FNS, + .context = &altera_cyclone_v_uart_context_0.base + }, + #endif + #ifdef CYCLONE_V_CONFIG_UART_1 + { + .device_file = "/dev/ttyS1", + .probe = altera_cyclone_v_uart_probe_1, + .handler = DEVICE_FNS, + .context = &altera_cyclone_v_uart_context_1.base + }, + #endif +}; + +const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table); + +static void output_char(char c) +{ + rtems_termios_device_context *ctx = console_device_table[0].context; + + ns16550_polled_putchar( ctx, c ); +} + +BSP_output_char_function_type BSP_output_char = output_char; + +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/arm/atsam/console/console.c b/bsps/arm/atsam/console/console.c new file mode 100644 index 0000000000..d51d2ace7d --- /dev/null +++ b/bsps/arm/atsam/console/console.c @@ -0,0 +1,526 @@ +/* + * Copyright (c) 2016 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include + +#include + +#include + +#include + +typedef struct { + rtems_termios_device_context base; + Usart *regs; + rtems_vector_number irq; + uint32_t id; + bool console; +#ifdef ATSAM_CONSOLE_USE_INTERRUPTS + bool transmitting; +#endif +} atsam_usart_context; + +static atsam_usart_context atsam_usart_instances[] = { + { + .regs = USART0, + .irq = USART0_IRQn, + .id = ID_USART0 + } +#ifdef USART1 + , { + .regs = USART1, + .irq = USART1_IRQn, + .id = ID_USART1 + } +#endif +#ifdef USART2 + , { + .regs = USART2, + .irq = USART2_IRQn, + .id = ID_USART2 + } +#endif +}; + +#ifdef ATSAM_CONSOLE_USE_INTERRUPTS +static void atsam_usart_interrupt(void *arg) +{ + rtems_termios_tty *tty = arg; + atsam_usart_context *ctx = rtems_termios_get_device_context(tty); + Usart *regs = ctx->regs; + uint32_t csr = regs->US_CSR; + + while ((csr & US_CSR_RXRDY) != 0) { + char c = (char) regs->US_RHR; + + rtems_termios_enqueue_raw_characters(tty, &c, 1); + + csr = regs->US_CSR; + } + + if (ctx->transmitting && (csr & US_CSR_TXEMPTY) != 0) { + rtems_termios_dequeue_characters(tty, 1); + } +} +#endif + +static bool atsam_usart_set_attributes( + rtems_termios_device_context *base, + const struct termios *term +) +{ + atsam_usart_context *ctx = (atsam_usart_context *) base; + Usart *regs = ctx->regs; + rtems_termios_baud_t baud; + uint32_t mr; + + baud = rtems_termios_baud_to_number(term->c_ospeed); + regs->US_BRGR = (BOARD_MCK / baud) / 16; + + if ((term->c_cflag & CREAD) != 0) { + regs->US_CR = US_CR_RXEN | US_CR_TXEN; + } else { + regs->US_CR = US_CR_TXEN; + } + + mr = US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK; + + switch (term->c_cflag & CSIZE) { + case CS5: + mr |= US_MR_CHRL_5_BIT; + break; + case CS6: + mr |= US_MR_CHRL_6_BIT; + break; + case CS7: + mr |= US_MR_CHRL_7_BIT; + break; + default: + mr |= US_MR_CHRL_8_BIT; + break; + } + + if ((term->c_cflag & PARENB) != 0) { + if ((term->c_cflag & PARODD) != 0) { + mr |= US_MR_PAR_ODD; + } else { + mr |= US_MR_PAR_EVEN; + } + } else { + mr |= US_MR_PAR_NO; + } + + if ((term->c_cflag & CSTOPB) != 0) { + mr |= US_MR_NBSTOP_2_BIT; + } else { + mr |= US_MR_NBSTOP_1_BIT; + } + + regs->US_MR = mr; + + return true; +} + +static bool atsam_usart_first_open( + rtems_termios_tty *tty, + rtems_termios_device_context *base, + struct termios *term, + rtems_libio_open_close_args_t *args +) +{ + atsam_usart_context *ctx = (atsam_usart_context *) base; + Usart *regs = ctx->regs; +#ifdef ATSAM_CONSOLE_USE_INTERRUPTS + rtems_status_code sc; +#endif + + regs->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RSTSTA; + regs->US_IDR = 0xffffffff; + + PMC_EnablePeripheral(ctx->id); + + rtems_termios_set_initial_baud(tty, ATSAM_CONSOLE_BAUD); + atsam_usart_set_attributes(base, term); + +#ifdef ATSAM_CONSOLE_USE_INTERRUPTS + regs->US_IER = US_IDR_RXRDY; + sc = rtems_interrupt_handler_install( + ctx->irq, + "USART", + RTEMS_INTERRUPT_SHARED, + atsam_usart_interrupt, + tty + ); + if (sc != RTEMS_SUCCESSFUL) { + return false; + } +#endif + + return true; +} + +static void atsam_usart_last_close( + rtems_termios_tty *tty, + rtems_termios_device_context *base, + rtems_libio_open_close_args_t *args +) +{ + atsam_usart_context *ctx = (atsam_usart_context *) base; + +#ifdef ATSAM_CONSOLE_USE_INTERRUPTS + rtems_interrupt_handler_remove(ctx->irq, atsam_usart_interrupt, tty); +#endif + + if (!ctx->console) { + PMC_DisablePeripheral(ctx->id); + } +} + +static void atsam_usart_write( + rtems_termios_device_context *base, + const char *buf, + size_t len +) +{ + atsam_usart_context *ctx = (atsam_usart_context *) base; + Usart *regs = ctx->regs; + +#ifdef ATSAM_CONSOLE_USE_INTERRUPTS + if (len > 0) { + ctx->transmitting = true; + regs->US_THR = buf[0]; + regs->US_IER = US_IDR_TXEMPTY; + } else { + ctx->transmitting = false; + regs->US_IDR = US_IDR_TXEMPTY; + } +#else + size_t i; + + for (i = 0; i < len; ++i) { + while ((regs->US_CSR & US_CSR_TXEMPTY) == 0) { + /* Wait */ + } + + regs->US_THR = buf[i]; + } +#endif +} + +#ifndef ATSAM_CONSOLE_USE_INTERRUPTS +static int atsam_usart_read(rtems_termios_device_context *base) +{ + atsam_usart_context *ctx = (atsam_usart_context *) base; + Usart *regs = ctx->regs; + + if ((regs->US_CSR & US_CSR_RXRDY) != 0) { + return (char) regs->US_RHR; + } else { + return -1; + } +} +#endif + +static const rtems_termios_device_handler atsam_usart_handler = { + .first_open = atsam_usart_first_open, + .last_close = atsam_usart_last_close, + .write = atsam_usart_write, + .set_attributes = atsam_usart_set_attributes, +#ifdef ATSAM_CONSOLE_USE_INTERRUPTS + .mode = TERMIOS_IRQ_DRIVEN +#else + .poll_read = atsam_usart_read, + .mode = TERMIOS_POLLED +#endif +}; + +typedef struct { + rtems_termios_device_context base; + Uart *regs; + rtems_vector_number irq; + uint32_t id; + bool console; +#ifdef ATSAM_CONSOLE_USE_INTERRUPTS + bool transmitting; +#endif +} atsam_uart_context; + +static atsam_uart_context atsam_uart_instances[] = { + { + .regs = UART0, + .irq = UART0_IRQn, + .id = ID_UART0 + } +#ifdef UART1 + , { + .regs = UART1, + .irq = UART1_IRQn, + .id = ID_UART1 + } +#endif +#ifdef UART2 + , { + .regs = UART2, + .irq = UART2_IRQn, + .id = ID_UART2 + } +#endif +#ifdef UART3 + , { + .regs = UART3, + .irq = UART3_IRQn, + .id = ID_UART3 + } +#endif +#ifdef UART4 + , { + .regs = UART4, + .irq = UART4_IRQn, + .id = ID_UART4 + } +#endif +}; + +#ifdef ATSAM_CONSOLE_USE_INTERRUPTS +static void atsam_uart_interrupt(void *arg) +{ + rtems_termios_tty *tty = arg; + atsam_uart_context *ctx = rtems_termios_get_device_context(tty); + Uart *regs = ctx->regs; + uint32_t sr = regs->UART_SR; + + while ((sr & UART_SR_RXRDY) != 0) { + char c = (char) regs->UART_RHR; + + rtems_termios_enqueue_raw_characters(tty, &c, 1); + + sr = regs->UART_SR; + } + + if (ctx->transmitting && (sr & UART_SR_TXEMPTY) != 0) { + rtems_termios_dequeue_characters(tty, 1); + } +} +#endif + +static bool atsam_uart_set_attributes( + rtems_termios_device_context *base, + const struct termios *term +) +{ + atsam_uart_context *ctx = (atsam_uart_context *) base; + Uart *regs = ctx->regs; + rtems_termios_baud_t baud; + uint32_t mr; + + baud = rtems_termios_baud_to_number(term->c_ospeed); + regs->UART_BRGR = (BOARD_MCK / baud) / 16; + + if ((term->c_cflag & CREAD) != 0) { + regs->UART_CR = UART_CR_RXEN | UART_CR_TXEN; + } else { + regs->UART_CR = UART_CR_TXEN; + } + + mr = UART_MR_FILTER_DISABLED | UART_MR_BRSRCCK_PERIPH_CLK; + + if ((term->c_cflag & CSIZE) != CS8) { + return false; + } + + if ((term->c_cflag & PARENB) != 0) { + if ((term->c_cflag & PARODD) != 0) { + mr |= UART_MR_PAR_ODD; + } else { + mr |= UART_MR_PAR_EVEN; + } + } else { + mr |= UART_MR_PAR_NO; + } + + if ((term->c_cflag & CSTOPB) != 0) { + return false; + } + + regs->UART_MR = mr; + + return true; +} + +static bool atsam_uart_first_open( + rtems_termios_tty *tty, + rtems_termios_device_context *base, + struct termios *term, + rtems_libio_open_close_args_t *args +) +{ + atsam_uart_context *ctx = (atsam_uart_context *) base; + Uart *regs = ctx->regs; +#ifdef ATSAM_CONSOLE_USE_INTERRUPTS + rtems_status_code sc; +#endif + + regs->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RSTSTA; + regs->UART_IDR = 0xffffffff; + + PMC_EnablePeripheral(ctx->id); + + rtems_termios_set_initial_baud(tty, ATSAM_CONSOLE_BAUD); + atsam_uart_set_attributes(base, term); + +#ifdef ATSAM_CONSOLE_USE_INTERRUPTS + regs->UART_IER = UART_IDR_RXRDY; + sc = rtems_interrupt_handler_install( + ctx->irq, + "UART", + RTEMS_INTERRUPT_SHARED, + atsam_uart_interrupt, + tty + ); + if (sc != RTEMS_SUCCESSFUL) { + return false; + } +#endif + + return true; +} + +static void atsam_uart_last_close( + rtems_termios_tty *tty, + rtems_termios_device_context *base, + rtems_libio_open_close_args_t *args +) +{ + atsam_uart_context *ctx = (atsam_uart_context *) base; + +#ifdef ATSAM_CONSOLE_USE_INTERRUPTS + rtems_interrupt_handler_remove(ctx->irq, atsam_uart_interrupt, tty); +#endif + + if (!ctx->console) { + PMC_DisablePeripheral(ctx->id); + } +} + +static void atsam_uart_write( + rtems_termios_device_context *base, + const char *buf, + size_t len +) +{ + atsam_uart_context *ctx = (atsam_uart_context *) base; + Uart *regs = ctx->regs; + +#ifdef ATSAM_CONSOLE_USE_INTERRUPTS + if (len > 0) { + ctx->transmitting = true; + regs->UART_THR = buf[0]; + regs->UART_IER = UART_IDR_TXEMPTY; + } else { + ctx->transmitting = false; + regs->UART_IDR = UART_IDR_TXEMPTY; + } +#else + size_t i; + + for (i = 0; i < len; ++i) { + while ((regs->UART_SR & UART_SR_TXEMPTY) == 0) { + /* Wait */ + } + + regs->UART_THR = buf[i]; + } +#endif +} + +#ifndef ATSAM_CONSOLE_USE_INTERRUPTS +static int atsam_uart_read(rtems_termios_device_context *base) +{ + atsam_uart_context *ctx = (atsam_uart_context *) base; + Uart *regs = ctx->regs; + + if ((regs->UART_SR & UART_SR_RXRDY) != 0) { + return (char) regs->UART_RHR; + } else { + return -1; + } +} +#endif + +static const rtems_termios_device_handler atsam_uart_handler = { + .first_open = atsam_uart_first_open, + .last_close = atsam_uart_last_close, + .write = atsam_uart_write, + .set_attributes = atsam_uart_set_attributes, +#ifdef ATSAM_CONSOLE_USE_INTERRUPTS + .mode = TERMIOS_IRQ_DRIVEN +#else + .poll_read = atsam_uart_read, + .mode = TERMIOS_POLLED +#endif +}; + +rtems_status_code console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + size_t i; + + rtems_termios_initialize(); + + for (i = 0; i < RTEMS_ARRAY_SIZE(atsam_usart_instances); ++i) { + char usart[] = "/dev/ttyUSARTX"; + + usart[sizeof(usart) - 2] = (char) ('0' + i); + rtems_termios_device_install( + &usart[0], + &atsam_usart_handler, + NULL, + &atsam_usart_instances[i].base + ); + +#if ATSAM_CONSOLE_DEVICE_TYPE == 0 + if (i == ATSAM_CONSOLE_DEVICE_INDEX) { + atsam_usart_instances[i].console = true; + link(&usart[0], CONSOLE_DEVICE_NAME); + } +#endif + } + + for (i = 0; i < RTEMS_ARRAY_SIZE(atsam_uart_instances); ++i) { + char uart[] = "/dev/ttyUARTX"; + + uart[sizeof(uart) - 2] = (char) ('0' + i); + rtems_termios_device_install( + &uart[0], + &atsam_uart_handler, + NULL, + &atsam_uart_instances[i].base + ); + +#if ATSAM_CONSOLE_DEVICE_TYPE == 1 + if (i == ATSAM_CONSOLE_DEVICE_INDEX) { + atsam_uart_instances[i].console = true; + link(&uart[0], CONSOLE_DEVICE_NAME); + } +#endif + } + + return RTEMS_SUCCESSFUL; +} diff --git a/bsps/arm/atsam/console/debug-console.c b/bsps/arm/atsam/console/debug-console.c new file mode 100644 index 0000000000..a405fe9665 --- /dev/null +++ b/bsps/arm/atsam/console/debug-console.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include + +#include +#include +#include + +static void atsam_debug_console_out(char c) +{ + DBG_PutChar((uint8_t) c); +} + +static void atsam_debug_console_init(void) +{ + DBG_Configure(115200, BOARD_MCK); + BSP_output_char = atsam_debug_console_out; +} + +static void atsam_debug_console_early_init(char c) +{ + atsam_debug_console_init(); + atsam_debug_console_out(c); +} + +static int atsam_debug_console_in(void) +{ + return (int) DBG_GetChar(); +} + +BSP_output_char_function_type BSP_output_char = atsam_debug_console_early_init; + +BSP_polling_getchar_function_type BSP_poll_char = atsam_debug_console_in; + +RTEMS_SYSINIT_ITEM( + atsam_debug_console_init, + RTEMS_SYSINIT_BSP_START, + RTEMS_SYSINIT_ORDER_LAST +); diff --git a/bsps/arm/beagle/console/console-config.c b/bsps/arm/beagle/console/console-config.c new file mode 100644 index 0000000000..78af5f6a93 --- /dev/null +++ b/bsps/arm/beagle/console/console-config.c @@ -0,0 +1,152 @@ +/** + * @file + * + * @ingroup arm_beagle + * + * @brief Console configuration. + */ + +/* + * Copyright (c) 2012 Claas Ziemke. All rights reserved. + * + * Claas Ziemke + * Kernerstrasse 11 + * 70182 Stuttgart + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + * Modified by Ben Gras to make + * interrupt-driven uart i/o work for beagleboards; beaglebone support added. + */ + +#include +#include + +#include + +#include +#include +#include + +#define CONSOLE_UART_THR (*(volatile unsigned int *)BSP_CONSOLE_UART_BASE) +#define CONSOLE_UART_RHR (*(volatile unsigned int *)BSP_CONSOLE_UART_BASE) +#define CONSOLE_UART_LSR (*(volatile unsigned int *)(BSP_CONSOLE_UART_BASE+0x14)) +#define CONSOLE_SYSC (*(volatile uint32_t *) (BSP_CONSOLE_UART_BASE + 0x54)) +#define CONSOLE_SYSS (*(volatile uint32_t *) (BSP_CONSOLE_UART_BASE + 0x58)) + +#define TX_FIFO_E (1<<5) +#define RX_FIFO_E (1<<0) + +static uint8_t beagle_uart_get_register(uintptr_t addr, uint8_t i) +{ + uint8_t v; + volatile uint32_t *reg_r = (volatile uint32_t *) addr + i; + + if(reg_r == (uint32_t*) BSP_CONSOLE_UART_BASE /* reading RHR */ ) { + /* check there should be anything in the RHR before accessing it */ + if(!(CONSOLE_UART_LSR & 0x01)) { + return 0; + } + } + + v = (uint8_t) *reg_r; + + return v; +} + +static void beagle_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val) +{ + volatile uint32_t *reg = (volatile uint32_t *) addr; + + reg [i] = val; +} + +console_tbl Console_Configuration_Ports [] = { + { + .sDeviceName = "/dev/ttyS0", + .deviceType = SERIAL_NS16550, +#if CONSOLE_POLLED /* option to facilitate running the tests */ + .pDeviceFns = &ns16550_fns_polled, +#else + .pDeviceFns = &ns16550_fns, +#endif + .ulMargin = 16, + .ulHysteresis = 8, + .pDeviceParams = (void *) CONSOLE_BAUD, + .ulCtrlPort1 = BSP_CONSOLE_UART_BASE, + .ulDataPort = BSP_CONSOLE_UART_BASE, + .ulIntVector = BSP_CONSOLE_UART_IRQ, + .getRegister = beagle_uart_get_register, + .setRegister = beagle_uart_set_register, + .ulClock = UART_CLOCK, /* 48MHz base clock */ + }, +}; + +unsigned long Console_Configuration_Count = 1; + +static int init_needed = 1; // don't rely on bss being 0 + +static void beagle_console_init(void) +{ + if(init_needed) { + const uint32_t div = UART_CLOCK / 16 / CONSOLE_BAUD; + CONSOLE_SYSC = 2; + while ((CONSOLE_SYSS & 1) == 0) + ; + if ((CONSOLE_LSR & (CONSOLE_LSR_THRE | CONSOLE_LSR_TEMT)) == CONSOLE_LSR_THRE) { + CONSOLE_LCR = 0x83; + CONSOLE_DLL = div; + CONSOLE_DLM = (div >> 8) & 0xff; + CONSOLE_LCR = 0x03; + CONSOLE_ACR = 0x00; + } + + while ((CONSOLE_LSR & CONSOLE_LSR_TEMT) == 0) + ; + + CONSOLE_LCR = 0x80 | 0x03; + CONSOLE_DLL = 0x00; + CONSOLE_DLM = 0x00; + CONSOLE_LCR = 0x03; + CONSOLE_MCR = 0x03; + CONSOLE_FCR = 0x07; + CONSOLE_LCR = 0x83; + CONSOLE_DLL = div; + CONSOLE_DLM = (div >> 8) & 0xff; + CONSOLE_LCR = 0x03; + CONSOLE_ACR = 0x00; + init_needed = 0; + } +} + +#define CONSOLE_THR8 (*(volatile uint8_t *) (BSP_CONSOLE_UART_BASE + 0x00)) + +static void uart_write_polled( char c ) +{ + if(init_needed) beagle_console_init(); + + while( ( CONSOLE_LSR & TX_FIFO_E ) == 0 ) + ; + CONSOLE_THR8 = c; +} + +static void _BSP_put_char( char c ) { + uart_write_polled( c ); +} + +static int _BSP_get_char(void) +{ + if ((CONSOLE_LSR & CONSOLE_LSR_RDR) != 0) { + return CONSOLE_RBR; + } else { + return -1; + } +} + +BSP_output_char_function_type BSP_output_char = _BSP_put_char; + +BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char; diff --git a/bsps/arm/csb336/console/uart.c b/bsps/arm/csb336/console/uart.c new file mode 100644 index 0000000000..8d8a0c1ed0 --- /dev/null +++ b/bsps/arm/csb336/console/uart.c @@ -0,0 +1,476 @@ +/* + * Console driver for MC9328XML UARTs. + * + * Written Jay Monkman + * Copyright (c) 2005 by Loping Dog Embedded Systems + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Define this to use interrupt driver UART driver */ +#define USE_INTERRUPTS 1 + +/* How many serial ports? */ +#define NUM_DEVS 2 +#define poll_write(c) imx_uart_poll_write_char(0, c) +#define poll_read() imx_uart_poll_read_char(0) + +static int imx_uart_first_open(int, int, void *); +static int imx_uart_last_close(int, int, void *); +static int imx_uart_poll_read(int); +static int imx_uart_set_attrs(int, const struct termios *); +static void imx_uart_init(int minor); +static void imx_uart_set_baud(int, int); +static ssize_t imx_uart_poll_write(int, const char *, size_t); +static int imx_uart_poll_read_char(int minor); +static void imx_uart_poll_write_char(int minor, char c); +static void _BSP_output_char(char c); +static int _BSP_poll_char(void); + +#if USE_INTERRUPTS +static void imx_uart_tx_isr(void *); +static void imx_uart_rx_isr(void *); +static void imx_uart_isr_on(rtems_vector_number); +static void imx_uart_isr_off(rtems_vector_number); +static ssize_t imx_uart_intr_write(int, const char *, size_t); +static rtems_vector_number imx_uart_name_transmit(int minor); +static rtems_vector_number imx_uart_name_receive(int minor); +#endif + +/* TERMIOS callbacks */ +#if USE_INTERRUPTS +rtems_termios_callbacks imx_uart_cbacks = { + .firstOpen = imx_uart_first_open, + .lastClose = imx_uart_last_close, + .pollRead = NULL, + .write = imx_uart_intr_write, + .setAttributes = imx_uart_set_attrs, + .stopRemoteTx = NULL, + .startRemoteTx = NULL, + .outputUsesInterrupts = 1, +}; +#else +rtems_termios_callbacks imx_uart_cbacks = { + .firstOpen = imx_uart_first_open, + .lastClose = imx_uart_last_close, + .pollRead = imx_uart_poll_read, + .write = imx_uart_poll_write, + .setAttributes = imx_uart_set_attrs, + .stopRemoteTx = NULL, + .startRemoteTx = NULL, + .outputUsesInterrupts = 0, +}; +#endif + +typedef struct { + int minor; + mc9328mxl_uart_regs_t * regs; + volatile const char *buf; + volatile int len; + volatile int idx; + void *tty; +} imx_uart_data_t; + +static imx_uart_data_t imx_uart_data[NUM_DEVS]; + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + int i; + + for (i = 0; i < NUM_DEVS; i++) { + imx_uart_init(i); + } + + rtems_termios_initialize(); + + /* /dev/console and /dev/tty0 are the same */ + status = rtems_io_register_name("/dev/console", major, 0); + if (status != RTEMS_SUCCESSFUL) { + rtems_panic("%s:%d Error registering /dev/console :: %d\n", + __FUNCTION__, __LINE__, status); + } + + status = rtems_io_register_name("/dev/tty0", major, 0); + if (status != RTEMS_SUCCESSFUL) { + rtems_panic("%s:%d Error registering /dev/tty0 :: %d\n", + __FUNCTION__, __LINE__, status); + } + + status = rtems_io_register_name("/dev/tty1", major, 1); + if (status != RTEMS_SUCCESSFUL) { + rtems_panic("%s:%d Error registering /dev/tty1 :: %d\n", + __FUNCTION__, __LINE__, status); + } + return RTEMS_SUCCESSFUL; +} + +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_status_code rc; + + if (minor > (NUM_DEVS - 1)) { + return RTEMS_INVALID_NUMBER; + } + + rc = rtems_termios_open(major, minor, arg, &imx_uart_cbacks); + + return rc; +} + +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_close(arg); +} + +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_read(arg); +} + +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_write(arg); +} + +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_ioctl(arg); +} + +static void imx_uart_init(int minor) +{ + imx_uart_data[minor].minor = minor; + imx_uart_data[minor].buf = NULL; + imx_uart_data[minor].len = 0; + imx_uart_data[minor].idx = 0; + + if (minor == 0) { + imx_uart_data[minor].regs = + (mc9328mxl_uart_regs_t *) MC9328MXL_UART1_BASE; + } else if (minor == 1) { + imx_uart_data[minor].regs = + (mc9328mxl_uart_regs_t *) MC9328MXL_UART2_BASE; + } else { + rtems_panic("%s:%d Unknown UART minor number %d\n", + __FUNCTION__, __LINE__, minor); + } + + imx_uart_data[minor].regs->cr1 = ( + MC9328MXL_UART_CR1_UARTCLKEN | + MC9328MXL_UART_CR1_UARTEN); + + imx_uart_data[minor].regs->cr2 = ( + MC9328MXL_UART_CR2_IRTS | + MC9328MXL_UART_CR2_WS | + MC9328MXL_UART_CR2_TXEN | + MC9328MXL_UART_CR2_RXEN | + MC9328MXL_UART_CR2_SRST); + + imx_uart_data[minor].regs->cr3 = 0; + + imx_uart_data[minor].regs->cr4 = 0; + + imx_uart_data[minor].regs->fcr = ( + MC9328MXL_UART_FCR_TXTL(32) | + MC9328MXL_UART_FCR_RFDIV_1 | + MC9328MXL_UART_FCR_RXTL(1)); + + imx_uart_set_baud(minor, 38400); + +} + +static int imx_uart_first_open(int major, int minor, void *arg) +{ + rtems_libio_open_close_args_t *args = arg; + rtems_status_code status = RTEMS_SUCCESSFUL; + + imx_uart_data[minor].tty = args->iop->data1; + +#if USE_INTERRUPTS + status = rtems_interrupt_handler_install( + imx_uart_name_transmit(minor), + "UART", + RTEMS_INTERRUPT_UNIQUE, + imx_uart_tx_isr, + &imx_uart_data[minor] + ); + assert(status == RTEMS_SUCCESSFUL); + imx_uart_isr_on(imx_uart_name_transmit(minor)); + + status = rtems_interrupt_handler_install( + imx_uart_name_receive(minor), + "UART", + RTEMS_INTERRUPT_UNIQUE, + imx_uart_rx_isr, + &imx_uart_data[minor] + ); + assert(status == RTEMS_SUCCESSFUL); + imx_uart_isr_on(imx_uart_name_receive(minor)); + + imx_uart_data[minor].regs->cr1 |= MC9328MXL_UART_CR1_RRDYEN; +#endif + + return 0; +} + +static int imx_uart_last_close(int major, int minor, void *arg) +{ +#if USE_INTERRUPTS + rtems_status_code status = RTEMS_SUCCESSFUL; + + imx_uart_isr_off(imx_uart_name_transmit(minor)); + status = rtems_interrupt_handler_remove( + imx_uart_name_transmit(minor), + imx_uart_tx_isr, + &imx_uart_data[minor] + ); + assert(status == RTEMS_SUCCESSFUL); + + imx_uart_isr_off(imx_uart_name_receive(minor)); + status = rtems_interrupt_handler_remove( + imx_uart_name_receive(minor), + imx_uart_rx_isr, + &imx_uart_data[minor] + ); + assert(status == RTEMS_SUCCESSFUL); +#endif + + return 0; +} + +static int imx_uart_poll_read(int minor) +{ + if (imx_uart_data[minor].regs->sr2 & MC9328MXL_UART_SR2_RDR) { + return imx_uart_data[minor].regs->rxd & 0xff; + } else { + return -1; + } +} + + +static ssize_t imx_uart_poll_write(int minor, const char *buf, size_t len) +{ + int i; + for (i = 0; i < len; i++) { + /* Wait for there to be room in the fifo */ + while (!(imx_uart_data[minor].regs->sr2 & MC9328MXL_UART_SR2_TXDC)) { + continue; + } + + imx_uart_data[minor].regs->txd = buf[i]; + } + return 1; + +} + +#if USE_INTERRUPTS +static ssize_t imx_uart_intr_write(int minor, const char *buf, size_t len) +{ + if (len > 0) { + imx_uart_data[minor].buf = buf; + imx_uart_data[minor].len = len; + imx_uart_data[minor].idx = 0; + + imx_uart_data[minor].regs->cr1 |= MC9328MXL_UART_CR1_TXMPTYEN; + } + + return 1; +} +#endif + + +/* This is for setting baud rate, bits, etc. */ +static int imx_uart_set_attrs(int minor, const struct termios *t) +{ + int baud; + + baud = rtems_termios_baud_to_number(t->c_ospeed); + imx_uart_set_baud(minor, baud); + + return 0; +} + +#if USE_INTERRUPTS +static void imx_uart_isr_on(rtems_vector_number name) +{ + MC9328MXL_AITC_INTENNUM = name; +} +static void imx_uart_isr_off(rtems_vector_number name) +{ + MC9328MXL_AITC_INTDISNUM = name; +} + +static void imx_uart_rx_isr(void * param) +{ + imx_uart_data_t *uart_data = param; + char buf[32]; + int i=0; + + while (uart_data->regs->sr2 & MC9328MXL_UART_SR2_RDR) { + buf[i] = uart_data->regs->rxd & 0xff; + i++; + } + + rtems_termios_enqueue_raw_characters(uart_data->tty, buf, i); +} + +static void imx_uart_tx_isr(void * param) +{ + imx_uart_data_t *uart_data = param; + int len; + int minor = uart_data->minor; + + + if (uart_data->idx < uart_data->len) { + while ( (uart_data->regs->sr1 & MC9328MXL_UART_SR1_TRDY) && + (uart_data->idx < uart_data->len)) { + uart_data->regs->txd = uart_data->buf[uart_data->idx]; + uart_data->idx++; + } + } else { + len = uart_data->len; + uart_data->len = 0; + imx_uart_data[minor].regs->cr1 &= ~MC9328MXL_UART_CR1_TXMPTYEN; + rtems_termios_dequeue_characters(uart_data->tty, len); + } +} + +static rtems_vector_number imx_uart_name_transmit(int minor) +{ + if (minor == 0) { + return BSP_INT_UART1_TX; + } else if (minor == 1) { + return BSP_INT_UART2_TX; + } + + assert(0); +} + +static rtems_vector_number imx_uart_name_receive(int minor) +{ + if (minor == 0) { + return BSP_INT_UART1_RX; + } else if (minor == 1) { + return BSP_INT_UART2_RX; + } + + assert(0); +} +#endif + +/* + * Set the UART's baud rate. The calculation is: + * (baud * 16) / ref_freq = num/demom + * + * ref_freq = perclk1 / RFDIV[2:0] + * BIR = num - 1 + * BMR = demom - 1 + * + * Setting 'num' to 16 yields this equation: + * demom = ref_freq / baud + */ +static void imx_uart_set_baud(int minor, int baud) +{ + unsigned int perclk1; + unsigned int denom; + unsigned int ref_freq = 0; + uint32_t fcr; + + perclk1 = get_perclk1_freq(); + fcr = imx_uart_data[minor].regs->fcr; + + switch(fcr & MC9328MXL_UART_FCR_RFDIV_MASK) { + case MC9328MXL_UART_FCR_RFDIV_1: ref_freq = perclk1/1; break; + case MC9328MXL_UART_FCR_RFDIV_2: ref_freq = perclk1/2; break; + case MC9328MXL_UART_FCR_RFDIV_3: ref_freq = perclk1/3; break; + case MC9328MXL_UART_FCR_RFDIV_4: ref_freq = perclk1/4; break; + case MC9328MXL_UART_FCR_RFDIV_5: ref_freq = perclk1/5; break; + case MC9328MXL_UART_FCR_RFDIV_6: ref_freq = perclk1/6; break; + case MC9328MXL_UART_FCR_RFDIV_7: ref_freq = perclk1/7; break; + default: + rtems_panic("%s:%d Unknown RFDIV: 0x%" PRIx32, + __FUNCTION__, __LINE__, + fcr & MC9328MXL_UART_FCR_RFDIV_MASK); + break; + } + + denom = ref_freq / baud; + + imx_uart_data[minor].regs->bir = 0xf; + imx_uart_data[minor].regs->bmr = denom; +} + + +/* + * Polled, non-blocking read from UART + */ +static int imx_uart_poll_read_char(int minor) +{ + return imx_uart_poll_read(minor); +} + +/* + * Polled, blocking write from UART + */ +static void imx_uart_poll_write_char(int minor, char c) +{ + imx_uart_poll_write(minor, &c, 1); +} + +/* + * Functions for printk() and friends. + */ +static void _BSP_output_char(char c) +{ + poll_write(c); +} + +BSP_output_char_function_type BSP_output_char = _BSP_output_char; + +static int _BSP_poll_char(void) +{ + return poll_read(); +} + +BSP_polling_getchar_function_type BSP_poll_char = _BSP_poll_char; + + diff --git a/bsps/arm/csb337/console/dbgu.c b/bsps/arm/csb337/console/dbgu.c new file mode 100644 index 0000000000..1a16762e32 --- /dev/null +++ b/bsps/arm/csb337/console/dbgu.c @@ -0,0 +1,223 @@ +/* + * Console driver for AT91RM9200 DBGU port + * + * This driver uses the shared console driver in + * ...../libbsp/shared/console.c + * + * Copyright (c) 2003 by Cogent Computer Systems + * Written by Mike Kelly + * and Jay Monkman + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +volatile int dbg_dly; + +/* static function prototypes */ +static int dbgu_first_open(int major, int minor, void *arg); +static int dbgu_last_close(int major, int minor, void *arg); +static int dbgu_read(int minor); +static ssize_t dbgu_write(int minor, const char *buf, size_t len); +static void dbgu_init(int minor); +static void dbgu_write_polled(int minor, char c); +static int dbgu_set_attributes(int minor, const struct termios *t); + +/* Pointers to functions for handling the UART. */ +const console_fns dbgu_fns = +{ + libchip_serial_default_probe, + dbgu_first_open, + dbgu_last_close, + dbgu_read, + dbgu_write, + dbgu_init, + dbgu_write_polled, /* not used in this driver */ + dbgu_set_attributes, + FALSE /* TRUE if interrupt driven, FALSE if not. */ +}; +/*********************************************************************/ +/* Functions called via callbacks (i.e. the ones in uart_fns */ +/*********************************************************************/ + +/* + * This is called the first time each device is opened. Since + * the driver is polled, we don't have to do anything. If the driver + * were interrupt driven, we'd enable interrupts here. + */ +static int dbgu_first_open(int major, int minor, void *arg) +{ + return 0; +} + + +/* + * This is called the last time each device is closed. Since + * the driver is polled, we don't have to do anything. If the driver + * were interrupt driven, we'd disable interrupts here. + */ +static int dbgu_last_close(int major, int minor, void *arg) +{ + return 0; +} + + +/* + * Read one character from UART. + * + * return -1 if there's no data, otherwise return + * the character in lowest 8 bits of returned int. + */ +static int dbgu_read(int minor) +{ + char c; + console_tbl *console_entry; + at91rm9200_dbgu_regs_t *dbgu; + + console_entry = BSP_get_uart_from_minor(minor); + + if (console_entry == NULL) { + return -1; + } + + dbgu = (at91rm9200_dbgu_regs_t *)console_entry->ulCtrlPort1; + + if (!(dbgu->sr & DBGU_INT_RXRDY)) { + return -1; + } + + c = dbgu->rhr & 0xff; + + return c; +} + + +/* + * Write buffer to UART + * + * return 1 on success, -1 on error + */ +static ssize_t dbgu_write(int minor, const char *buf, size_t len) +{ + int i, x; + char c; + console_tbl *console_entry; + at91rm9200_dbgu_regs_t *dbgu; + + console_entry = BSP_get_uart_from_minor(minor); + + if (console_entry == NULL) { + return -1; + } + + dbgu = (at91rm9200_dbgu_regs_t *)console_entry->ulCtrlPort1; + + for (i = 0; i < len; i++) { + /* Wait for fifo to have room */ + while(1) { + if (dbgu->sr & DBGU_INT_TXRDY) { + break; + } + } + + c = (char) buf[i]; + dbgu->thr = c; + + /* the TXRDY flag does not seem to update right away (is this true?) */ + /* so we wait a bit before continuing */ + for (x = 0; x < 100; x++) { + dbg_dly++; /* using a global so this doesn't get optimized out */ + } + } + + return 1; +} + + +/* Set up the UART. */ +static void dbgu_init(int minor) +{ + console_tbl *console_entry; + at91rm9200_dbgu_regs_t *dbgu; + + console_entry = BSP_get_uart_from_minor(minor); + + if (console_entry == NULL) { + return; + } + + dbgu = (at91rm9200_dbgu_regs_t *)console_entry->ulCtrlPort1; + + /* Clear error bits, and reset */ + dbgu->cr = (DBGU_CR_RSTSTA | DBGU_CR_RSTTX | DBGU_CR_RSTRX); + + /* Clear pending interrupts */ + dbgu->idr = DBGU_INT_ALL; + dbgu->imr = 0; + + /* Set port to no parity, no loopback */ + dbgu->mr = DBGU_MR_PAR_NONE | DBGU_MR_CHMODE_NORM; + + /* Set the baud rate */ + dbgu->brgr = (at91rm9200_get_mck() / 16) / BSP_get_baud(); + + /* Enable the DBGU */ + dbgu->cr = (DBGU_CR_TXEN | DBGU_CR_RXEN); +} + +/* This is used for getchark support */ +static void dbgu_write_polled(int minor, char c) +{ + dbgu_write(minor, &c, 1); +} + +/* This is for setting baud rate, bits, etc. */ +static int dbgu_set_attributes(int minor, const struct termios *t) +{ + return 0; +} + +/***********************************************************************/ +/* + * The following functions are not used by TERMIOS, but other RTEMS + * functions use them instead. + */ +/***********************************************************************/ +/* + * Read from UART. This is used in the exit code, and can't + * rely on interrupts. + */ +static int dbgu_poll_read(int minor) +{ + return dbgu_read(minor); +} + + +/* + * Write a character to the console. This is used by printk() and + * maybe other low level functions. It should not use interrupts or any + * RTEMS system calls. It needs to be very simple + */ +static void _BSP_put_char( char c ) { + dbgu_write_polled(0, c); +} + +BSP_output_char_function_type BSP_output_char = _BSP_put_char; + +static int _BSP_poll_char(void) +{ + return dbgu_poll_read(0); +} + +BSP_polling_getchar_function_type BSP_poll_char = _BSP_poll_char; diff --git a/bsps/arm/csb337/console/fbcons.c b/bsps/arm/csb337/console/fbcons.c new file mode 100644 index 0000000000..62e840938d --- /dev/null +++ b/bsps/arm/csb337/console/fbcons.c @@ -0,0 +1,125 @@ +/* + * LCD Console Output Driver for CSBx37 + */ + +/* + * COPYRIGHT (c) 1989-2014. + * On-Line Applications Research Corporation (OAR). + * + * Modified by Fernando Nicodemos + * from NCB - Sistemas Embarcados Ltda. (Brazil) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include + +#include +#include +#include +#include "sed1356.h" + +/* static function prototypes */ +static int fbcons_first_open(int major, int minor, void *arg); +static int fbcons_last_close(int major, int minor, void *arg); +static int fbcons_read(int minor); +static ssize_t fbcons_write(int minor, const char *buf, size_t len); +static void fbcons_init(int minor); +static void fbcons_write_polled(int minor, char c); +static int fbcons_set_attributes(int minor, const struct termios *t); + +/* Pointers to functions for handling the UART. */ +const console_fns fbcons_fns = +{ + libchip_serial_default_probe, + fbcons_first_open, + fbcons_last_close, + fbcons_read, + fbcons_write, + fbcons_init, + fbcons_write_polled, /* not used in this driver */ + fbcons_set_attributes, + FALSE /* TRUE if interrupt driven, FALSE if not. */ +}; +/*********************************************************************/ +/* Functions called via callbacks (i.e. the ones in uart_fns */ +/*********************************************************************/ + +/* + * This is called the first time each device is opened. Since + * the driver is polled, we don't have to do anything. If the driver + * were interrupt driven, we'd enable interrupts here. + */ +static int fbcons_first_open(int major, int minor, void *arg) +{ + /* printk( "Frame buffer -- first open\n" ); */ + return 0; +} + + +/* + * This is called the last time each device is closed. Since + * the driver is polled, we don't have to do anything. If the driver + * were interrupt driven, we'd disable interrupts here. + */ +static int fbcons_last_close(int major, int minor, void *arg) +{ + /* printk( "Frame buffer -- last close\n" ); */ + return 0; +} + + +/* + * Read one character from UART. + * + * return -1 if there's no data, otherwise return + * the character in lowest 8 bits of returned int. + */ +static int fbcons_read(int minor) +{ + /* printk( "Frame buffer -- read\n" ); */ + return -1; +} + + +/* + * Write buffer to LCD + * + * return 1 on success, -1 on error + */ +static ssize_t fbcons_write(int minor, const char *buf, size_t len) +{ + int i; + + /* printk( "Frame buffer -- write\n" ); */ + for ( i=0 ; i from NCB - Sistemas + * Embarcados Ltda. (Brazil) to be more compliant with RTEMS coding + * standards and to eliminate C++ style comments. + */ + +#include + +#include +#include +#include "sed1356.h" +#include "font8x16.h" + +int mode900lq; +long PIXELS_PER_ROW; +long PIXELS_PER_COL; +long COLS_PER_SCREEN; +long ROWS_PER_SCREEN; +long SED_HOR_PULSE_WIDTH_LCD; +long SED_VER_PULSE_START_LCD; +long SED_HOR_PULSE_START_LCD; +long SED_HOR_NONDISP_LCD; +long SED_VER_NONDISP_LCD; +long SED_VER_PULSE_WIDTH_LCD; + +/* globals to keep track of foreground, background colors and x,y position */ +int sed_color_depth; /* 4, 8 or 16 */ +int sed_fg_color; /* 0 to 15, used as lookup into VGA color table */ +int sed_bg_color; /* 0 to 15, used as lookup into VGA color table */ +int sed_col; /* current column, 0 to COLS_PER_SCREEN - 1 */ +int sed_row; /* current row, 0 to (ROWS_PER_SCREEN * 2) - 1 */ +int sed_disp_mode_crt; /* CRT=1, LCD=0 */ +int sed135x_ok; +int sed135x_tst; +uint32_t sed_fb_offset; /* current offset into frame buffer for sed_putchar */ + +void sed_writechar(uint8_t c); +void sed_scroll(void); + +#define SED_REG_BASE 0x30000000 /* *CS2 */ +#define SED_MEM_BASE (SED_REG_BASE + 0x00200000) +#define SED_STEP 1 /* 16-bit port on 16-bit boundry */ + +#define SED_REG16(_x_) *(volatile uint16_t *)((uint32_t)SED_REG_BASE + (((uint32_t)_x_ * SED_STEP) ^ 0)) /* Control/Status Registers, 16-bit mode */ +#define RD_FB16(_reg_,_val_) ((_val_) = *((volatile uint16_t *)(((uint32_t)SED_MEM_BASE + ((uint32_t)(_reg_ * SED_STEP) ^ 0))))) +#define WR_FB16(_reg_,_val_) (*((volatile uint16_t *)(((uint32_t)SED_MEM_BASE + ((uint32_t)(_reg_ * SED_STEP) ^ 0)))) = (_val_)) + +#if 0 +#define SED1356_REG_LCD_HOR_DISP SED_REG16(0x32) +#define SED1356_REG_LCD_HOR_NONDISP_and_START SED_REG16(0x34) +#define SED1356_REG_LCD_HOR_PULSE SED_REG16(0x36) +#define SED1356_REG_LCD_VER_DISP_HT_LO_and_HI SED_REG16(0x38) +#define SED1356_REG_LCD_VER_NONDISP_and_START SED_REG16(0x3a) +#define SED1356_REG_LCD_VER_PULSE SED_REG16(0x3c) +#define SED1356_REG_LCD_DISP_MODE_and_MISC SED_REG16(0x40) +#define SED1356_REG_LCD_DISP_START_LO_and_MID SED_REG16(0x42) +#define SED1356_REG_LCD_DISP_START_HI SED_REG16(0x44) +#define SED1356_REG_LCD_ADD_OFFSET_LO_and_HI SED_REG16(0x46) +#define SED1356_REG_LCD_PIXEL_PAN SED_REG16(0x48) +#define SED1356_REG_LCD_FIFO_THRESH_LO_and_HI SED_REG16(0x4a) +#endif + + +#define H2SED(_x_) (_x_) + +#define FB_SIZE (640 * 480) +#define SED_ROW_SIZE(_depth_) ((PIXELS_PER_ROW * _depth_) / 8) +#define SED_FB_SIZE(_depth_) (((PIXELS_PER_COL * PIXELS_PER_ROW) * _depth_) / 8) + +#define FONT_WIDTH 8 +#define FONT_HEIGHT 16 + +#define SED_GET_ADD(_row_, _col_, _depth_) \ + (((((_row_ * PIXELS_PER_ROW) * FONT_HEIGHT) \ + + (_col_ * FONT_WIDTH)) \ + * _depth_) / 8) + + +#define SED_GET_PHYS_ADD(_reg_) \ + (volatile unsigned long)(SED_MEM_BASE + ((_reg_ * SED_STEP) ^ 0)) + + +#include "sed1356_16bit.h" + +/* #define SED_DBG */ +int sed135x_tst = 0; + +void sed_write_frame_buffer( + uint32_t i, + uint16_t wr16 +) +{ + WR_FB16(i, wr16); +} + +int sed_frame_buffer_size(void) +{ + return SED_FB_SIZE(sed_color_depth); +} + +void sed_clr_row(int char_row) +{ + unsigned long sed_mem_add; + int i; + uint16_t wr16; + + /* clear the desired row */ + sed_mem_add = SED_GET_ADD(char_row, 0, sed_color_depth); + +#ifdef SED_DBG + sed135x_tst = 1; + printf("SED Clear Row %d, FB Add 0x%08lx, CPU Add 0x%08lx.\n ", char_row, sed_mem_add, SED_GET_PHYS_ADD(sed_mem_add)); + sed135x_tst = 0; +#endif + + switch (sed_color_depth) + { + case 4: + wr16 = ((sed_bg_color << 12) | (sed_bg_color << 8) | (sed_bg_color << 4) | (sed_bg_color << 0)); +#ifdef SED_DBG + sed135x_tst = 1; + printf("SED Clear Row %d, FB Add 0x%08lx to 0x%08lx.\n ", char_row, sed_mem_add, sed_mem_add + ((PIXELS_PER_ROW * FONT_HEIGHT) / 2)); + sed135x_tst = 0; +#endif + for (i = 0; i < ((PIXELS_PER_ROW * FONT_HEIGHT) / 2); i += 2){ + WR_FB16(sed_mem_add, wr16); + sed_mem_add += 2; + } /* for font_row */ + break; + case 8: + wr16 = ((sed_bg_color << 8) | (sed_bg_color << 0)); + for (i = 0; i < (PIXELS_PER_ROW * FONT_HEIGHT); i += 2){ + WR_FB16(sed_mem_add, wr16); + sed_mem_add += 2; + } /* for font_row */ + break; + case 16: + wr16 = ((vga_lookup[sed_bg_color])); + for (i = 0; i < ((PIXELS_PER_ROW * FONT_HEIGHT) * 2); i += 2){ + WR_FB16(sed_mem_add, wr16); + sed_mem_add += 2; + } /* for font_row */ + break; + } /* switch sed_color_depth */ +} /* sed_clr_row */ + +void sed_init(void) +{ + mode900lq = 0; + PIXELS_PER_ROW = 640; + PIXELS_PER_COL = 480; + COLS_PER_SCREEN = 80; + ROWS_PER_SCREEN = 30; + SED_HOR_PULSE_WIDTH_LCD = 0x0b; + SED_HOR_NONDISP_LCD = 0x13; + SED_VER_PULSE_WIDTH_LCD = 0x01; + SED_VER_PULSE_START_LCD = 0x09; + SED_VER_NONDISP_LCD = 0x2c; + + sed_color_depth = 16; /* 16 => vga lookup */ + sed_fg_color = 14; /* Bright Yellow */ + sed_bg_color = 1; /* Blue */ + sed_disp_mode_crt = 0; /* default to LCD */ + sed_fb_offset = 0x00; + sed_row = 0; + sed_col = 0; + + sed135x_ok = 1; + sed135x_tst = 0; + sed_clearscreen(); +} + +/* + * sed_putchar() + * + * This routine parses the character and calls sed_writechar if it is a + * printable character + */ +void sed_putchar(char c) +{ + + if ((sed135x_ok == 0) || (sed135x_tst == 1)) return; + + /* First parse the character to see if it printable or an + * acceptable control character. + */ + switch (c) { + case '\r': + sed_col = 0; + return; + case '\n': + sed_col = 0; + sed_scroll(); + return; + case '\b': + sed_col--; + if (sed_col < 0) { + sed_row--; + if (sed_row < 0) + sed_row = 0; + sed_col = COLS_PER_SCREEN - 1; + } + c = 0; /* erase the character */ + sed_writechar(c); + break; + default: + if (((uint8_t)c < FIRST_CHAR) || ((uint8_t)c > LAST_CHAR)) + return; /* drop anything we can't print */ + c -= FIRST_CHAR; /* get aligned to the first printable character */ + sed_writechar(c); + /* advance to next column */ + sed_col++; + if (sed_col == COLS_PER_SCREEN) { + sed_col = 0; + sed_scroll(); + } + break; + } + +} /* sed_putchar() */ + +/* + * sed_writechar() + * + * This routine writes the character to the screen at the current cursor + * location. + */ +void sed_writechar(uint8_t c) +{ + uint32_t sed_mem_add; + int font_row, font_col; + uint8_t font_data8; + uint16_t wr16; + + /* Convert the current row,col and color depth values + * into an address + */ + sed_mem_add = SED_GET_ADD(sed_row, sed_col, sed_color_depth); + +#ifdef SED_DBG + sed135x_tst = 1; + printf("SED writechar at row %d, col %d, FB Add 0x%08lx, CPU Add 0x%08lx.\n ", sed_row, sed_col, sed_mem_add, SED_GET_PHYS_ADD(sed_mem_add)); + sed135x_tst = 0; +#endif + + if (FONT_WIDTH == 8) { + switch (sed_color_depth) { + case 4: + /* Now render the font by painting one font row at a time */ + for (font_row = 0; font_row < FONT_HEIGHT; font_row++) { + /* get the font row of data */ + font_data8 = font8x16[(c * FONT_HEIGHT) + font_row]; + + + for (font_col = 0; font_col < 8; font_col += 4) + { + /* get a words worth of pixels */ + wr16 = (((font_data8 & 0x80) ? sed_fg_color << 12 : sed_bg_color << 12) + | ((font_data8 & 0x40) ? sed_fg_color << 8 : sed_bg_color << 8) + | ((font_data8 & 0x20) ? sed_fg_color << 4 : sed_bg_color << 4) + | ((font_data8 & 0x10) ? sed_fg_color << 0 : sed_bg_color << 0)); + font_data8 = font_data8 << 4; + WR_FB16(sed_mem_add, wr16); + /* if we are in the 2nd frame buffer, write to the 1st + * frame buffer also + */ + if (sed_row > (ROWS_PER_SCREEN - 1)) { + WR_FB16((sed_mem_add - SED_FB_SIZE(sed_color_depth)), wr16); + } + sed_mem_add += 2; + } /* for font_col */ + /* go to the next pixel row */ + sed_mem_add += (SED_ROW_SIZE(sed_color_depth) - ((FONT_WIDTH * sed_color_depth) / 8)); + } /* for font_row */ + break; + + case 8: + /* Now render the font by painting one font row at a time */ + for (font_row = 0; font_row < FONT_HEIGHT; font_row++) { + /* get the font row of data */ + font_data8 = font8x16[(c * FONT_HEIGHT) + font_row]; + for (font_col = 0; font_col < 8; font_col += 2) + { + /* get a words worth of pixels */ + wr16 = (((font_data8 & 0x80) ? sed_fg_color << 8 : sed_bg_color << 8) + | ((font_data8 & 0x40) ? sed_fg_color << 0 : sed_bg_color << 0)); + font_data8 = font_data8 << 2; + WR_FB16(sed_mem_add, wr16); + /* if we are in the 2nd frame buffer, write to the 1st + * frame buffer also + */ + if (sed_row > (ROWS_PER_SCREEN - 1)) { + WR_FB16((sed_mem_add - SED_FB_SIZE(sed_color_depth)), wr16); + } + sed_mem_add += 2; + } /* for font_col */ + /* go to the next pixel row */ + sed_mem_add += (SED_ROW_SIZE(sed_color_depth) - ((FONT_WIDTH * sed_color_depth) / 8)); + } /* for font_row */ + break; + + case 16: + /* Now render the font by painting one font row at a time */ + for (font_row = 0; font_row < FONT_HEIGHT; font_row++) { + /* get the font row of data */ + font_data8 = font8x16[(c * FONT_HEIGHT) + font_row]; + for (font_col = 0; font_col < 8; font_col++) + { + /* get a words worth of pixels */ + wr16 = ((font_data8 & 0x80) ? + vga_lookup[sed_fg_color] : vga_lookup[sed_bg_color]); + font_data8 = font_data8 << 1; + WR_FB16(sed_mem_add, wr16); + /* if we are in the 2nd frame buffer, write to the 1st + * frame buffer also. + */ + if (sed_row > (ROWS_PER_SCREEN - 1)) { + WR_FB16((sed_mem_add - SED_FB_SIZE(sed_color_depth)), wr16); + } + sed_mem_add += 2; + } /* for font_col */ + /* go to the next pixel row */ + sed_mem_add += (SED_ROW_SIZE(sed_color_depth) - ((FONT_WIDTH * sed_color_depth) / 8)); + } /* for font_row */ + break; + + } /* switch sed_color depth */ + } /* FONT_WIDTH == 8 */ + else + { + return; + } +} /* sed_writechar() */ + +static void sed_update_fb_offset(void) +{ + /* write the new sed_fb_offset value */ + if (sed_disp_mode_crt) { + /* before we change the address offset, wait for the display to + * go from active to non-active, unless the display is not enabled + */ + if (SED1356_REG_DISP_MODE & H2SED(SED1356_DISP_MODE_CRT)) { /* CRT is on */ + while ((SED1356_REG_CRT_VER_NONDISP_and_START & H2SED(SED1356_VER_NONDISP)) == 0) {} + while ((SED1356_REG_CRT_VER_NONDISP_and_START & H2SED(SED1356_VER_NONDISP)) == 1) {} + } + SED1356_REG_CRT_DISP_START_LO_and_MID = H2SED(((sed_fb_offset & 0x00ffff) >> 0)); + SED1356_REG_CRT_DISP_START_HI = H2SED(((sed_fb_offset & 0x070000) >> 16)); + } + else /* LCD */ + { + if (SED1356_REG_DISP_MODE & H2SED(SED1356_DISP_MODE_LCD)) { /* LCD is on */ + while ((SED1356_REG_LCD_VER_NONDISP_and_START & H2SED(SED1356_VER_NONDISP)) == 0) {} + while ((SED1356_REG_LCD_VER_NONDISP_and_START & H2SED(SED1356_VER_NONDISP)) == 1) {} + } + SED1356_REG_LCD_DISP_START_LO_and_MID = H2SED(((sed_fb_offset & 0x00ffff) >> 0)); + SED1356_REG_LCD_DISP_START_HI = H2SED(((sed_fb_offset & 0x070000) >> 16)); + } +} + +/* sed_scroll() + * + * Because we are most likely running out of FLASH and probably also with + * cache disabled, a brute force memcpy of the whole screen would be very + * slow, even with reduced color depths. Instead, we define a frame buffer + * that is twice the size of our actual display. This does limit us to a + * 1Mbyte active display size, but 640 x 480 @ 16-bits/pixel = 614K so it + * works just fine. 800 x 600 can be had by reducing the color depth to + * 8-bits/pixel and using the look up tables. + * + * With the double buffering, we always write to the first buffer, even + * when the second buffer is active. This allows us to scroll by adjusting + * the starting and ending addresses in the SED135x by one row. When we + * reach the end of our virtual buffer, we reset the starting and ending + * addresses to the first buffer. Note that we can not adjust the SED135x + * registers until it is in vertical retrace. That means we have to wait + * until it is in active display, then goes to non-display, unless the + * screen is blanked, in which case we can update immediately. + */ +void sed_scroll(void) +{ + sed_row++; + + /* clear the new row(s) */ + sed_clr_row(sed_row); + if (sed_row > (ROWS_PER_SCREEN - 1)) { + sed_clr_row(sed_row - ROWS_PER_SCREEN); + } + /* when sed_y_pos is greater than ROWS_PER_SCREEN we just adjust the + * start and end addresses in the SED135x. If it is equal to 2 * + * ROWS_PER_SCREEN, we reset the start and end addresses to SED_MEM_BASE. + */ + if (sed_row > (ROWS_PER_SCREEN - 1)) { + if (sed_row > ((ROWS_PER_SCREEN * 2) - 1)) { + sed_fb_offset = 0x00; + sed_row = 0; + sed_clearscreen(); + } else { + /* calculate the new offset address of the frame buffer in words */ + sed_fb_offset += (SED_GET_ADD(1, 0, sed_color_depth) / 2); + } + sed_update_fb_offset(); + } /* if (sed_row > (ROWS_PER_SCREEN - 1)) */ +} + +void sed_putstring(char *s) +{ + char *p = s; + while (*p) + sed_putchar(*p++); +} + +void sed_clearscreen(void) +{ + int i; + uint16_t wr16; + int bg = sed_bg_color; + int fbsize = sed_frame_buffer_size(); + + /* we double buffer so clear ALL of memory */ + fbsize *= 2; + + /* fill the frame buffer with incrementing color values */ + switch (sed_color_depth){ + case 4: wr16 = bg | bg << 4 | bg << 8 | bg << 12; break; + case 8: wr16 = bg | bg << 8; break; + /* 16-bits bypasses the lookup table */ + default: wr16 = vga_lookup[bg]; break; + } + for (i = 0; i < fbsize; i += 2){ + sed_write_frame_buffer(i, wr16); + } +} diff --git a/bsps/arm/csb337/console/uarts.c b/bsps/arm/csb337/console/uarts.c new file mode 100644 index 0000000000..b705a477b7 --- /dev/null +++ b/bsps/arm/csb337/console/uarts.c @@ -0,0 +1,243 @@ +/* + * Console driver for for KIT637_V6 (CSB637) + * + * This driver uses the shared console driver in + * ...../libbsp/shared/console.c + * + * Copyright (c) 2003 by Cogent Computer Systems + * Written by Jay Monkman + * + * Modified by Fernando Nicodemos + * from NCB - Sistemas Embarcados Ltda. (Brazil) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + * Modified and FrameBuffer Console Device Support added by + * Joel Sherrill, 2009. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +extern const console_fns dbgu_fns; + +#if ENABLE_LCD + extern const console_fns fbcons_fns; + #define LCD_DEV 1 +#else + #define LCD_DEV 0 +#endif + +#if (ENABLE_UMON && ENABLE_UMON_CONSOLE) + extern const console_fns umoncons_fns; + #define UMON_CONS_DEV 1 +#else + #define UMON_CONS_DEV 0 +#endif + +#if ENABLE_USART0 || ENABLE_USART1 || ENABLE_USART2 || ENABLE_USART3 + extern const console_fns usart_polling_fns; +#endif + +#if ENABLE_USART0 + #define USART0_DEV 1 +#else + #define USART0_DEV 0 +#endif + +#if ENABLE_USART1 + #define USART1_DEV 1 +#else + #define USART1_DEV 0 +#endif + +#if ENABLE_USART2 + #define USART2_DEV 1 +#else + #define USART2_DEV 0 +#endif + +#if ENABLE_USART3 + #define USART3_DEV 1 +#else + #define USART3_DEV 0 +#endif + +#define NUM_DEVS \ + (1 + LCD_DEV + UMON_CONS_DEV + \ + USART0_DEV + USART1_DEV + USART2_DEV + USART3_DEV) + +/* These are used by code in console.c */ +unsigned long Console_Configuration_Count = NUM_DEVS; + +/* + * There's one item in array for each UART. + * + * Some of these fields are marked "NOT USED". They are not used + * by console.c, but may be used by drivers in libchip + * + * when we add other types of UARTS we will need to move this + * structure to a generic uart.c file with only this in it + */ +console_tbl Console_Configuration_Ports[] = { + { + "/dev/com0", /* sDeviceName */ + SERIAL_CUSTOM, /* deviceType */ + &dbgu_fns, /* pDeviceFns */ + NULL, /* deviceProbe */ + NULL, /* pDeviceFlow */ + 0, /* ulMargin - NOT USED */ + 0, /* ulHysteresis - NOT USED */ + NULL, /* pDeviceParams */ + DBGU_BASE, /* ulCtrlPort1 - Pointer to DBGU regs */ + 0, /* ulCtrlPort2 - NOT USED */ + 0, /* ulDataPort - NOT USED */ + NULL, /* getRegister - NOT USED */ + NULL, /* setRegister - NOT USED */ + NULL, /* getData - NOT USED */ + NULL, /* setData - NOT USED */ + 0, /* ulClock - NOT USED */ + 0 /* ulIntVector - NOT USED */ + }, +#if ENABLE_LCD + { + "/dev/fbcons", /* sDeviceName */ + SERIAL_CUSTOM, /* deviceType */ + &fbcons_fns, /* pDeviceFns */ + NULL, /* deviceProbe */ + NULL, /* pDeviceFlow */ + 0, /* ulMargin - NOT USED */ + 0, /* ulHysteresis - NOT USED */ + NULL, /* pDeviceParams */ + 0, /* ulCtrlPort1 - Pointer to DBGU regs */ + 0, /* ulCtrlPort2 - NOT USED */ + 0, /* ulDataPort - NOT USED */ + NULL, /* getRegister - NOT USED */ + NULL, /* setRegister - NOT USED */ + NULL, /* getData - NOT USED */ + NULL, /* setData - NOT USED */ + 0, /* ulClock - NOT USED */ + 0 /* ulIntVector - NOT USED */ + }, +#endif +#if (ENABLE_UMON && ENABLE_UMON_CONSOLE) + { + "/dev/umon", /* sDeviceName */ + SERIAL_CUSTOM, /* deviceType */ + &umoncons_fns, /* pDeviceFns */ + NULL, /* deviceProbe */ + NULL, /* pDeviceFlow */ + 0, /* ulMargin - NOT USED */ + 0, /* ulHysteresis - NOT USED */ + NULL, /* pDeviceParams */ + 0, /* ulCtrlPort1 - Pointer to UMON regs */ + 0, /* ulCtrlPort2 - NOT USED */ + 0, /* ulDataPort - NOT USED */ + NULL, /* getRegister - NOT USED */ + NULL, /* setRegister - NOT USED */ + NULL, /* getData - NOT USED */ + NULL, /* setData - NOT USED */ + 0, /* ulClock - NOT USED */ + 0 /* ulIntVector - NOT USED */ + }, +#endif +#if ENABLE_USART0 + { + "/dev/com1", /* sDeviceName */ + SERIAL_CUSTOM, /* deviceType */ + &usart_polling_fns,/* pDeviceFns */ + NULL, /* deviceProbe */ + NULL, /* pDeviceFlow */ + 0, /* ulMargin - NOT USED */ + 0, /* ulHysteresis - NOT USED */ + NULL, /* pDeviceParams */ + USART0_BASE, /* ulCtrlPort1 - Pointer to USART 0 regs */ + 0, /* ulCtrlPort2 - NOT USED */ + 0, /* ulDataPort - NOT USED */ + NULL, /* getRegister - NOT USED */ + NULL, /* setRegister - NOT USED */ + NULL, /* getData - NOT USED */ + NULL, /* setData - NOT USED */ + 0, /* ulClock - NOT USED */ + 0 /* ulIntVector - NOT USED */ + }, +#endif +#if ENABLE_USART1 + { + "/dev/com2", /* sDeviceName */ + SERIAL_CUSTOM, /* deviceType */ + &usart_polling_fns,/* pDeviceFns */ + NULL, /* deviceProbe */ + NULL, /* pDeviceFlow */ + 0, /* ulMargin - NOT USED */ + 0, /* ulHysteresis - NOT USED */ + NULL, /* pDeviceParams */ + USART1_BASE, /* ulCtrlPort1 - Pointer to USART 1 regs */ + 0, /* ulCtrlPort2 - NOT USED */ + 0, /* ulDataPort - NOT USED */ + NULL, /* getRegister - NOT USED */ + NULL, /* setRegister - NOT USED */ + NULL, /* getData - NOT USED */ + NULL, /* setData - NOT USED */ + 0, /* ulClock - NOT USED */ + 0 /* ulIntVector - NOT USED */ + }, +#endif +#if ENABLE_USART2 + { + "/dev/com3", /* sDeviceName */ + SERIAL_CUSTOM, /* deviceType */ + &usart_polling_fns,/* pDeviceFns */ + NULL, /* deviceProbe */ + NULL, /* pDeviceFlow */ + 0, /* ulMargin - NOT USED */ + 0, /* ulHysteresis - NOT USED */ + NULL, /* pDeviceParams */ + USART2_BASE, /* ulCtrlPort1 - Pointer to USART 2 regs */ + 0, /* ulCtrlPort2 - NOT USED */ + 0, /* ulDataPort - NOT USED */ + NULL, /* getRegister - NOT USED */ + NULL, /* setRegister - NOT USED */ + NULL, /* getData - NOT USED */ + NULL, /* setData - NOT USED */ + 0, /* ulClock - NOT USED */ + 0 /* ulIntVector - NOT USED */ + }, +#endif +#if ENABLE_USART3 + { + "/dev/com4", /* sDeviceName */ + SERIAL_CUSTOM, /* deviceType */ + &usart_polling_fns,/* pDeviceFns */ + NULL, /* deviceProbe */ + NULL, /* pDeviceFlow */ + 0, /* ulMargin - NOT USED */ + 0, /* ulHysteresis - NOT USED */ + NULL, /* pDeviceParams */ + USART3_BASE, /* ulCtrlPort1 - Pointer to USART 3 regs */ + 0, /* ulCtrlPort2 - NOT USED */ + 0, /* ulDataPort - NOT USED */ + NULL, /* getRegister - NOT USED */ + NULL, /* setRegister - NOT USED */ + NULL, /* getData - NOT USED */ + NULL, /* setData - NOT USED */ + 0, /* ulClock - NOT USED */ + 0 /* ulIntVector - NOT USED */ + } +#endif +}; + +console_tbl *BSP_get_uart_from_minor(int minor) +{ + return Console_Port_Tbl[minor]; +} diff --git a/bsps/arm/csb337/console/usart.c b/bsps/arm/csb337/console/usart.c new file mode 100644 index 0000000000..23b877ce64 --- /dev/null +++ b/bsps/arm/csb337/console/usart.c @@ -0,0 +1,261 @@ +/* + * Driver for AT91RM9200 USART ports + */ + +/* + * COPYRIGHT (c) 2006-2009. + * NCB - Sistemas Embarcados Ltda. (Brazil) + * Fernando Nicodemos + * + * and + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. +*/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* static function prototypes */ +static int usart_first_open(int major, int minor, void *arg); +static int usart_last_close(int major, int minor, void *arg); +static int usart_read_polled(int minor); +static ssize_t usart_write_polled_support(int minor, const char *buf, size_t len); +static void usart_init(int minor); +static void usart_write_polled(int minor, char c); +static int usart_set_attributes(int minor, const struct termios *t); +at91rm9200_usart_regs_t *usart_get_base(int minor); + +/* Pointers to functions for handling the UART polled. */ +const console_fns usart_polling_fns = { + libchip_serial_default_probe, /* deviceProbe */ + usart_first_open, /* deviceFirstOpen */ + usart_last_close, /* deviceLastClose */ + usart_read_polled, /* deviceRead */ + usart_write_polled_support, /* deviceWrite */ + usart_init, /* deviceInitialize */ + usart_write_polled, /* deviceWritePolled */ + usart_set_attributes, /* deviceSetAttributes */ + FALSE /* TRUE if interrupt driven, FALSE if not. */ +}; + +at91rm9200_usart_regs_t *usart_get_base(int minor) +{ + console_tbl *console_entry; + at91rm9200_usart_regs_t *port; + + console_entry = BSP_get_uart_from_minor(minor); + + if (console_entry == NULL) + return 0; + + port = (at91rm9200_usart_regs_t *) console_entry->ulCtrlPort1; + //printk( "minor=%d entry=%p port=%p\n", minor, console_entry, port ); + + return port; +} + +/* + * Functions called via callbacks (i.e. the ones in uart_fns + */ + +/* + * This is called the first time each device is opened. Since + * the driver is polled, we don't have to do anything. If the driver + * were interrupt driven, we'd enable interrupts here. + */ +static int usart_first_open(int major, int minor, void *arg) +{ + at91rm9200_usart_regs_t *usart; + + usart = usart_get_base(minor); + if ( !usart ) + return -1; + + /* XXX port isn't being initialized or enabled */ + + /* XXX I hope this is enough */ + usart->cr = (US_CR_RXEN | US_CR_TXEN); + return 0; +} + +/* + * This is called the last time each device is closed. Since + * the driver is polled, we don't have to do anything. If the driver + * were interrupt driven, we'd disable interrupts here. + */ +static int usart_last_close(int major, int minor, void *arg) +{ + at91rm9200_usart_regs_t *usart; + + usart = usart_get_base(minor); + if ( !usart ) + return -1; + + return 0; +} + +/* + * Read one character from UART. + * + * return -1 if there's no data, otherwise return + * the character in lowest 8 bits of returned int. + */ +static int usart_read_polled(int minor) +{ + at91rm9200_usart_regs_t *usart; + + usart = usart_get_base(minor); + if ( !usart ) + return -1; + + /* if nothing ready return -1 */ + if ( (usart->sr & US_IER_RXRDY) == 0 ) + return -1; + + return usart->rhr; +} + + +/* + * Write character out + */ +static void usart_write_polled(int minor, char c) +{ + at91rm9200_usart_regs_t *usart; + + usart = usart_get_base(minor); + if ( !usart ) + return; + + /* delay until TX empty */ + while ( (usart->sr & US_IER_TXEMPTY) == 0 ) + ; + + usart->thr = c; +} + +/* + * Write buffer to UART + * + * return 1 on success, -1 on error + */ +static ssize_t usart_write_polled_support(int minor, const char *buf, size_t len) +{ + at91rm9200_usart_regs_t *usart; + int nwrite=0; + + /* + * Verify the minor number + */ + usart = usart_get_base(minor); + if ( !usart ) + return -1; + + /* + * poll each byte in the string out of the port. + */ + while (nwrite < len) { + usart_write_polled(minor, *buf++); + nwrite++; + } + + /* + * return the number of bytes written. + */ + return nwrite; + + return 1; +} + + +/* Set up the UART. */ +static void usart_init(int minor) +{ + at91rm9200_usart_regs_t *usart; + + usart = usart_get_base(minor); + if ( !usart ) + return; + +} + + +/* This is for setting baud rate, bits, etc. */ +static int usart_set_attributes(int minor, const struct termios *t) +{ + uint32_t brgr; + uint32_t mode, baud, baud_requested; + at91rm9200_usart_regs_t *usart; + + usart = usart_get_base(minor); + if ( !usart ) + return -1; + + /* Get current mode register */ + mode = usart->mr & ~(US_MR_USMODE | US_MR_USCLKS | US_MR_CHRL + | US_MR_PAR | US_MR_NBSTOP); + + /* Byte size */ + switch (t->c_cflag & CSIZE){ + case CS5: + mode |= US_MR_CHRL_5; + break; + case CS6: + mode |= US_MR_CHRL_6; + break; + case CS7: + mode |= US_MR_CHRL_7; + break; + default: + mode |= US_MR_CHRL_8; + break; + } + + /* Stop bits */ + if (t->c_cflag & CSTOPB){ + mode |= US_MR_NBSTOP_2; /* 2 stop bits */ + } else + mode |= US_MR_NBSTOP_1; /* 1 stop bits */ + + /* Parity */ + if (t->c_cflag & PARENB){ + /* Mark or Space parity */ + if (t->c_cflag & PARODD){ + mode |= US_MR_PAR_ODD; + } else + mode |= US_MR_PAR_EVEN; + } else + mode |= US_MR_PAR_NONE; + + baud_requested = t->c_ospeed; + + /* If not, set the dbgu console baud as USART baud default */ + if (!baud_requested) + baud_requested = BSP_get_baud(); + + baud = rtems_termios_baud_to_number(baud_requested); + + brgr = (at91rm9200_get_mck() / 16) / baud; + + if (brgr > 65535){ /* BRGR is 16-bit, so switch to slower clock */ + brgr /= 8; + mode |= US_MR_USCLKS_MCK_DIV8; + } + + usart->mr = mode; + usart->brgr = brgr; + return 0; +} diff --git a/bsps/arm/edb7312/console/uart.c b/bsps/arm/edb7312/console/uart.c new file mode 100644 index 0000000000..4ba71c8cc2 --- /dev/null +++ b/bsps/arm/edb7312/console/uart.c @@ -0,0 +1,169 @@ +/* + * Cirrus EP7312 Console Driver + * + * Copyright (c) 2002 by Jay Monkman + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include /* Must be before libio.h */ +#include +#include +#include + +#include +#include +#include + +#define NUM_DEVS 1 +int uart_poll_read(int minor); + +static int uart_first_open(int major, int minor, void *arg); +static int uart_last_close(int major, int minor, void *arg); +static int uart_read(int minor); +static ssize_t uart_write(int minor, const char *buf, size_t len); +static void uart_init(int minor); +static void uart_write_polled(int minor, char c); +static int uart_set_attributes(int minor, const struct termios *t); + +unsigned long Console_Configuration_Count = NUM_DEVS; + +const console_fns uart_fns = +{ + libchip_serial_default_probe, + uart_first_open, + uart_last_close, + uart_read, + uart_write, + uart_init, + uart_write_polled, + uart_set_attributes, + FALSE +}; +console_tbl Console_Configuration_Ports[] = { + { + "/dev/com0", /* sDeviceName */ + SERIAL_CUSTOM, /* deviceType */ + &uart_fns, /* pDeviceFns */ + NULL, /* deviceProbe */ + NULL, /* pDeviceFlow */ + 16, /* ulMargin */ + 8, /* ulHysteresis */ + NULL, /* pDeviceParams */ + (uint32_t)EP7312_UARTCR1, /* ulCtrlPort1 */ + (uint32_t)EP7312_SYSFLG1, /* ulCtrlPort2 */ + (uint32_t)EP7312_UARTDR1, /* ulDataPort */ + 0, /* getRegister */ + 0, /* setRegister */ + 0, /* getData */ + 0, /* setData */ + 0, /* ulClock */ + 0 /* ulIntVector */ + }}; + +static int uart_first_open(int major, int minor, void *arg) {return 0;} +static int uart_last_close(int major, int minor, void *arg) {return 0;} +static int uart_read(int minor) +{ + return uart_poll_read(minor); +} + +static void uart_write_polled(int minor, char c) +{ + uart_write(minor, &c, 1); +} + +static int uart_set_attributes(int minor, const struct termios *t) +{ + return 0; +} + +int uart_poll_read(int minor) +{ + volatile uint32_t *data_reg; + volatile uint32_t *ctrl_reg2; + char c; + int err; + + data_reg = (uint32_t *)Console_Port_Tbl[minor]->ulDataPort; + ctrl_reg2 = (uint32_t *)Console_Port_Tbl[minor]->ulCtrlPort2; + + if ((*ctrl_reg2 & EP7312_UART_URXFE1) != 0) { + return -1; + } + + err = *data_reg; + c = err & 0xff; + err &= (EP7312_UART_FRMERR | EP7312_UART_PARERR | EP7312_UART_OVERR); + + return c; +} + +static ssize_t uart_do_write( + volatile uint32_t *uartdr, + const char *buf, + size_t len, + volatile uint32_t *sysflg +) +{ + size_t i; + + for (i = 0; i < len; i++) { + /* Wait for fifo to have room */ + while ((*sysflg & EP7312_UART_UTXFF1) != 0) { + continue; + } + + *uartdr = buf[i]; + } + + return len; +} + +static ssize_t uart_write(int minor, const char *buf, size_t len) +{ + volatile uint32_t *data_reg; + volatile uint32_t *ctrl_reg2; + + data_reg = (uint32_t *)Console_Port_Tbl[minor]->ulDataPort; + ctrl_reg2 = (uint32_t *)Console_Port_Tbl[minor]->ulCtrlPort2; + + return uart_do_write(data_reg, buf, len, ctrl_reg2); +} + +static void uart_init(int minor) +{ + volatile uint32_t *ctrl_reg1; + + ctrl_reg1 = (uint32_t *)Console_Port_Tbl[minor]->ulCtrlPort1; + + /* *ctrl_reg = (BSP_UART_DATA8 | + BSP_UART_STOP1 | + BSP_UART_PARITY_NONE | + EP7312_UART_FIFOEN | + BSP_UART_BAUD_9600); + */ + *ctrl_reg1 = (EP7312_UART_WRDLEN8 | + EP7312_UART_FIFOEN | + 0x17); /* 9600 baud */ + +} + +/* + * Debug IO support + */ +static void _BSP_null_char(char c) +{ + uart_do_write(EP7312_UARTDR1, &c, 1, EP7312_SYSFLG1); +} + +static int _BSP_get_char(void) +{ + return uart_poll_read(0); +} + +BSP_output_char_function_type BSP_output_char = _BSP_null_char; + +BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char; diff --git a/bsps/arm/gdbarmsim/console/console-io.c b/bsps/arm/gdbarmsim/console/console-io.c new file mode 100644 index 0000000000..8bea74d934 --- /dev/null +++ b/bsps/arm/gdbarmsim/console/console-io.c @@ -0,0 +1,58 @@ +/* + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include + +/* + * console_initialize_hardware + * + * This routine initializes the console hardware. + * + */ +void console_initialize_hardware(void) +{ + return; +} + +/* + * console_outbyte_polled + * + * This routine transmits a character using polling. + */ +void console_outbyte_polled( + int port, + char ch +) +{ + gdbarmsim_writec(ch); +} + +/* + * console_inbyte_nonblocking + * + * This routine polls for a character. + */ + +int console_inbyte_nonblocking( + int port +) +{ + return -1; +} + +#include + +static void MyBSP_output_char(char c) { console_outbyte_polled( 0, c ); } + +BSP_output_char_function_type BSP_output_char = MyBSP_output_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/arm/gumstix/console/ffuart.c b/bsps/arm/gumstix/console/ffuart.c new file mode 100644 index 0000000000..335fc6f4de --- /dev/null +++ b/bsps/arm/gumstix/console/ffuart.c @@ -0,0 +1,227 @@ +/* + * Console driver for pxa255 full function port by Yang Xi + * Copyright (c) 2004 by Jay Monkman + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +volatile int dbg_dly; + +/* static function prototypes */ +static int ffuart_first_open(int major, int minor, void *arg); +static int ffuart_last_close(int major, int minor, void *arg); +static int ffuart_read(int minor); +static ssize_t ffuart_write(int minor, const char *buf, size_t len); +static void ffuart_init(int minor); +static void ffuart_write_polled(int minor, char c); +static int ffuart_set_attributes(int minor, const struct termios *t); + +/* Pointers to functions for handling the UART. */ +const console_fns ffuart_fns = +{ + libchip_serial_default_probe, + ffuart_first_open, + ffuart_last_close, + ffuart_read, + ffuart_write, + ffuart_init, + ffuart_write_polled, /* not used in this driver */ + ffuart_set_attributes, + FALSE /* TRUE if interrupt driven, FALSE if not. */ +}; + + +/* + * This is called the first time each device is opened. Since + * the driver is polled, we don't have to do anything. If the driver + * were interrupt driven, we'd enable interrupts here. + */ +static int ffuart_first_open(int major, int minor, void *arg) +{ + return 0; +} + + +/* + * This is called the last time each device is closed. Since + * the driver is polled, we don't have to do anything. If the driver + * were interrupt driven, we'd disable interrupts here. + */ +static int ffuart_last_close(int major, int minor, void *arg) +{ + return 0; +} + + +/* + * Read one character from UART. + * + * return -1 if there's no data, otherwise return + * the character in lowest 8 bits of returned int. + */ +static int ffuart_read(int minor) +{ + char c; + console_tbl *console_entry; + ffuart_reg_t *ffuart; + + console_entry = BSP_get_uart_from_minor(minor); + + if (console_entry == NULL) { + return -1; + } + + ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1; + + if (!(ffuart->lsr & FULL_RECEIVE)) { + return -1; + } + + c = ffuart->rbr & 0xff; + + return c; +} + + +/* + * Write buffer to UART + * + * return 1 on success, -1 on error + */ +static ssize_t ffuart_write(int minor, const char *buf, size_t len) +{ + size_t i, x; + char c; + console_tbl *console_entry; + ffuart_reg_t *ffuart; + + console_entry = BSP_get_uart_from_minor(minor); + + if (console_entry == NULL) { + return -1; + } + + ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1; + + for (i = 0; i < len; i++) { + + while(1) { + if (ffuart->lsr & SEND_EMPTY) { + break; + } + } + + c = (char) buf[i]; +#if ON_SKYEYE != 1 + if(c=='\n'){ + ffuart->rbr = '\r'; + for (x = 0; x < 100; x++) { + dbg_dly++; /* using a global so this doesn't get optimized out */ + } + while(1){ + if(ffuart->lsr & SEND_EMPTY){ + break; + } + } + } +#endif + ffuart->rbr = c; + + /* the TXRDY flag does not seem to update right away (is this true?) */ + /* so we wait a bit before continuing */ + for (x = 0; x < 100; x++) { + dbg_dly++; /* using a global so this doesn't get optimized out */ + } + } + + return 1; +} + + +static void ffuart_init(int minor) +{ + + + console_tbl *console_entry; + ffuart_reg_t *ffuart; + unsigned int divisor; + + console_entry = BSP_get_uart_from_minor(minor); + + + + if (console_entry == NULL) { + return; + } + + ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1; + ffuart->lcr |= DLAB; + /*Set the Bound*/ + ffuart->lcr |= DLAB; + divisor = FREQUENCY_UART / (115200*16); + ffuart->rbr = divisor & 0xff; + ffuart->ier = (divisor >> 8)&0xff; + /*Disable FIFO*/ + ffuart->iir = 0; + ffuart->lcr &=~DLAB; + /*Enable UART*/ + ffuart->ier = 0x40; + ffuart->lcr = EIGHT_BITS_NOPARITY_1STOPBIT; + +} + +/* I'm not sure this is needed for the shared console driver. */ +static void ffuart_write_polled(int minor, char c) +{ + ffuart_write(minor, &c, 1); +} + +/* This is for setting baud rate, bits, etc. */ +static int ffuart_set_attributes(int minor, const struct termios *t) +{ + return 0; +} + +/***********************************************************************/ +/* + * The following functions are not used by TERMIOS, but other RTEMS + * functions use them instead. + */ +/***********************************************************************/ +/* + * Read from UART. This is used in the exit code, and can't + * rely on interrupts. + */ +static int ffuart_poll_read(int minor) +{ + return ffuart_read(minor); +} + + +/* + * Write a character to the console. This is used by printk() and + * maybe other low level functions. It should not use interrupts or any + * RTEMS system calls. It needs to be very simple + */ +static void _BSP_put_char( char c ) { + ffuart_write_polled(0, c); +} + +static int _BSP_poll_char(void) { + return ffuart_poll_read(0); +} + +BSP_output_char_function_type BSP_output_char = _BSP_put_char; +BSP_polling_getchar_function_type BSP_poll_char = _BSP_poll_char; diff --git a/bsps/arm/gumstix/console/uarts.c b/bsps/arm/gumstix/console/uarts.c new file mode 100644 index 0000000000..08408695e0 --- /dev/null +++ b/bsps/arm/gumstix/console/uarts.c @@ -0,0 +1,66 @@ +/* + * Console driver for GUMSTIX by Yang Xi + * + * This driver uses the shared console driver in + * ...../libbsp/shared/console.c + * + * Copyright (c) 2003 by Cogent Computer Systems + * Written by Jay Monkman + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include + +#include +#include +#include + +/* How many serial ports? */ +#define NUM_DEVS 1 + +/* These are used by code in console.c */ +unsigned long Console_Configuration_Count = NUM_DEVS; + +extern const console_fns ffuart_fns; + +/* + * There's one item in array for each UART. + * + * Some of these fields are marked "NOT USED". They are not used + * by console.c, but may be used by drivers in libchip + * + * when we add other types of UARTS we will need to move this + * structure to a generic uart.c file with only this in it + */ +console_tbl Console_Configuration_Ports[] = { + { + "/dev/com0", /* sDeviceName */ + SERIAL_CUSTOM, /* deviceType */ + &ffuart_fns, /* pDeviceFns */ + NULL, /* deviceProbe */ + NULL, /* pDeviceFlow */ + 0, /* ulMargin - NOT USED */ + 0, /* ulHysteresis - NOT USED */ + NULL, /* pDeviceParams */ + FFUART_BASE, /* ulCtrlPort1 - Pointer to DBGU regs */ + 0, /* ulCtrlPort2 - NOT USED */ + 0, /* ulDataPort - NOT USED */ + NULL, /* getRegister - NOT USED */ + NULL, /* setRegister - NOT USED */ + NULL, /* getData - NOT USED */ + NULL, /* setData - NOT USED */ + 0, /* ulClock - NOT USED */ + 0 /* ulIntVector - NOT USED */ + }}; + + +console_tbl *BSP_get_uart_from_minor(int minor) +{ + return Console_Port_Tbl[minor]; +} diff --git a/bsps/arm/imx/console/console-config.c b/bsps/arm/imx/console/console-config.c new file mode 100644 index 0000000000..0731446f08 --- /dev/null +++ b/bsps/arm/imx/console/console-config.c @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2017 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#define IMX_UART_TX_FIFO_LEVEL 16 + +typedef struct { + rtems_termios_device_context base; + volatile imx_uart *regs; +#ifdef CONSOLE_USE_INTERRUPTS + rtems_vector_number irq; + int tx_in_progress; +#endif +} imx_uart_context; + +static imx_uart_context imx_uart_instances[7]; + +static imx_uart_context *imx_uart_console = &imx_uart_instances[0]; + +static volatile imx_uart *imx_uart_get_regs(rtems_termios_device_context *base) +{ + imx_uart_context *ctx; + + ctx = (imx_uart_context *) base; + return ctx->regs; +} + +static void imx_uart_write_polled(rtems_termios_device_context *base, char c) +{ + volatile imx_uart *regs; + + regs = imx_uart_get_regs(base); + + while ((regs->usr1 & IMX_UART_USR1_TRDY) == 0) { + /* Wait */ + } + + regs->utxd = IMX_UART_UTXD_TX_DATA(c); +} + +void imx_uart_console_drain(void) +{ + volatile imx_uart *regs; + + regs = imx_uart_get_regs(&imx_uart_console->base); + + if (regs != NULL) { + while ((regs->usr2 & IMX_UART_USR2_TXFE) == 0) { + /* Wait */ + } + } +} + +static void imx_output_char(char c) +{ + imx_uart_write_polled(&imx_uart_console->base, c); +} + +static void imx_uart_init_context( + imx_uart_context *ctx, + const char *fdt, + const char *serial +) +{ + int node; + + rtems_termios_device_context_initialize(&ctx->base, "UART"); + node = fdt_path_offset(fdt, serial); + ctx->regs = imx_get_reg_of_node(fdt, node); +#ifdef CONSOLE_USE_INTERRUPTS + ctx->irq = imx_get_irq_of_node(fdt, node, 0); +#endif +} + +static void imx_uart_probe(void) +{ + const void *fdt; + int node; + int offset; + const char *console; + size_t i; + + fdt = bsp_fdt_get(); + node = fdt_path_offset(fdt, "/chosen"); + + console = fdt_getprop(fdt, node, "stdout-path", NULL); + if (console == NULL) { + console = ""; + } + + node = fdt_path_offset(fdt, "/aliases"); + offset = fdt_first_property_offset(fdt, node); + i = 0; + + while (offset >= 0 && i < RTEMS_ARRAY_SIZE(imx_uart_instances)) { + const struct fdt_property *prop; + + prop = fdt_get_property_by_offset(fdt, offset, NULL); + + if (prop != NULL) { + const char *name; + + name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); + if (strstr(name, "serial") != NULL) { + imx_uart_context *ctx; + const char *serial; + + ctx = &imx_uart_instances[i]; + serial = prop->data; + + if (strcmp(serial, console) == 0) { + imx_uart_console = ctx; + } + + imx_uart_init_context(ctx, fdt, serial); + ++i; + } + } + + offset = fdt_next_property_offset(fdt, offset); + } + + BSP_output_char = imx_output_char; +} + +static void imx_output_char_init(char c) +{ + imx_uart_probe(); + imx_output_char(c); +} + +BSP_output_char_function_type BSP_output_char = imx_output_char_init; + +BSP_polling_getchar_function_type BSP_poll_char = NULL; + +#ifdef CONSOLE_USE_INTERRUPTS +static void imx_uart_interrupt(void *arg) +{ + rtems_termios_tty *tty; + imx_uart_context *ctx; + volatile imx_uart *regs; + uint32_t usr2; + + tty = arg; + ctx = rtems_termios_get_device_context(tty); + regs = ctx->regs; + usr2 = regs->usr2; + + regs->usr1 = IMX_UART_USR1_AGTIM; + + while ((usr2 & IMX_UART_USR2_RDR) != 0) { + char c; + + c = IMX_UART_URXD_RX_DATA_GET(regs->urxd); + rtems_termios_enqueue_raw_characters(tty, &c, 1); + usr2 = regs->usr2; + } + + if (ctx->tx_in_progress > 0 && (regs->usr1 & IMX_UART_USR1_TRDY) != 0) { + rtems_termios_dequeue_characters(tty, ctx->tx_in_progress); + } +} +#endif + +static bool imx_uart_set_attributes( + rtems_termios_device_context *base, + const struct termios *term +) +{ + imx_uart_context *ctx; + volatile imx_uart *regs; + uint32_t ufcr; + uint32_t baud; + + ctx = (imx_uart_context *) base; + regs = imx_uart_get_regs(&ctx->base); + + baud = rtems_termios_baud_to_number(term->c_ospeed); + + if (baud != 0) { + ufcr = regs->ufcr; + ufcr = IMX_UART_UFCR_RFDIV_SET(ufcr, 0x5); + regs->ufcr = ufcr; + regs->ubir = 15; + regs->ubmr = imx_ccm_uart_hz() / baud - 1; + } + + return true; +} + +static bool imx_uart_first_open( + rtems_termios_tty *tty, + rtems_termios_device_context *base, + struct termios *term, + rtems_libio_open_close_args_t *args +) +{ + imx_uart_context *ctx; + volatile imx_uart *regs; +#ifdef CONSOLE_USE_INTERRUPTS + rtems_status_code sc; + uint32_t ufcr; +#endif + + ctx = (imx_uart_context *) base; + regs = imx_uart_get_regs(&ctx->base); + + regs->ucr1 = IMX_UART_UCR1_UARTEN; + regs->ucr2 = IMX_UART_UCR2_IRTS | IMX_UART_UCR2_WS | IMX_UART_UCR2_RXEN + | IMX_UART_UCR2_TXEN | IMX_UART_UCR2_SRST; + + rtems_termios_set_initial_baud(tty, 115200); + imx_uart_set_attributes(base, term); + +#ifdef CONSOLE_USE_INTERRUPTS + ufcr = regs->ufcr; + ufcr = IMX_UART_UFCR_RXTL_SET(ufcr, 16); + ufcr = IMX_UART_UFCR_TXTL_SET(ufcr, IMX_UART_TX_FIFO_LEVEL); + regs->ufcr = ufcr; + regs->ucr1 |= IMX_UART_UCR1_RRDYEN; + regs->ucr2 |= IMX_UART_UCR2_ATEN; + sc = rtems_interrupt_handler_install( + ctx->irq, + "UART", + RTEMS_INTERRUPT_SHARED, + imx_uart_interrupt, + tty + ); + if (sc != RTEMS_SUCCESSFUL) { + return false; + } +#endif + + return true; +} + +static void imx_uart_last_close( + rtems_termios_tty *tty, + rtems_termios_device_context *base, + rtems_libio_open_close_args_t *args +) +{ +#ifdef CONSOLE_USE_INTERRUPTS + imx_uart_context *ctx; + + ctx = (imx_uart_context *) base; + rtems_interrupt_handler_remove(ctx->irq, imx_uart_interrupt, tty); +#endif +} + +static void imx_uart_write( + rtems_termios_device_context *base, + const char *buf, + size_t len +) +{ +#ifdef CONSOLE_USE_INTERRUPTS + imx_uart_context *ctx; + volatile imx_uart *regs; + int n; + uint32_t ucr1; + + ctx = (imx_uart_context *) base; + regs = imx_uart_get_regs(&ctx->base); + ucr1 = regs->ucr1; + + if (len > 0) { + int i; + + n = (int) MIN(len, IMX_UART_TX_FIFO_LEVEL); + ucr1 |= IMX_UART_UCR1_TRDYEN; + + for (i = 0; i < n; ++i) { + regs->utxd = IMX_UART_UTXD_TX_DATA(buf[i]); + } + } else { + n = 0; + ucr1 &= ~IMX_UART_UCR1_TRDYEN; + } + + regs->ucr1 = ucr1; + ctx->tx_in_progress = n; +#else + size_t i; + + for (i = 0; i < len; ++i) { + imx_uart_write_polled(base, buf[i]); + } +#endif +} + +#ifndef CONSOLE_USE_INTERRUPTS +static int imx_uart_read(rtems_termios_device_context *base) +{ + volatile imx_uart *regs; + + regs = imx_uart_get_regs(base); + + if ((regs->usr2 & IMX_UART_USR2_RDR) != 0) { + return IMX_UART_URXD_RX_DATA_GET(regs->urxd); + } else { + return -1; + } +} +#endif + +static const rtems_termios_device_handler imx_uart_handler = { + .first_open = imx_uart_first_open, + .last_close = imx_uart_last_close, + .write = imx_uart_write, + .set_attributes = imx_uart_set_attributes, +#ifdef CONSOLE_USE_INTERRUPTS + .mode = TERMIOS_IRQ_DRIVEN +#else + .poll_read = imx_uart_read, + .mode = TERMIOS_POLLED +#endif +}; + +rtems_status_code console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + char path[] = "/dev/ttyS?"; + size_t i; + + rtems_termios_initialize(); + + for (i = 0; i < RTEMS_ARRAY_SIZE(imx_uart_instances); ++i) { + imx_uart_context *ctx; + + ctx = &imx_uart_instances[i]; + path[sizeof(path) - 2] = (char) ('0' + i); + + rtems_termios_device_install( + path, + &imx_uart_handler, + NULL, + &ctx->base + ); + + if (ctx == imx_uart_console) { + link(path, CONSOLE_DEVICE_NAME); + } + } + + return RTEMS_SUCCESSFUL; +} + +RTEMS_SYSINIT_ITEM( + imx_uart_probe, + RTEMS_SYSINIT_BSP_START, + RTEMS_SYSINIT_ORDER_LAST +); diff --git a/bsps/arm/lm3s69xx/console/console-config.c b/bsps/arm/lm3s69xx/console/console-config.c new file mode 100644 index 0000000000..b702f0cd66 --- /dev/null +++ b/bsps/arm/lm3s69xx/console/console-config.c @@ -0,0 +1,78 @@ +/* + * Copyright © 2013 Eugeniy Meshcheryakov + * + * Copyright (c) 2011 Sebastian Huber. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include + +#include +#include +#include +#include + +console_tbl Console_Configuration_Ports [] = { + #ifdef LM3S69XX_ENABLE_UART_0 + { + .sDeviceName = "/dev/ttyS0", + .deviceType = SERIAL_CUSTOM, + .pDeviceFns = &lm3s69xx_uart_fns, + .ulCtrlPort1 = LM3S69XX_UART_0_BASE, + .ulClock = LM3S69XX_UART_BAUD, + .ulIntVector = LM3S69XX_IRQ_UART_0, + .pDeviceParams = (void *)0 + }, + #endif + #ifdef LM3S69XX_ENABLE_UART_1 + { + .sDeviceName = "/dev/ttyS1", + .deviceType = SERIAL_CUSTOM, + .pDeviceFns = &lm3s69xx_uart_fns, + .ulCtrlPort1 = LM3S69XX_UART_1_BASE, + .ulClock = LM3S69XX_UART_BAUD, + .ulIntVector = LM3S69XX_IRQ_UART_1, + .pDeviceParams = (void *)1 + }, + #endif + #ifdef LM3S69XX_ENABLE_UART_2 + { + .sDeviceName = "/dev/ttyS2", + .deviceType = SERIAL_CUSTOM, + .pDeviceFns = &lm3s69xx_uart_fns, + .ulCtrlPort1 = LM3S69XX_UART_2_BASE, + .ulClock = LM3S69XX_UART_BAUD, + .ulIntVector = LM3S69XX_IRQ_UART_2, + .pDeviceParams = (void *)2 + } + #endif +}; + +#define PORT_COUNT \ + (sizeof(Console_Configuration_Ports) \ + / sizeof(Console_Configuration_Ports [0])) + +unsigned long Console_Configuration_Count = PORT_COUNT; + +static void output_char(char c) +{ + const console_fns *con = + Console_Configuration_Ports [Console_Port_Minor].pDeviceFns; + + con->deviceWritePolled((int) Console_Port_Minor, c); +} + +BSP_output_char_function_type BSP_output_char = output_char; + +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/arm/lm3s69xx/console/uart.c b/bsps/arm/lm3s69xx/console/uart.c new file mode 100644 index 0000000000..67a85f4e96 --- /dev/null +++ b/bsps/arm/lm3s69xx/console/uart.c @@ -0,0 +1,167 @@ +/* + * Copyright © 2013 Eugeniy Meshcheryakov + * + * Copyright (c) 2011 Sebastian Huber. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define LM3S69XX_UART_FIFO_DEPTH 16 + +static volatile lm3s69xx_uart *get_uart_regs(int minor) +{ + console_tbl *ct = Console_Port_Tbl [minor]; + + return (lm3s69xx_uart *) ct->ulCtrlPort1; +} + +static unsigned int get_uart_number(int minor) +{ + console_tbl *ct = Console_Port_Tbl [minor]; + + return (unsigned int)ct->pDeviceParams; +} + +/* + * Returns both integer and fractional parts as one number. + */ +static uint32_t get_baud_div(uint32_t baud) +{ + uint32_t clock4 = LM3S69XX_SYSTEM_CLOCK * 4; + return (clock4 + baud - 1) / baud; +} + +static void irq_handler(void *arg) +{ + int minor = (int)arg; + console_data *cd = &Console_Port_Data [minor]; + volatile lm3s69xx_uart *uart = get_uart_regs(minor); + + do { + char buf[LM3S69XX_UART_FIFO_DEPTH]; + int i = 0; + uint32_t status = uart->fr; + + while (((status & UARTFR_RXFE) == 0) && (i < LM3S69XX_UART_FIFO_DEPTH)) { + uint32_t d = uart->dr; + + if ((d & UARTDR_ERROR_MSK) == 0) { + buf[i] = UARTDR_DATA_GET(d); + i++; + } + + status = uart->fr; + } + + if (i > 0) + rtems_termios_enqueue_raw_characters(cd->termios_data, buf, i); + } while (uart->mis != 0); +} + +static void initialize(int minor) +{ + const console_tbl *ct = Console_Port_Tbl[minor]; + volatile lm3s69xx_uart *uart = get_uart_regs(minor); + unsigned int num = get_uart_number(minor); + + lm3s69xx_syscon_enable_uart_clock(num, true); + + uart->ctl = 0; + + uint32_t brd = get_baud_div(LM3S69XX_UART_BAUD); + uart->ibrd = brd / 64; + uart->fbrd = brd % 64; + + uart->lcrh = UARTLCRH_WLEN(0x3) | UARTLCRH_FEN; + uart->ctl = UARTCTL_RXE | UARTCTL_TXE | UARTCTL_UARTEN; + + int rv = rtems_interrupt_handler_install(ct->ulIntVector, "UART", + RTEMS_INTERRUPT_UNIQUE, irq_handler, (void *)minor); + assert(rv == RTEMS_SUCCESSFUL); +} + +static int first_open(int major, int minor, void *arg) +{ + rtems_libio_open_close_args_t *oc = (rtems_libio_open_close_args_t *) arg; + struct rtems_termios_tty *tty = (struct rtems_termios_tty *) oc->iop->data1; + console_data *cd = &Console_Port_Data [minor]; + volatile lm3s69xx_uart *uart = get_uart_regs(minor); + + cd->termios_data = tty; + rtems_termios_set_initial_baud(tty, LM3S69XX_UART_BAUD); + + /* Drain the RX FIFO. */ + while ((uart->fr & UARTFR_RXFE) == 0) + (void)uart->dr; + + uart->im = UARTI_RX | UARTI_RT; + + return 0; +} + +static int last_close(int major, int minor, void *arg) +{ + volatile lm3s69xx_uart *uart = get_uart_regs(minor); + uart->im = 0; + + return 0; +} + +static void write_polled(int minor, char c) +{ + volatile lm3s69xx_uart *uart = get_uart_regs(minor); + + while ((uart->fr & UARTFR_TXFF) != 0) { + /* Wait */ + } + + uart->dr = UARTDR_DATA(c); +} + +static ssize_t write_support_polled( + int minor, + const char *s, + size_t n +) +{ + ssize_t i = 0; + + for (i = 0; i < n; ++i) { + write_polled(minor, s [i]); + } + + return n; +} + +static int set_attribues(int minor, const struct termios *term) +{ + return -1; +} + +const console_fns lm3s69xx_uart_fns = { + .deviceProbe = libchip_serial_default_probe, + .deviceFirstOpen = first_open, + .deviceLastClose = last_close, + .deviceRead = NULL, + .deviceWrite = write_support_polled, + .deviceInitialize = initialize, + .deviceWritePolled = write_polled, + .deviceSetAttributes = set_attribues, + .deviceOutputUsesInterrupts = false +}; diff --git a/bsps/arm/lpc176x/console/console-config.c b/bsps/arm/lpc176x/console/console-config.c new file mode 100644 index 0000000000..c80932daf7 --- /dev/null +++ b/bsps/arm/lpc176x/console/console-config.c @@ -0,0 +1,192 @@ +/** + * @file + * + * @ingroup lpc176x + * + * @brief Console configuration. + */ + +/* + * Copyright (c) 2008-2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include +#include +#include +#include + +/** + * @brief Gets the uart register according to the current address. + * + * @param addr Register address. + * @param i Index register. + * @return Uart register. + */ +static inline uint8_t lpc176x_uart_get_register( + const uintptr_t addr, + const uint8_t i +) +{ + volatile uint32_t *reg = (volatile uint32_t *) addr; + + return (uint8_t) reg[ i ]; +} + +/** + * @brief Sets the uart register address according to the value passed. + * + * @param addr Register address. + * @param i Index register. + * @param val Value to set. + */ +static inline void lpc176x_uart_set_register( + const uintptr_t addr, + const uint8_t i, + const uint8_t val +) +{ + volatile uint32_t *reg = (volatile uint32_t *) addr; + + reg[ i ] = val; +} + +static bool lpc176x_uart1_probe(rtems_termios_device_context *ctx) +{ + (void)ctx; + + lpc176x_module_enable( LPC176X_MODULE_UART_1, LPC176X_MODULE_PCLK_DEFAULT ); + + lpc176x_pin_select( LPC176X_PIN_UART_1_TXD, LPC176X_PIN_FUNCTION_01 ); + lpc176x_pin_select( LPC176X_PIN_UART_1_RXD, LPC176X_PIN_FUNCTION_01 ); + + return true; +} + +#ifdef LPC176X_CONFIG_UART_2 +static bool lpc176x_uart2_probe(rtems_termios_device_context *ctx) +{ + (void)ctx; + + lpc176x_module_enable( LPC176X_MODULE_UART_2, LPC176X_MODULE_PCLK_DEFAULT ); + + lpc176x_pin_select( LPC176X_PIN_UART_2_TXD, LPC176X_PIN_FUNCTION_01 ); + lpc176x_pin_select( LPC176X_PIN_UART_2_RXD, LPC176X_PIN_FUNCTION_01 ); + + return true; +} +#endif + +#ifdef LPC176X_CONFIG_UART_3 +static bool lpc176x_uart3_probe(rtems_termios_device_context *ctx) +{ + (void)ctx; + + lpc176x_module_enable( LPC176X_MODULE_UART_3, LPC176X_MODULE_PCLK_DEFAULT ); + + lpc176x_pin_select( LPC176X_PIN_UART_3_TXD, LPC176X_PIN_FUNCTION_10 ); + lpc176x_pin_select( LPC176X_PIN_UART_3_RXD, LPC176X_PIN_FUNCTION_10 ); + + return true; +} +#endif + +#ifdef LPC176X_CONFIG_CONSOLE +static ns16550_context lpc176x_uart_context_0 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"), + .get_reg = lpc176x_uart_get_register, + .set_reg = lpc176x_uart_set_register, + .port = UART0_BASE_ADDR, + .irq = LPC176X_IRQ_UART_0, + .clock = LPC176X_PCLK, + .initial_baud = LPC176X_UART_BAUD, + .has_fractional_divider_register = true +}; +#endif + +#ifdef LPC176X_CONFIG_UART_1 +static ns16550_context lpc176x_uart_context_1 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"), + .get_reg = lpc176x_uart_get_register, + .set_reg = lpc176x_uart_set_register, + .port = UART1_BASE_ADDR, + .irq = LPC176X_IRQ_UART_1, + .clock = LPC176X_PCLK, + .initial_baud = LPC176X_UART_BAUD, + .has_fractional_divider_register = true +}; +#endif + +#ifdef LPC176X_CONFIG_UART_2 +static ns16550_context lpc176x_uart_context_2 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 2"), + .get_reg = lpc176x_uart_get_register, + .set_reg = lpc176x_uart_set_register, + .port = UART2_BASE_ADDR, + .irq = LPC176X_IRQ_UART_2, + .clock = LPC176X_PCLK, + .initial_baud = LPC176X_UART_BAUD, + .has_fractional_divider_register = true +}; +#endif + +#ifdef LPC176X_CONFIG_UART_3 +static ns16550_context lpc176x_uart_context_3 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 3"), + .get_reg = lpc176x_uart_get_register, + .set_reg = lpc176x_uart_set_register, + .port = UART3_BASE_ADDR, + .irq = LPC176X_IRQ_UART_3, + .clock = LPC176X_PCLK, + .initial_baud = LPC176X_UART_BAUD, + .has_fractional_divider_register = true +}; +#endif + +const console_device console_device_table[] = { + #ifdef LPC176X_CONFIG_CONSOLE + { + .device_file = "/dev/ttyS0", + .probe = console_device_probe_default, + .handler = &ns16550_handler_interrupt, + .context = &lpc176x_uart_context_0.base + }, + #endif + #ifdef LPC176X_CONFIG_UART_1 + { + .device_file = "/dev/ttyS1", + .probe = lpc176x_uart1_probe, + .handler = &ns16550_handler_interrupt, + .context = &lpc176x_uart_context_1.base + }, + #endif + #ifdef LPC176X_CONFIG_UART_2 + { + .device_file = "/dev/ttyS2", + .probe = lpc176x_uart2_probe, + .handler = &ns16550_handler_interrupt, + .context = &lpc176x_uart_context_2.base + }, + #endif + #ifdef LPC176X_CONFIG_UART_3 + { + .device_file = "/dev/ttyS3", + .probe = lpc176x_uart3_probe, + .handler = &ns16550_handler_interrupt, + .context = &lpc176x_uart_context_3.base + }, + #endif +}; + +const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table); diff --git a/bsps/arm/lpc24xx/console/console-config.c b/bsps/arm/lpc24xx/console/console-config.c new file mode 100644 index 0000000000..de94552c27 --- /dev/null +++ b/bsps/arm/lpc24xx/console/console-config.c @@ -0,0 +1,134 @@ +/** + * @file + * + * @ingroup lpc24xx + * + * @brief Console configuration. + */ + +/* + * Copyright (c) 2008-2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include + +#include +#include +#include +#include +#include + +static uint8_t lpc24xx_uart_get_register(uintptr_t addr, uint8_t i) +{ + volatile uint32_t *reg = (volatile uint32_t *) addr; + + return (uint8_t) reg [i]; +} + +static void lpc24xx_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val) +{ + volatile uint32_t *reg = (volatile uint32_t *) addr; + + reg [i] = val; +} + +#ifdef LPC24XX_CONFIG_CONSOLE +static ns16550_context lpc24xx_uart_context_0 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"), + .get_reg = lpc24xx_uart_get_register, + .set_reg = lpc24xx_uart_set_register, + .port = UART0_BASE_ADDR, + .irq = LPC24XX_IRQ_UART_0, + .clock = LPC24XX_PCLK, + .initial_baud = LPC24XX_UART_BAUD, + .has_fractional_divider_register = true +}; +#endif + +#ifdef LPC24XX_CONFIG_UART_1 +static ns16550_context lpc24xx_uart_context_1 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"), + .get_reg = lpc24xx_uart_get_register, + .set_reg = lpc24xx_uart_set_register, + .port = UART1_BASE_ADDR, + .irq = LPC24XX_IRQ_UART_1, + .clock = LPC24XX_PCLK, + .initial_baud = LPC24XX_UART_BAUD, + .has_fractional_divider_register = true +}; +#endif + +#ifdef LPC24XX_CONFIG_UART_2 +static ns16550_context lpc24xx_uart_context_2 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 2"), + .get_reg = lpc24xx_uart_get_register, + .set_reg = lpc24xx_uart_set_register, + .port = UART2_BASE_ADDR, + .irq = LPC24XX_IRQ_UART_2, + .clock = LPC24XX_PCLK, + .initial_baud = LPC24XX_UART_BAUD, + .has_fractional_divider_register = true +}; +#endif + +#ifdef LPC24XX_CONFIG_UART_3 +static ns16550_context lpc24xx_uart_context_3 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 3"), + .get_reg = lpc24xx_uart_get_register, + .set_reg = lpc24xx_uart_set_register, + .port = UART3_BASE_ADDR, + .irq = LPC24XX_IRQ_UART_3, + .clock = LPC24XX_PCLK, + .initial_baud = LPC24XX_UART_BAUD, + .has_fractional_divider_register = true +}; +#endif + +const console_device console_device_table[] = { + #ifdef LPC24XX_CONFIG_CONSOLE + { + .device_file = "/dev/ttyS0", + .probe = console_device_probe_default, + .handler = &ns16550_handler_interrupt, + .context = &lpc24xx_uart_context_0.base + }, + #endif + #ifdef LPC24XX_CONFIG_UART_1 + { + .device_file = "/dev/ttyS1", + .probe = lpc24xx_uart_probe_1, + .handler = &ns16550_handler_interrupt, + .context = &lpc24xx_uart_context_1.base + }, + #endif + #ifdef LPC24XX_CONFIG_UART_2 + { + .device_file = "/dev/ttyS2", + .probe = lpc24xx_uart_probe_2, + .handler = &ns16550_handler_interrupt, + .context = &lpc24xx_uart_context_2.base + }, + #endif + #ifdef LPC24XX_CONFIG_UART_3 + { + .device_file = "/dev/ttyS3", + .probe = lpc24xx_uart_probe_3, + .handler = &ns16550_handler_interrupt, + .context = &lpc24xx_uart_context_3.base + }, + #endif +}; + +const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table); diff --git a/bsps/arm/lpc24xx/console/uart-probe-1.c b/bsps/arm/lpc24xx/console/uart-probe-1.c new file mode 100644 index 0000000000..3b5f08059f --- /dev/null +++ b/bsps/arm/lpc24xx/console/uart-probe-1.c @@ -0,0 +1,40 @@ +/** + * @file + * + * @ingroup lpc24xx + * + * @brief UART 1 probe. + */ + +/* + * Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include +#include + +bool lpc24xx_uart_probe_1(rtems_termios_device_context *context) +{ + static const lpc24xx_pin_range pins [] = { + LPC24XX_PIN_UART_1_TXD_P0_15, + LPC24XX_PIN_UART_1_RXD_P0_16, + LPC24XX_PIN_TERMINAL + }; + + lpc24xx_module_enable(LPC24XX_MODULE_UART_1, LPC24XX_MODULE_PCLK_DEFAULT); + lpc24xx_pin_config(&pins [0], LPC24XX_PIN_SET_FUNCTION); + + return ns16550_probe(context); +} diff --git a/bsps/arm/lpc24xx/console/uart-probe-2.c b/bsps/arm/lpc24xx/console/uart-probe-2.c new file mode 100644 index 0000000000..d45dbb755b --- /dev/null +++ b/bsps/arm/lpc24xx/console/uart-probe-2.c @@ -0,0 +1,40 @@ +/** + * @file + * + * @ingroup lpc24xx + * + * @brief UART 2 probe. + */ + +/* + * Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include +#include + +bool lpc24xx_uart_probe_2(rtems_termios_device_context *context) +{ + static const lpc24xx_pin_range pins [] = { + LPC24XX_PIN_UART_2_TXD_P0_10, + LPC24XX_PIN_UART_2_RXD_P0_11, + LPC24XX_PIN_TERMINAL + }; + + lpc24xx_module_enable(LPC24XX_MODULE_UART_2, LPC24XX_MODULE_PCLK_DEFAULT); + lpc24xx_pin_config(&pins [0], LPC24XX_PIN_SET_FUNCTION); + + return ns16550_probe(context); +} diff --git a/bsps/arm/lpc24xx/console/uart-probe-3.c b/bsps/arm/lpc24xx/console/uart-probe-3.c new file mode 100644 index 0000000000..fad932ef9e --- /dev/null +++ b/bsps/arm/lpc24xx/console/uart-probe-3.c @@ -0,0 +1,40 @@ +/** + * @file + * + * @ingroup lpc24xx + * + * @brief UART 3 probe. + */ + +/* + * Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include +#include + +bool lpc24xx_uart_probe_3(rtems_termios_device_context *context) +{ + static const lpc24xx_pin_range pins [] = { + LPC24XX_PIN_UART_3_TXD_P0_0, + LPC24XX_PIN_UART_3_RXD_P0_1, + LPC24XX_PIN_TERMINAL + }; + + lpc24xx_module_enable(LPC24XX_MODULE_UART_3, LPC24XX_MODULE_PCLK_DEFAULT); + lpc24xx_pin_config(&pins [0], LPC24XX_PIN_SET_FUNCTION); + + return ns16550_probe(context); +} diff --git a/bsps/arm/lpc32xx/console/console-config.c b/bsps/arm/lpc32xx/console/console-config.c new file mode 100644 index 0000000000..17e6b0af8f --- /dev/null +++ b/bsps/arm/lpc32xx/console/console-config.c @@ -0,0 +1,225 @@ +/** + * @file + * + * @ingroup arm_lpc32xx + * + * @brief Console configuration. + */ + +/* + * Copyright (c) 2009-2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include +#include +#include +#include +#include + +static uint8_t lpc32xx_uart_get_register(uintptr_t addr, uint8_t i) +{ + volatile uint32_t *reg = (volatile uint32_t *) addr; + + return (uint8_t) reg [i]; +} + +static void lpc32xx_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val) +{ + volatile uint32_t *reg = (volatile uint32_t *) addr; + + reg [i] = val; +} + +#ifdef LPC32XX_UART_3_BAUD + static bool lpc32xx_uart_probe_3(rtems_termios_device_context *context) + { + LPC32XX_UARTCLK_CTRL |= BSP_BIT32(0); + LPC32XX_U3CLK = LPC32XX_CONFIG_U3CLK; + LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 4, 5); + + return ns16550_probe(context); + } +#endif + +#ifdef LPC32XX_UART_4_BAUD + static bool lpc32xx_uart_probe_4(rtems_termios_device_context *context) + { + volatile lpc32xx_gpio *gpio = &lpc32xx.gpio; + + /* + * Set GPO_21/U4_TX/LCDVD[3] to U4_TX. This works only if LCD module is + * disabled. + */ + gpio->p2_mux_set = BSP_BIT32(2); + + LPC32XX_UARTCLK_CTRL |= BSP_BIT32(1); + LPC32XX_U4CLK = LPC32XX_CONFIG_U4CLK; + LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 6, 7); + + return ns16550_probe(context); + } +#endif + +#ifdef LPC32XX_UART_6_BAUD + static bool lpc32xx_uart_probe_6(rtems_termios_device_context *context) + { + /* Bypass the IrDA modulator/demodulator */ + LPC32XX_UART_CTRL |= BSP_BIT32(5); + + LPC32XX_UARTCLK_CTRL |= BSP_BIT32(3); + LPC32XX_U6CLK = LPC32XX_CONFIG_U6CLK; + LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 10, 11); + + return ns16550_probe(context); + } +#endif + +/* FIXME: Console selection */ + +#ifdef LPC32XX_UART_5_BAUD +static ns16550_context lpc32xx_uart_context_5 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 5"), + .get_reg = lpc32xx_uart_get_register, + .set_reg = lpc32xx_uart_set_register, + .port = LPC32XX_BASE_UART_5, + .irq = LPC32XX_IRQ_UART_5, + .clock = 16 * LPC32XX_UART_5_BAUD, + .initial_baud = LPC32XX_UART_5_BAUD +}; +#endif + +#ifdef LPC32XX_UART_3_BAUD +static ns16550_context lpc32xx_uart_context_3 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 3"), + .get_reg = lpc32xx_uart_get_register, + .set_reg = lpc32xx_uart_set_register, + .port = LPC32XX_BASE_UART_3, + .irq = LPC32XX_IRQ_UART_3, + .clock = 16 * LPC32XX_UART_3_BAUD, + .initial_baud = LPC32XX_UART_3_BAUD +}; +#endif + +#ifdef LPC32XX_UART_4_BAUD +static ns16550_context lpc32xx_uart_context_4 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 4"), + .get_reg = lpc32xx_uart_get_register, + .set_reg = lpc32xx_uart_set_register, + .port = LPC32XX_BASE_UART_4, + .irq = LPC32XX_IRQ_UART_4, + .clock = 16 * LPC32XX_UART_4_BAUD, + .initial_baud = LPC32XX_UART_4_BAUD +}; +#endif + +#ifdef LPC32XX_UART_6_BAUD +static ns16550_context lpc32xx_uart_context_6 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 6"), + .get_reg = lpc32xx_uart_get_register, + .set_reg = lpc32xx_uart_set_register, + .port = LPC32XX_BASE_UART_6, + .irq = LPC32XX_IRQ_UART_6, + .clock = 16 * LPC32XX_UART_6_BAUD, + .initial_baud = LPC32XX_UART_6_BAUD +}; +#endif + +#ifdef LPC32XX_UART_1_BAUD +static lpc32xx_hsu_context lpc32xx_uart_context_1 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"), + .hsu = (volatile lpc32xx_hsu *) LPC32XX_BASE_UART_1, + .irq = LPC32XX_IRQ_UART_1, + .initial_baud = LPC32XX_UART_1_BAUD +}; +#endif + +#ifdef LPC32XX_UART_2_BAUD +static lpc32xx_hsu_context lpc32xx_uart_context_2 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 2"), + .hsu = (volatile lpc32xx_hsu *) LPC32XX_BASE_UART_2, + .irq = LPC32XX_IRQ_UART_2, + .initial_baud = LPC32XX_UART_2_BAUD +}; +#endif + +#ifdef LPC32XX_UART_7_BAUD +static lpc32xx_hsu_context lpc32xx_uart_context_7 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 7"), + .hsu = (volatile lpc32xx_hsu *) LPC32XX_BASE_UART_7, + .irq = LPC32XX_IRQ_UART_7, + .initial_baud = LPC32XX_UART_7_BAUD +}; +#endif + +const console_device console_device_table[] = { + #ifdef LPC32XX_UART_5_BAUD + { + .device_file = "/dev/ttyS5", + .probe = console_device_probe_default, + .handler = &ns16550_handler_interrupt, + .context = &lpc32xx_uart_context_5.base + }, + #endif + #ifdef LPC32XX_UART_3_BAUD + { + .device_file = "/dev/ttyS3", + .probe = lpc32xx_uart_probe_3, + .handler = &ns16550_handler_interrupt, + .context = &lpc32xx_uart_context_3.base + }, + #endif + #ifdef LPC32XX_UART_4_BAUD + { + .device_file = "/dev/ttyS4", + .probe = lpc32xx_uart_probe_4, + .handler = &ns16550_handler_interrupt, + .context = &lpc32xx_uart_context_4.base + }, + #endif + #ifdef LPC32XX_UART_6_BAUD + { + .device_file = "/dev/ttyS6", + .probe = lpc32xx_uart_probe_6, + .handler = &ns16550_handler_interrupt, + .context = &lpc32xx_uart_context_6.base + }, + #endif + #ifdef LPC32XX_UART_1_BAUD + { + .device_file = "/dev/ttyS1", + .probe = lpc32xx_hsu_probe, + .handler = &lpc32xx_hsu_fns, + .context = &lpc32xx_uart_context_1.base + }, + #endif + #ifdef LPC32XX_UART_2_BAUD + { + .device_file = "/dev/ttyS2", + .probe = lpc32xx_hsu_probe, + .handler = &lpc32xx_hsu_fns, + .context = &lpc32xx_uart_context_2.base + }, + #endif + #ifdef LPC32XX_UART_7_BAUD + { + .device_file = "/dev/ttyS7", + .probe = lpc32xx_hsu_probe, + .handler = &lpc32xx_hsu_fns, + .context = &lpc32xx_uart_context_7.base + }, + #endif +}; + +const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table); diff --git a/bsps/arm/lpc32xx/console/hsu.c b/bsps/arm/lpc32xx/console/hsu.c new file mode 100644 index 0000000000..b2044e0753 --- /dev/null +++ b/bsps/arm/lpc32xx/console/hsu.c @@ -0,0 +1,208 @@ +/** + * @file + * + * @ingroup arm_lpc32xx + * + * @brief High speed UART driver (14-clock). + */ + +/* + * Copyright (c) 2010-2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include + +#define HSU_FIFO_SIZE 64 + +#define HSU_LEVEL_RX_MASK 0xffU +#define HSU_LEVEL_TX_MASK 0xff00U +#define HSU_LEVEL_TX_SHIFT 8 + +#define HSU_RX_DATA_MASK 0xffU +#define HSU_RX_EMPTY (1U << 8) +#define HSU_RX_ERROR (1U << 9) +#define HSU_RX_BREAK (1U << 10) + +#define HSU_IIR_TX (1U << 0) +#define HSU_IIR_RX_TRIG (1U << 1) +#define HSU_IIR_RX_TIMEOUT (1U << 2) + +#define HSU_CTRL_INTR_DISABLED 0x1280fU +#define HSU_CTRL_RX_INTR_ENABLED 0x1284fU +#define HSU_CTRL_RX_AND_TX_INTR_ENABLED 0x1286fU + +/* We are interested in RX timeout, RX trigger and TX trigger interrupts */ +#define HSU_IIR_MASK 0x7U + +bool lpc32xx_hsu_probe(rtems_termios_device_context *base) +{ + lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base; + volatile lpc32xx_hsu *hsu = ctx->hsu; + + hsu->ctrl = HSU_CTRL_INTR_DISABLED; + + /* Drain FIFOs */ + while (hsu->level != 0) { + hsu->fifo; + } + + return true; +} + +static void lpc32xx_hsu_interrupt_handler(void *arg) +{ + rtems_termios_tty *tty = arg; + lpc32xx_hsu_context *ctx = rtems_termios_get_device_context(tty); + volatile lpc32xx_hsu *hsu = ctx->hsu; + + /* Iterate until no more interrupts are pending */ + do { + int rv = 0; + int i = 0; + char buf [HSU_FIFO_SIZE]; + + /* Enqueue received characters */ + while (i < HSU_FIFO_SIZE) { + uint32_t in = hsu->fifo; + + if ((in & HSU_RX_EMPTY) == 0) { + if ((in & HSU_RX_BREAK) == 0) { + buf [i] = in & HSU_RX_DATA_MASK; + ++i; + } + } else { + break; + } + } + rtems_termios_enqueue_raw_characters(tty, buf, i); + + /* Dequeue transmitted characters */ + rv = rtems_termios_dequeue_characters(tty, (int) ctx->chars_in_transmission); + if (rv == 0) { + /* Nothing to transmit */ + } + } while ((hsu->iir & HSU_IIR_MASK) != 0); +} + +static bool lpc32xx_hsu_first_open( + struct rtems_termios_tty *tty, + rtems_termios_device_context *base, + struct termios *term, + rtems_libio_open_close_args_t *args +) +{ + lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base; + volatile lpc32xx_hsu *hsu = ctx->hsu; + rtems_status_code sc; + bool ok; + + sc = rtems_interrupt_handler_install( + ctx->irq, + "HSU", + RTEMS_INTERRUPT_UNIQUE, + lpc32xx_hsu_interrupt_handler, + tty + ); + ok = sc == RTEMS_SUCCESSFUL; + + if (ok) { + rtems_termios_set_initial_baud(tty, ctx->initial_baud); + hsu->ctrl = HSU_CTRL_RX_INTR_ENABLED; + } + + return ok; +} + +static void lpc32xx_hsu_last_close( + struct rtems_termios_tty *tty, + rtems_termios_device_context *base, + rtems_libio_open_close_args_t *args +) +{ + lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base; + volatile lpc32xx_hsu *hsu = ctx->hsu; + + hsu->ctrl = HSU_CTRL_INTR_DISABLED; + + rtems_interrupt_handler_remove( + ctx->irq, + lpc32xx_hsu_interrupt_handler, + tty + ); +} + +static void lpc32xx_hsu_write( + rtems_termios_device_context *base, + const char *buf, + size_t len +) +{ + lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base; + volatile lpc32xx_hsu *hsu = ctx->hsu; + size_t tx_level = (hsu->level & HSU_LEVEL_TX_MASK) >> HSU_LEVEL_TX_SHIFT; + size_t tx_free = HSU_FIFO_SIZE - tx_level; + size_t i = 0; + size_t out = len > tx_free ? tx_free : len; + + for (i = 0; i < out; ++i) { + hsu->fifo = buf [i]; + } + + ctx->chars_in_transmission = out; + + if (len > 0) { + hsu->ctrl = HSU_CTRL_RX_AND_TX_INTR_ENABLED; + } else { + hsu->ctrl = HSU_CTRL_RX_INTR_ENABLED; + hsu->iir = HSU_IIR_TX; + } +} + +static bool lpc32xx_hsu_set_attributes( + rtems_termios_device_context *base, + const struct termios *term +) +{ + lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base; + volatile lpc32xx_hsu *hsu = ctx->hsu; + int baud_flags = term->c_ospeed; + + if (baud_flags != 0) { + int32_t baud = rtems_termios_baud_to_number(baud_flags); + + if (baud > 0) { + uint32_t baud_divisor = 14 * (uint32_t) baud; + uint32_t rate = LPC32XX_PERIPH_CLK / baud_divisor; + uint32_t remainder = LPC32XX_PERIPH_CLK - rate * baud_divisor; + + if (2 * remainder >= baud_divisor) { + ++rate; + } + + hsu->rate = rate - 1; + } + } + + return true; +} + +const rtems_termios_device_handler lpc32xx_hsu_fns = { + .first_open = lpc32xx_hsu_first_open, + .last_close = lpc32xx_hsu_last_close, + .write = lpc32xx_hsu_write, + .set_attributes = lpc32xx_hsu_set_attributes, + .mode = TERMIOS_IRQ_DRIVEN +}; diff --git a/bsps/arm/raspberrypi/console/console-config.c b/bsps/arm/raspberrypi/console/console-config.c new file mode 100644 index 0000000000..d2186c918b --- /dev/null +++ b/bsps/arm/raspberrypi/console/console-config.c @@ -0,0 +1,68 @@ +/** + * @file + * + * @ingroup raspberrypi_usart + * + * @brief Console Configuration. + */ + +/* + * Copyright (c) 2015 Yang Qiao + * based on work by: + * Copyright (c) 2013 Alan Cudmore + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.org/license/LICENSE + * + */ + +#include + +#include + +#include +#include +#include +#include +#include + +console_tbl Console_Configuration_Ports [] = { + { + .sDeviceName = "/dev/ttyS0", + .deviceType = SERIAL_CUSTOM, + .pDeviceFns = &bcm2835_usart_fns, + .deviceProbe = NULL, + .pDeviceFlow = NULL, + .ulCtrlPort1 = BCM2835_UART0_BASE, + .ulCtrlPort2 = 0, + .ulClock = USART0_DEFAULT_BAUD, + .ulIntVector = BCM2835_IRQ_ID_UART + }, + { + .sDeviceName ="/dev/fbcons", + .deviceType = SERIAL_CUSTOM, + .pDeviceFns = &fbcons_fns, + .deviceProbe = fbcons_probe, + .pDeviceFlow = NULL, + }, +}; + +#define PORT_COUNT \ + (sizeof(Console_Configuration_Ports) \ + / sizeof(Console_Configuration_Ports [0])) + +unsigned long Console_Configuration_Count = PORT_COUNT; + +static void output_char(char c) +{ + const console_fns *con = + Console_Configuration_Ports [Console_Port_Minor].pDeviceFns; + + con->deviceWritePolled((int) Console_Port_Minor, c); +} + +BSP_output_char_function_type BSP_output_char = output_char; + +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/arm/raspberrypi/console/console_select.c b/bsps/arm/raspberrypi/console/console_select.c new file mode 100644 index 0000000000..bd246ca868 --- /dev/null +++ b/bsps/arm/raspberrypi/console/console_select.c @@ -0,0 +1,114 @@ +/** + * @file + * + * @ingroup raspberrypi_console + * + * @brief console select + */ + +/* + * Copyright (c) 2015 Yang Qiao + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.org/license/LICENSE + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "../../shared/dev/serial/legacy-console.h" +#include + +rtems_device_minor_number BSPPrintkPort = 0; + +/* + * Method to return true if the device associated with the + * minor number probs available. + */ +static bool bsp_Is_Available( rtems_device_minor_number minor ) +{ + console_tbl *cptr = Console_Port_Tbl[ minor ]; + + /* + * First perform the configuration dependent probe, then the + * device dependent probe + */ + if ( ( !cptr->deviceProbe || cptr->deviceProbe( minor ) ) && + cptr->pDeviceFns->deviceProbe( minor ) ) { + return true; + } + + return false; +} + +/* + * Method to return the first available device. + */ +static rtems_device_minor_number bsp_First_Available_Device( void ) +{ + rtems_device_minor_number minor; + + for ( minor = 0; minor < Console_Port_Count; minor++ ) { + console_tbl *cptr = Console_Port_Tbl[ minor ]; + + /* + * First perform the configuration dependent probe, then the + * device dependent probe + */ + + if ( ( !cptr->deviceProbe || cptr->deviceProbe( minor ) ) && + cptr->pDeviceFns->deviceProbe( minor ) ) { + return minor; + } + } + + /* + * Error No devices were found. We will want to bail here. + */ + bsp_fatal( BSP_FATAL_CONSOLE_NO_DEV ); +} + +void bsp_console_select( void ) +{ + /* + * Reset Console_Port_Minor and + * BSPPrintkPort here if desired. + * + * This default version allows the bsp to set these + * values at creation and will not touch them again + * unless the selected port number is not available. + */ + const char *opt; + + Console_Port_Minor = BSP_CONSOLE_UART0; + BSPPrintkPort = BSP_CONSOLE_UART0; + + opt = rpi_cmdline_get_arg( "--console=" ); + + if ( opt ) { + if ( strncmp( opt, "fbcons", sizeof( "fbcons" ) - 1 ) == 0 ) { + if ( rpi_video_is_initialized() > 0 ) { + Console_Port_Minor = BSP_CONSOLE_FB; + BSPPrintkPort = BSP_CONSOLE_FB; + } + } + } + + /* + * If the device that was selected isn't available then + * let the user know and select the first available device. + */ + if ( !bsp_Is_Available( Console_Port_Minor ) ) { + Console_Port_Minor = bsp_First_Available_Device(); + } +} diff --git a/bsps/arm/raspberrypi/console/fb.c b/bsps/arm/raspberrypi/console/fb.c new file mode 100644 index 0000000000..815d17e8ca --- /dev/null +++ b/bsps/arm/raspberrypi/console/fb.c @@ -0,0 +1,437 @@ +/** + * @file + * + * @ingroup raspberrypi + * + * @brief framebuffer support. + */ + +/* + * Copyright (c) 2015 Yang Qiao + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.org/license/LICENSE + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#define SCREEN_WIDTH 1024 +#define SCREEN_HEIGHT 768 +#define BPP 32 + +/* flag to limit driver to protect against multiple opens */ +static Atomic_Flag driver_mutex; + +/* + * screen information for the driver (fb0). + */ + +static struct fb_var_screeninfo fb_var_info = { + .xres = SCREEN_WIDTH, + .yres = SCREEN_HEIGHT, + .bits_per_pixel = BPP +}; + +static struct fb_fix_screeninfo fb_fix_info = { + .smem_start = (void *) NULL, + .smem_len = 0, + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .line_length = 0 +}; + +typedef enum { + NO_SUITABLE_MODE = -1, + BAD_FORMAT = -2, + AUTO_SELECT = -3, + DONT_INIT = -4, + NO_MODE_REQ = -5, +} mode_err_ret_val; + +int rpi_get_fix_screen_info( struct fb_fix_screeninfo *info ) +{ + *info = fb_fix_info; + return 0; +} + +int rpi_get_var_screen_info( struct fb_var_screeninfo *info ) +{ + *info = fb_var_info; + return 0; +} + +/** + * @brief Find mode given in string format. + * + * expected format + * x[-] + * numbers , and are decadic + * + * @param[out] fb_var_ptr pointer to variable mode part filled by function + * @param[in] video_string string to be parsed + * @retval video mode number to be set + * @retval -1 no suitable mode found + * @retval -2 bad format of the video_string + * @retval -3 automatic mode selection requested + * @retval -4 request to not initialize graphics + * @retval -5 no mode requested/empty video string + */ + +static int parse_mode_from_string( + struct fb_var_screeninfo *fb_var_ptr, + const char *video_string +) +{ + const char *opt; + char *endptr; + uint32_t width; + uint32_t height; + uint32_t bpp = 0; + + opt = video_string; + + if ( opt == NULL ) + return NO_MODE_REQ; + + if ( strncmp( opt, "auto", 4 ) == 0 ) + return AUTO_SELECT; + + if ( strncmp( opt, "none", 4 ) == 0 || + strncmp( opt, "off", 3 ) == 0 ) + return DONT_INIT; + + width = strtol( opt, &endptr, 10 ); + + if ( *endptr != 'x' ) { + return BAD_FORMAT; + } + + opt = endptr + 1; + height = strtol( opt, &endptr, 10 ); + + switch ( *endptr ) { + case '-': + opt = endptr + 1; + endptr = NULL; + bpp = strtol( opt, &endptr, 10 ); + + if ( ( endptr == opt ) || ( endptr == NULL ) ) + return BAD_FORMAT; + + if ( *endptr && ( *endptr != ' ' ) ) + return BAD_FORMAT; + + break; + case ' ': + case 0: + break; + default: + return BAD_FORMAT; + } + + fb_var_ptr->xres = width; + fb_var_ptr->yres = height; + + if ( bpp != 0 ) + fb_var_ptr->bits_per_pixel = bpp; + + return 0; +} + +static int find_mode_from_vc( void ) +{ + int res; + unsigned int width; + unsigned int height; + bcm2835_get_display_size_entries entries; + + res = bcm2835_mailbox_get_display_size( &entries ); + + width = entries.width; + height = entries.height; + + if ( width == 0 || height == 0 ) { + fb_var_info.xres = SCREEN_WIDTH; + fb_var_info.yres = SCREEN_HEIGHT; + } else { + fb_var_info.xres = width; + fb_var_info.yres = height; + } + printk("find_mode_from_vc %u x %u, res %d\n", width, height, res); + + return res; +} + +bool rpi_fb_hdmi_is_present( void ) +{ + bcm2835_get_display_size_entries entries; + + memset( &entries, 0, sizeof( entries ) ); + bcm2835_mailbox_get_display_size( &entries ); + + /* Impossible display dimension */ + if ( ( entries.width < 10 ) || ( entries.height < 10 ) ) + return false; + + /* Know default values reported when monitor is not present */ + if ( ( entries.width == 0x290 ) && ( entries.height == 0x1A0 ) ) + return false; + + return true; +} + +int rpi_fb_init( void ) +{ + int res; + int mode_from_cmdline; + bcm2835_init_frame_buffer_entries init_frame_buffer_entries; + + if ( fb_fix_info.smem_start != NULL ) { + return RPI_FB_INIT_ALREADY_INITIALIZED; + } + + if ( rpi_fb_hdmi_is_present() == false ) { + return RPI_FB_INIT_NO_DISPLAY; + } + + mode_from_cmdline = parse_mode_from_string( &fb_var_info, + rpi_cmdline_get_arg( "--video=" ) ); + + switch ( mode_from_cmdline ) { + case BAD_FORMAT: + return RPI_FB_INIT_CMDLINE_BAD_FORMAT; + case AUTO_SELECT: + break; + case DONT_INIT: + return RPI_FB_INIT_CMDLINE_DONT_INIT; + case NO_MODE_REQ: + return RPI_FB_INIT_CMDLINE_NO_MODE_REQ; + } + + if ( mode_from_cmdline ) { + if ( find_mode_from_vc() ) + return RPI_FB_INIT_MODE_PROBE_ERROR; + } + + memset( &init_frame_buffer_entries, 0, sizeof( init_frame_buffer_entries ) ); + init_frame_buffer_entries.xres = fb_var_info.xres; + init_frame_buffer_entries.yres = fb_var_info.yres; + init_frame_buffer_entries.xvirt = fb_var_info.xres; + init_frame_buffer_entries.yvirt = fb_var_info.yres; + init_frame_buffer_entries.depth = fb_var_info.bits_per_pixel; + init_frame_buffer_entries.pixel_order = bcm2835_mailbox_pixel_order_rgb; + init_frame_buffer_entries.alpha_mode = bcm2835_mailbox_alpha_mode_0_opaque; + init_frame_buffer_entries.voffset_x = 0; + init_frame_buffer_entries.voffset_y = 0; + init_frame_buffer_entries.overscan_left = 0; + init_frame_buffer_entries.overscan_right = 0; + init_frame_buffer_entries.overscan_top = 0; + init_frame_buffer_entries.overscan_bottom = 0; + printk("bcm2835_mailbox_init_frame_buffer ...\n"); + res = bcm2835_mailbox_init_frame_buffer( &init_frame_buffer_entries ); + printk("bcm2835_mailbox_init_frame_buffer returned %d\n", res); + if (res != 0) { + printk("bcm2835_mailbox_init_frame_buffer retry ...\n"); + res = bcm2835_mailbox_init_frame_buffer( &init_frame_buffer_entries ); + printk("bcm2835_mailbox_init_frame_buffer returned %d\n", res); + if (res != 0) + return RPI_FB_INIT_SETUP_FAILED; + } + + bcm2835_get_pitch_entries get_pitch_entries; + bcm2835_mailbox_get_pitch( &get_pitch_entries ); + + fb_var_info.xres = init_frame_buffer_entries.xres; + fb_var_info.yres = init_frame_buffer_entries.yres; + fb_var_info.bits_per_pixel = init_frame_buffer_entries.depth; + fb_fix_info.smem_start = (void *) init_frame_buffer_entries.base; + fb_fix_info.smem_len = init_frame_buffer_entries.size; + fb_fix_info.line_length = get_pitch_entries.pitch; + + if ( fb_fix_info.smem_start == NULL ) + return RPI_FB_INIT_START_ADDR_UNKNOWN; + + printk("fb_fix_info.smem_start %p\n", fb_fix_info.smem_start); + + arm_cp15_set_translation_table_entries( (void *) fb_fix_info.smem_start, + (void *) fb_fix_info.smem_start + + fb_fix_info.smem_len, + ARMV7_MMU_DATA_READ_WRITE_CACHED ); + + return RPI_FB_INIT_OK; +} + +/* + * fbds device driver initialize entry point. + */ + +rtems_device_driver frame_buffer_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + + /* register the devices */ + status = rtems_io_register_name( FRAMEBUFFER_DEVICE_0_NAME, major, 0 ); + + if ( status != RTEMS_SUCCESSFUL ) { + printk( "[!] error registering framebuffer\n" ); + rtems_fatal_error_occurred( status ); + } + + _Atomic_Flag_clear( &driver_mutex, ATOMIC_ORDER_RELEASE ); + return RTEMS_SUCCESSFUL; +} + +/* + * fbds device driver open operation. + */ + +rtems_device_driver frame_buffer_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + if ( _Atomic_Flag_test_and_set( &driver_mutex, + ATOMIC_ORDER_ACQUIRE ) != 0 ) { + printk( "RaspberryPi framebuffer could not lock driver_mutex\n" ); + return RTEMS_UNSATISFIED; + } + + if ( fb_fix_info.smem_start == NULL ) { + int res; + res = rpi_fb_init(); + if ( (res < RPI_FB_INIT_OK) || (fb_fix_info.smem_start == NULL) ) { + _Atomic_Flag_clear( &driver_mutex, ATOMIC_ORDER_RELEASE ); + printk( "RaspberryPi framebuffer initialization failed\n" ); + return RTEMS_UNSATISFIED; + } + } + + memset( (void *) fb_fix_info.smem_start, 0, fb_fix_info.smem_len ); + return RTEMS_SUCCESSFUL; +} + +/* + * fbds device driver close operation. + */ + +rtems_device_driver frame_buffer_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + /* restore previous state. for VGA this means return to text mode. + * leave out if graphics hardware has been initialized in + * frame_buffer_initialize() */ + memset( (void *) fb_fix_info.smem_start, 0, fb_fix_info.smem_len ); + _Atomic_Flag_clear( &driver_mutex, ATOMIC_ORDER_RELEASE ); + return RTEMS_SUCCESSFUL; +} + +/* + * fbds device driver read operation. + */ + +rtems_device_driver frame_buffer_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg; + + rw_args->bytes_moved = + ( ( rw_args->offset + rw_args->count ) > fb_fix_info.smem_len ) ? + ( fb_fix_info.smem_len - rw_args->offset ) : rw_args->count; + memcpy( rw_args->buffer, + (const void *) ( fb_fix_info.smem_start + rw_args->offset ), + rw_args->bytes_moved ); + return RTEMS_SUCCESSFUL; +} + +/* + * fbds device driver write operation. + */ + +rtems_device_driver frame_buffer_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg; + + rw_args->bytes_moved = + ( ( rw_args->offset + rw_args->count ) > fb_fix_info.smem_len ) ? + ( fb_fix_info.smem_len - rw_args->offset ) : rw_args->count; + memcpy( (void *) ( fb_fix_info.smem_start + rw_args->offset ), + rw_args->buffer, + rw_args->bytes_moved ); + return RTEMS_SUCCESSFUL; +} + +/* + * ioctl entry point. + */ + +rtems_device_driver frame_buffer_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_libio_ioctl_args_t *args = arg; + + /* XXX check minor */ + + switch ( args->command ) { + case FBIOGET_VSCREENINFO: + memcpy( args->buffer, &fb_var_info, sizeof( fb_var_info ) ); + args->ioctl_return = 0; + break; + case FBIOGET_FSCREENINFO: + memcpy( args->buffer, &fb_fix_info, sizeof( fb_fix_info ) ); + args->ioctl_return = 0; + break; + case FBIOGETCMAP: + /* no palette - truecolor mode */ + args->ioctl_return = -1; + return RTEMS_UNSATISFIED; + case FBIOPUTCMAP: + /* no palette - truecolor mode */ + args->ioctl_return = -1; + return RTEMS_UNSATISFIED; + default: + args->ioctl_return = -1; + return RTEMS_UNSATISFIED; + } + + return RTEMS_SUCCESSFUL; +} diff --git a/bsps/arm/raspberrypi/console/fbcons.c b/bsps/arm/raspberrypi/console/fbcons.c new file mode 100644 index 0000000000..3669ba458d --- /dev/null +++ b/bsps/arm/raspberrypi/console/fbcons.c @@ -0,0 +1,177 @@ +/** + * @file + * + * @ingroup raspberrypi_console + * + * @brief framebuffer graphic console support. + */ + +/* + * Copyright (c) 2015 Yang Qiao + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.org/license/LICENSE + * + */ + +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include + +/* + * fbcons_init + * + * This function initializes the fb console to a quiecsent state. + */ +static void fbcons_init( int minor ) +{ +} + +/* + * fbcons_open + * + * This function opens a port for communication. + * + * Default state is 9600 baud, 8 bits, No parity, and 1 stop bit. + */ +static int fbcons_open( + int major, + int minor, + void *arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * fbcons_close + * + * This function shuts down the requested port. + */ +static int fbcons_close( + int major, + int minor, + void *arg +) +{ + return ( RTEMS_SUCCESSFUL ); +} + +/* + * fbcons_write_polled + * + * This routine polls out the requested character. + */ +static void fbcons_write_polled( + int minor, + char c +) +{ + rpi_fb_outch( c ); + + if ( c == '\n' ) + rpi_fb_outch( '\r' ); /* LF = LF + CR */ +} + +/* + * fbcons_write_support_polled + * + * Console Termios output entry point when using polled output. + * + */ +static ssize_t fbcons_write_support_polled( + int minor, + const char *buf, + size_t len +) +{ + int nwrite = 0; + + /* + * poll each byte in the string out of the port. + */ + while ( nwrite < len ) { + fbcons_write_polled( minor, *buf++ ); + nwrite++; + } + + /* + * return the number of bytes written. + */ + return nwrite; +} + +/* + * fbcons_inbyte_nonblocking_polled + * + * Console Termios polling input entry point. + */ +static int fbcons_inbyte_nonblocking_polled( int minor ) +{ + // if( rtems_kbpoll() ) { + // int c = getch(); + // return c; + // } + + return -1; +} + +/* + * fbcons_set_attributes + * + * This function sets the UART channel to reflect the requested termios + * port settings. + */ +static int fbcons_set_attributes( + int minor, + const struct termios *t +) +{ + return 0; +} + +bool fbcons_probe( int minor ) +{ + // rtems_status_code status; + static bool firstTime = true; + static bool ret = false; + + /* + * keyboard interrupt should be registered when the keyboard is available + */ + if ( firstTime ) { + if ( !rpi_fb_hdmi_is_present() ) { + ret = false; + } else { + ret = true; + } + } + + firstTime = false; + + return ret; +} + +const console_fns fbcons_fns = +{ + .deviceProbe = libchip_serial_default_probe, /* deviceProbe */ + .deviceFirstOpen = fbcons_open, /* deviceFirstOpen */ + .deviceLastClose = fbcons_close, /* deviceLastClose */ + .deviceRead = fbcons_inbyte_nonblocking_polled, /* deviceRead */ + .deviceWrite = fbcons_write_support_polled, /* deviceWrite */ + .deviceInitialize = fbcons_init, /* deviceInitialize */ + .deviceWritePolled = fbcons_write_polled, /* deviceWritePolled */ + .deviceSetAttributes = fbcons_set_attributes, /* deviceSetAttributes */ + .deviceOutputUsesInterrupts = FALSE, /* deviceOutputUsesInterrupts*/ +}; diff --git a/bsps/arm/raspberrypi/console/font_data.h b/bsps/arm/raspberrypi/console/font_data.h new file mode 100644 index 0000000000..852310cbf9 --- /dev/null +++ b/bsps/arm/raspberrypi/console/font_data.h @@ -0,0 +1,4639 @@ +/** + * @file + * + * @ingroup raspberrypi + * + * @brief graphic text console font file + * + */ +/* + * Copyright (c) 2015 Yang Qiao + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.org/license/LICENSE + * + */ + +#ifndef LIBBSP_ARM_RASPBERRYPI_FONT_DATA_H +#define LIBBSP_ARM_RASPBERRYPI_FONT_DATA_H + +#define RPI_FONT_CHARS 256 +#define RPI_FONT_WIDTH 8 +#define RPI_FONT_HEIGHT 16 +#define RPI_FONT_SIZE (RPI_FONT_CHARS * RPI_FONT_HEIGHT) + +static unsigned char rpi_font[RPI_FONT_SIZE] = { + + /* 0 0x00 '^@' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 1 0x01 '^A' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x81, /* 10000001 */ + 0xa5, /* 10100101 */ + 0x81, /* 10000001 */ + 0x81, /* 10000001 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0x81, /* 10000001 */ + 0x81, /* 10000001 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 2 0x02 '^B' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xdb, /* 11011011 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 3 0x03 '^C' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 4 0x04 '^D' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 5 0x05 '^E' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0xe7, /* 11100111 */ + 0xe7, /* 11100111 */ + 0xe7, /* 11100111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 6 0x06 '^F' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 7 0x07 '^G' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 8 0x08 '^H' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xe7, /* 11100111 */ + 0xc3, /* 11000011 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 9 0x09 '^I' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x42, /* 01000010 */ + 0x42, /* 01000010 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 10 0x0a '^J' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0x99, /* 10011001 */ + 0xbd, /* 10111101 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0xc3, /* 11000011 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 11 0x0b '^K' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1e, /* 00011110 */ + 0x0e, /* 00001110 */ + 0x1a, /* 00011010 */ + 0x32, /* 00110010 */ + 0x78, /* 01111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 12 0x0c '^L' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 13 0x0d '^M' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x33, /* 00110011 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x70, /* 01110000 */ + 0xf0, /* 11110000 */ + 0xe0, /* 11100000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 14 0x0e '^N' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x63, /* 01100011 */ + 0x63, /* 01100011 */ + 0x63, /* 01100011 */ + 0x67, /* 01100111 */ + 0xe7, /* 11100111 */ + 0xe6, /* 11100110 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 15 0x0f '^O' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xdb, /* 11011011 */ + 0x3c, /* 00111100 */ + 0xe7, /* 11100111 */ + 0x3c, /* 00111100 */ + 0xdb, /* 11011011 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 16 0x10 '^P' */ + 0x00, /* 00000000 */ + 0x80, /* 10000000 */ + 0xc0, /* 11000000 */ + 0xe0, /* 11100000 */ + 0xf0, /* 11110000 */ + 0xf8, /* 11111000 */ + 0xfe, /* 11111110 */ + 0xf8, /* 11111000 */ + 0xf0, /* 11110000 */ + 0xe0, /* 11100000 */ + 0xc0, /* 11000000 */ + 0x80, /* 10000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 17 0x11 '^Q' */ + 0x00, /* 00000000 */ + 0x02, /* 00000010 */ + 0x06, /* 00000110 */ + 0x0e, /* 00001110 */ + 0x1e, /* 00011110 */ + 0x3e, /* 00111110 */ + 0xfe, /* 11111110 */ + 0x3e, /* 00111110 */ + 0x1e, /* 00011110 */ + 0x0e, /* 00001110 */ + 0x06, /* 00000110 */ + 0x02, /* 00000010 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 18 0x12 '^R' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 19 0x13 '^S' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 20 0x14 '^T' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7f, /* 01111111 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7b, /* 01111011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 21 0x15 '^U' */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x0c, /* 00001100 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 22 0x16 '^V' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 23 0x17 '^W' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 24 0x18 '^X' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 25 0x19 '^Y' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 26 0x1a '^Z' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 27 0x1b '^[' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xfe, /* 11111110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 28 0x1c '^\' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 29 0x1d '^]' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x28, /* 00101000 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x28, /* 00101000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 30 0x1e '^^' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 31 0x1f '^_' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 32 0x20 ' ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 33 0x21 '!' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 34 0x22 '"' */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x24, /* 00100100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 35 0x23 '#' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 36 0x24 '$' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc2, /* 11000010 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x86, /* 10000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 37 0x25 '%' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc2, /* 11000010 */ + 0xc6, /* 11000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc6, /* 11000110 */ + 0x86, /* 10000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 38 0x26 '&' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 39 0x27 ''' */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 40 0x28 '(' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 41 0x29 ')' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 42 0x2a '*' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0xff, /* 11111111 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 43 0x2b '+' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 44 0x2c ',' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 45 0x2d '-' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 46 0x2e '.' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 47 0x2f '/' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x02, /* 00000010 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0x80, /* 10000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 48 0x30 '0' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 49 0x31 '1' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x38, /* 00111000 */ + 0x78, /* 01111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 50 0x32 '2' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 51 0x33 '3' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x3c, /* 00111100 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 52 0x34 '4' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x1c, /* 00011100 */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x1e, /* 00011110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 53 0x35 '5' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 54 0x36 '6' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 55 0x37 '7' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 56 0x38 '8' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 57 0x39 '9' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 58 0x3a ':' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 59 0x3b ';' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 60 0x3c '<' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 61 0x3d '=' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 62 0x3e '>' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 63 0x3f '?' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 64 0x40 '@' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xdc, /* 11011100 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 65 0x41 'A' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 66 0x42 'B' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 67 0x43 'C' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc2, /* 11000010 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc2, /* 11000010 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 68 0x44 'D' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 69 0x45 'E' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x66, /* 01100110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x60, /* 01100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 70 0x46 'F' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x66, /* 01100110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 71 0x47 'G' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc2, /* 11000010 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xde, /* 11011110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x66, /* 01100110 */ + 0x3a, /* 00111010 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 72 0x48 'H' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 73 0x49 'I' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 74 0x4a 'J' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1e, /* 00011110 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 75 0x4b 'K' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xe6, /* 11100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x78, /* 01111000 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 76 0x4c 'L' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 77 0x4d 'M' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xee, /* 11101110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 78 0x4e 'N' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xfe, /* 11111110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 79 0x4f 'O' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 80 0x50 'P' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 81 0x51 'Q' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xde, /* 11011110 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0x0e, /* 00001110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 82 0x52 'R' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 83 0x53 'S' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x38, /* 00111000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 84 0x54 'T' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x5a, /* 01011010 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 85 0x55 'U' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 86 0x56 'V' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 87 0x57 'W' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0xee, /* 11101110 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 88 0x58 'X' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 89 0x59 'Y' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 90 0x5a 'Z' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x86, /* 10000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc2, /* 11000010 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 91 0x5b '[' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 92 0x5c '\' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x80, /* 10000000 */ + 0xc0, /* 11000000 */ + 0xe0, /* 11100000 */ + 0x70, /* 01110000 */ + 0x38, /* 00111000 */ + 0x1c, /* 00011100 */ + 0x0e, /* 00001110 */ + 0x06, /* 00000110 */ + 0x02, /* 00000010 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 93 0x5d ']' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 94 0x5e '^' */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 95 0x5f '_' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 96 0x60 '`' */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 97 0x61 'a' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 98 0x62 'b' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 99 0x63 'c' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 100 0x64 'd' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1c, /* 00011100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 101 0x65 'e' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 102 0x66 'f' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1c, /* 00011100 */ + 0x36, /* 00110110 */ + 0x32, /* 00110010 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 103 0x67 'g' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + + /* 104 0x68 'h' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x6c, /* 01101100 */ + 0x76, /* 01110110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 105 0x69 'i' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 106 0x6a 'j' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x0e, /* 00001110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 107 0x6b 'k' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x78, /* 01111000 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 108 0x6c 'l' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 109 0x6d 'm' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xec, /* 11101100 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 110 0x6e 'n' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 111 0x6f 'o' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 112 0x70 'p' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* 113 0x71 'q' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x1e, /* 00011110 */ + 0x00, /* 00000000 */ + + /* 114 0x72 'r' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x76, /* 01110110 */ + 0x66, /* 01100110 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 115 0x73 's' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x38, /* 00111000 */ + 0x0c, /* 00001100 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 116 0x74 't' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0xfc, /* 11111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x36, /* 00110110 */ + 0x1c, /* 00011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 117 0x75 'u' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 118 0x76 'v' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 119 0x77 'w' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 120 0x78 'x' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 121 0x79 'y' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + + /* 122 0x7a 'z' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xcc, /* 11001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 123 0x7b '{' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 124 0x7c '|' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 125 0x7d '}' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 126 0x7e '~' */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 127 0x7f */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 128 0x80 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc2, /* 11000010 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc2, /* 11000010 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 129 0x81 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 130 0x82 */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 131 0x83 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 132 0x84 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 133 0x85 */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 134 0x86 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 135 0x87 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 136 0x88 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 137 0x89 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 138 0x8a */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 139 0x8b */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 140 0x8c */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 141 0x8d */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 142 0x8e */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 143 0x8f */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 144 0x90 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x66, /* 01100110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 145 0x91 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xec, /* 11101100 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x6e, /* 01101110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 146 0x92 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3e, /* 00111110 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xce, /* 11001110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 147 0x93 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 148 0x94 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 149 0x95 */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 150 0x96 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 151 0x97 */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 152 0x98 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + + /* 153 0x99 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 154 0x9a */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 155 0x9b */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 156 0x9c */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x64, /* 01100100 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xe6, /* 11100110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 157 0x9d */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 158 0x9e */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xf8, /* 11111000 */ + 0xc4, /* 11000100 */ + 0xcc, /* 11001100 */ + 0xde, /* 11011110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 159 0x9f */ + 0x00, /* 00000000 */ + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 160 0xa0 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 161 0xa1 */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 162 0xa2 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 163 0xa3 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 164 0xa4 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 165 0xa5 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xfe, /* 11111110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 166 0xa6 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x3e, /* 00111110 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 167 0xa7 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 168 0xa8 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 169 0xa9 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 170 0xaa */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 171 0xab */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0xe0, /* 11100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xdc, /* 11011100 */ + 0x86, /* 10000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x3e, /* 00111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 172 0xac */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0xe0, /* 11100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x66, /* 01100110 */ + 0xce, /* 11001110 */ + 0x9a, /* 10011010 */ + 0x3f, /* 00111111 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 173 0xad */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 174 0xae */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x36, /* 00110110 */ + 0x6c, /* 01101100 */ + 0xd8, /* 11011000 */ + 0x6c, /* 01101100 */ + 0x36, /* 00110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 175 0xaf */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xd8, /* 11011000 */ + 0x6c, /* 01101100 */ + 0x36, /* 00110110 */ + 0x6c, /* 01101100 */ + 0xd8, /* 11011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 176 0xb0 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + + /* 177 0xb1 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + + /* 178 0xb2 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + + /* 179 0xb3 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 180 0xb4 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 181 0xb5 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 182 0xb6 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 183 0xb7 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 184 0xb8 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 185 0xb9 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 186 0xba */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 187 0xbb */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 188 0xbc */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 189 0xbd */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 190 0xbe */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 191 0xbf */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 192 0xc0 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 193 0xc1 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 194 0xc2 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 195 0xc3 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 196 0xc4 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 197 0xc5 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 198 0xc6 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 199 0xc7 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 200 0xc8 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 201 0xc9 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 202 0xca */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 203 0xcb */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 204 0xcc */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 205 0xcd */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 206 0xce */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 207 0xcf */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 208 0xd0 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 209 0xd1 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 210 0xd2 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 211 0xd3 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 212 0xd4 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 213 0xd5 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 214 0xd6 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 215 0xd7 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 216 0xd8 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 217 0xd9 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 218 0xda */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 219 0xdb */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 220 0xdc */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 221 0xdd */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + + /* 222 0xde */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + + /* 223 0xdf */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 224 0xe0 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xdc, /* 11011100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 225 0xe1 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xd8, /* 11011000 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 226 0xe2 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 227 0xe3 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 228 0xe4 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 229 0xe5 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 230 0xe6 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + + /* 231 0xe7 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 232 0xe8 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 233 0xe9 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 234 0xea */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xee, /* 11101110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 235 0xeb */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1e, /* 00011110 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x3e, /* 00111110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 236 0xec */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 237 0xed */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x03, /* 00000011 */ + 0x06, /* 00000110 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0xf3, /* 11110011 */ + 0x7e, /* 01111110 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 238 0xee */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1c, /* 00011100 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x1c, /* 00011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 239 0xef */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 240 0xf0 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 241 0xf1 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 242 0xf2 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 243 0xf3 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 244 0xf4 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 245 0xf5 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 246 0xf6 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 247 0xf7 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 248 0xf8 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 249 0xf9 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 250 0xfa */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 251 0xfb */ + 0x00, /* 00000000 */ + 0x0f, /* 00001111 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0xec, /* 11101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x3c, /* 00111100 */ + 0x1c, /* 00011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 252 0xfc */ + 0x00, /* 00000000 */ + 0x6c, /* 01101100 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 253 0xfd */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x32, /* 00110010 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 254 0xfe */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 255 0xff */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + +}; + +#endif diff --git a/bsps/arm/raspberrypi/console/outch.c b/bsps/arm/raspberrypi/console/outch.c new file mode 100644 index 0000000000..20601384c7 --- /dev/null +++ b/bsps/arm/raspberrypi/console/outch.c @@ -0,0 +1,463 @@ +/** + * @file + * + * @ingroup raspberrypi + * + * @brief displaying characters on the console + */ + +/** + * + * Copyright (c) 2015 Yang Qiao + * based on work by: + * Copyright (C) 1998 Eric Valette (valette@crf.canon.fr) + * Canon Centre Recherche France. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + * Till Straumann , 2003/9: + * - added handling of basic escape sequences (cursor movement + * and erasing; just enough for the line editor 'libtecla' to + * work...) + * + */ + +#include +#include +#include +#include + +#include +#include +#include "font_data.h" + +static void wr_cursor( + int r, + int c +) +{ + /* dummy function for now */ +} + +#define TAB_SPACE 4 +#define CONSOLE_BG_COL 0x00 +#define CONSOLE_FG_COL 0xa0 + +static void *fb_mem = NULL; +static unsigned short maxCol; +static unsigned short maxRow; +static unsigned short bytes_per_pixel; +static unsigned int bytes_per_line; +static unsigned int bytes_per_char_line; +static unsigned char row; +static unsigned char column; +static unsigned int nLines; +static uint32_t fgx, bgx, eorx; +static int rpi_video_initialized; + +static const int video_font_draw_table32[ 16 ][ 4 ] = { + { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + { 0x00000000, 0x00000000, 0x00000000, 0x00ffffff }, + { 0x00000000, 0x00000000, 0x00ffffff, 0x00000000 }, + { 0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff }, + { 0x00000000, 0x00ffffff, 0x00000000, 0x00000000 }, + { 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff }, + { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000 }, + { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff }, + { 0x00ffffff, 0x00000000, 0x00000000, 0x00000000 }, + { 0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff }, + { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000 }, + { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff }, + { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000 }, + { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff }, + { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000 }, + { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff } +}; + +static void scroll( void ) +{ + int i, j; /* Counters */ + uint8_t *pt_scroll, *pt_bitmap; /* Pointers on the bit-map */ + + pt_bitmap = fb_mem; + j = 0; + pt_bitmap = pt_bitmap + j; + pt_scroll = pt_bitmap + bytes_per_char_line; + + for ( i = j; i < maxRow - 1; i++ ) { + memcpy( pt_bitmap, pt_scroll, bytes_per_char_line ); + pt_bitmap = pt_bitmap + bytes_per_char_line; + pt_scroll = pt_bitmap + bytes_per_char_line; + } + + /* + * Blank characters are displayed on the last line. + */ + memset( pt_bitmap, 0, bytes_per_char_line ); +} + +static void doCRNL( + int cr, + int nl +) +{ + if ( nl ) { + if ( ++row == maxRow ) { + scroll(); /* Scroll the screen now */ + row = maxRow - 1; + } + + nLines++; + } + + if ( cr ) + column = 0; + + /* Move cursor on the next location */ + if ( cr || nl ) { + wr_cursor( row, column ); + } +} + +static void advanceCursor( void ) +{ + if ( ++column == maxCol ) + doCRNL( 1, 1 ); + else + wr_cursor( row, column ); +} + +static void gotorc( + int r, + int c +) +{ + column = c; + row = r; + wr_cursor( row, column ); +} + +static void video_drawchars( + int r, + int c, + unsigned char ch +) +{ + if ( fb_mem == NULL ) { + return; + } + + uint8_t *cdat, *dest, *dest0; + int rows, offset; + + offset = r * bytes_per_char_line + c * bytes_per_pixel * RPI_FONT_WIDTH; + dest0 = fb_mem + offset; + + /* + * only 32-bit per pixel format is supported for now + */ + cdat = rpi_font + ch * RPI_FONT_HEIGHT; + + for ( rows = RPI_FONT_HEIGHT, dest = dest0; + rows--; dest += bytes_per_line ) { + uint8_t bits = *cdat++; + + ( (uint32_t *) dest )[ 0 ] = + ( video_font_draw_table32 + [ bits >> 4 ][ 0 ] & eorx ) ^ bgx; + ( (uint32_t *) dest )[ 1 ] = + ( video_font_draw_table32 + [ bits >> 4 ][ 1 ] & eorx ) ^ bgx; + ( (uint32_t *) dest )[ 2 ] = + ( video_font_draw_table32 + [ bits >> 4 ][ 2 ] & eorx ) ^ bgx; + ( (uint32_t *) dest )[ 3 ] = + ( video_font_draw_table32 + [ bits >> 4 ][ 3 ] & eorx ) ^ bgx; + + ( (uint32_t *) dest )[ 4 ] = + ( video_font_draw_table32 + [ bits & 15 ][ 0 ] & eorx ) ^ bgx; + ( (uint32_t *) dest )[ 5 ] = + ( video_font_draw_table32 + [ bits & 15 ][ 1 ] & eorx ) ^ bgx; + ( (uint32_t *) dest )[ 6 ] = + ( video_font_draw_table32 + [ bits & 15 ][ 2 ] & eorx ) ^ bgx; + ( (uint32_t *) dest )[ 7 ] = + ( video_font_draw_table32 + [ bits & 15 ][ 3 ] & eorx ) ^ bgx; + } +} + +#define ESC ( (char) 27 ) +/* erase current location without moving the cursor */ +#define BLANK ( (char) 0x7f ) + +static void videoPutChar( char ch ) +{ + switch ( ch ) { + case '\b': { + if ( column ) + column--; + + /* Move cursor on the previous location */ + wr_cursor( row, column ); + return; + } + case '\t': { + int i; + + i = TAB_SPACE - ( column & ( TAB_SPACE - 1 ) ); + + while ( i-- ) { + + video_drawchars( row, column, ' ' ); + column += 1; + + if ( column >= maxCol ) { + doCRNL( 1, 1 ); + return; + } + } + + wr_cursor( row, column ); + + return; + } + case '\n': { + doCRNL( 0, 1 ); + return; + } + case 7: { /* Bell code must be inserted here */ + return; + } + case '\r': { + doCRNL( 1, 0 ); + return; + } + case BLANK: { + video_drawchars( row, column, ' ' ); + + wr_cursor( row, column ); + + return; + } + default: { + // *pt_bitmap = (unsigned char)ch | attribute; + video_drawchars( row, column, ch ); + advanceCursor(); + return; + } + } +} + +/* trivial state machine to handle escape sequences: + * + * --------------------------------- + * | | + * | | + * KEY: esc V [ DCABHKJ esc | + * STATE: 0 -----> 27 -----> '[' ----------> -1 ----- + * ^\ \ \ \ + * KEY: | \other \ other \ other \ other + * <------------------------------------- + * + * in state '-1', the DCABHKJ cases are handled + * + * (cursor motion and screen clearing) + */ + +#define DONE ( -1 ) + +static int handleEscape( + int oldState, + char ch +) +{ + int rval = 0; + int ro, co; + + switch ( oldState ) { + case DONE: /* means the previous char terminated an ESC sequence... */ + case 0: + + if ( 27 == ch ) { + rval = 27; /* START of an ESC sequence */ + } + + break; + + case 27: + + if ( '[' == ch ) { + rval = ch; /* received ESC '[', so far */ + } else { + /* dump suppressed 'ESC'; outch will append the char */ + videoPutChar( ESC ); + } + + break; + + case '[': + /* handle 'ESC' '[' sequences here */ + ro = row; + co = column; + rval = DONE; /* done */ + + switch ( ch ) { + case 'D': /* left */ + + if ( co > 0 ) + co--; + + break; + case 'C': /* right */ + + if ( co < maxCol ) + co++; + + break; + case 'A': /* up */ + + if ( ro > 0 ) + ro--; + + break; + case 'B': /* down */ + + if ( ro < maxRow ) + ro++; + + break; + case 'H': /* home */ + ro = co = 0; + break; + case 'K': /* clear to end of line */ + + while ( column < maxCol - 1 ) + videoPutChar( ' ' ); + + videoPutChar( BLANK ); + break; + case 'J': /* clear to end of screen */ + + while ( ( ( row < maxRow - 1 ) || ( column < maxCol - 1 ) ) ) + videoPutChar( ' ' ); + + videoPutChar( BLANK ); + break; + default: + videoPutChar( ESC ); + videoPutChar( '[' ); + /* DONT move the cursor */ + ro = -1; + rval = 0; + break; + } + + // /* reset cursor */ + if ( ro >= 0 ) + gotorc( ro, co ); + + default: + break; + } + + return rval; +} + +static void clear_screen( void ) +{ + int i, j; + + for ( j = 0; j < maxRow; j++ ) { + for ( i = 0; i < maxCol; i++ ) { + videoPutChar( ' ' ); + } + } + + column = 0; + row = 0; +} + +void rpi_fb_outch( char c ) +{ + static int escaped = 0; + + if ( !( escaped = handleEscape( escaped, c ) ) ) { + if ( '\n' == c ) + videoPutChar( '\r' ); + + videoPutChar( c ); + } +} + +void rpi_video_init( void ) +{ + int ret = rpi_fb_init(); + + if ( ( ret != RPI_FB_INIT_OK ) && + ( ret != RPI_FB_INIT_ALREADY_INITIALIZED ) ) { + rpi_video_initialized = 0; + return; + } + + struct fb_var_screeninfo fb_var_info; + struct fb_fix_screeninfo fb_fix_info; + rpi_get_var_screen_info( &fb_var_info ); + rpi_get_fix_screen_info( &fb_fix_info ); + maxCol = fb_var_info.xres / RPI_FONT_WIDTH; + maxRow = fb_var_info.yres / RPI_FONT_HEIGHT; + bytes_per_pixel = fb_var_info.bits_per_pixel / 8; + bytes_per_line = bytes_per_pixel * fb_var_info.xres; + bytes_per_char_line = RPI_FONT_HEIGHT * bytes_per_line; + fb_mem = RTEMS_DEVOLATILE( void *, fb_fix_info.smem_start ); + column = 0; + row = 0; + nLines = 0; + fgx = ( CONSOLE_FG_COL << 24 ) | + ( CONSOLE_FG_COL << 16 ) | + ( CONSOLE_FG_COL << 8 ) | + CONSOLE_FG_COL; + bgx = ( CONSOLE_BG_COL << 24 ) | + ( CONSOLE_BG_COL << 16 ) | + ( CONSOLE_BG_COL << 8 ) | + CONSOLE_BG_COL; + eorx = fgx ^ bgx; + clear_screen(); + rpi_video_initialized = 1; +} + +int rpi_video_is_initialized( void ) +{ + return rpi_video_initialized; +} + +/* for old DOS compatibility n-curses type of applications */ +void gotoxy( + int x, + int y +); +int whereX( void ); +int whereY( void ); + +void gotoxy( + int x, + int y +) +{ + gotorc( y, x ); +} + +int whereX( void ) +{ + return row; +} + +int whereY( void ) +{ + return column; +} diff --git a/bsps/arm/raspberrypi/console/usart.c b/bsps/arm/raspberrypi/console/usart.c new file mode 100644 index 0000000000..25fb523621 --- /dev/null +++ b/bsps/arm/raspberrypi/console/usart.c @@ -0,0 +1,167 @@ +/** + * @file + * + * @ingroup raspberrypi_usart + * + * @brief USART support. + */ + +/* + * Copyright (c) 2013 Alan Cudmore + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.org/license/LICENSE + * + */ + +#include + +#include +#include +#include +#include +#include + +static void usart_delay(uint32_t n) +{ + volatile uint32_t i = 0; + + for(i = 0; i < n; i++) + ; +} + +#if 0 +/* + * These will be useful when the driver supports interrupt driven IO. + */ +static rtems_vector_number usart_get_irq_number(const console_tbl *ct) +{ + return ct->ulIntVector; +} + +static uint32_t usart_get_baud(const console_tbl *ct) +{ + return ct->ulClock; +} +#endif + +static void usart_set_baud(int minor, int baud) +{ + /* + * Nothing for now + */ + return; +} + +static void usart_initialize(int minor) +{ + unsigned int gpio_reg; + + /* + ** Program GPIO pins for UART 0 + */ + gpio_reg = BCM2835_REG(BCM2835_GPIO_GPFSEL1); + gpio_reg &= ~(7<<12); /* gpio14 */ + gpio_reg |= (4<<12); /* alt0 */ + gpio_reg &= ~(7<<15); /* gpio15 */ + gpio_reg |= (4<<15); /* alt0 */ + BCM2835_REG(BCM2835_GPIO_GPFSEL1) = gpio_reg; + + BCM2835_REG(BCM2835_GPIO_GPPUD) = 0; + usart_delay(150); + BCM2835_REG(BCM2835_GPIO_GPPUDCLK0) = (1<<14)|(1<<15); + usart_delay(150); + BCM2835_REG(BCM2835_GPIO_GPPUDCLK0) = 0; + + /* + ** Init the PL011 UART + */ + BCM2835_REG(BCM2835_UART0_CR) = 0; + BCM2835_REG(BCM2835_UART0_ICR) = 0x7FF; + BCM2835_REG(BCM2835_UART0_IMSC) = 0; + BCM2835_REG(BCM2835_UART0_IBRD) = 1; + BCM2835_REG(BCM2835_UART0_FBRD) = 40; + BCM2835_REG(BCM2835_UART0_LCRH) = 0x70; + BCM2835_REG(BCM2835_UART0_RSRECR) = 0; + + BCM2835_REG(BCM2835_UART0_CR) = 0x301; + + BCM2835_REG(BCM2835_UART0_IMSC) = BCM2835_UART0_IMSC_RX; + + usart_set_baud(minor, 115000); +} + +static int usart_first_open(int major, int minor, void *arg) +{ + rtems_libio_open_close_args_t *oc = (rtems_libio_open_close_args_t *) arg; + struct rtems_termios_tty *tty = (struct rtems_termios_tty *) oc->iop->data1; + const console_tbl *ct = Console_Port_Tbl [minor]; + console_data *cd = &Console_Port_Data [minor]; + + cd->termios_data = tty; + rtems_termios_set_initial_baud(tty, ct->ulClock); + + return 0; +} + +static int usart_last_close(int major, int minor, void *arg) +{ + return 0; +} + +static int usart_read_polled(int minor) +{ + if (minor == 0) { + if (((BCM2835_REG(BCM2835_UART0_FR)) & BCM2835_UART0_FR_RXFE) == 0) { + return((BCM2835_REG(BCM2835_UART0_DR)) & 0xFF ); + } else { + return -1; + } + } else { + printk("Unknown console minor number: %d\n", minor); + return -1; + } +} + +static void usart_write_polled(int minor, char c) +{ + while (1) { + if ((BCM2835_REG(BCM2835_UART0_FR) & BCM2835_UART0_FR_TXFF) == 0) + break; + } + BCM2835_REG(BCM2835_UART0_DR) = c; +} + +static ssize_t usart_write_support_polled( + int minor, + const char *s, + size_t n +) +{ + ssize_t i = 0; + + for (i = 0; i < n; ++i) { + usart_write_polled(minor, s [i]); + } + + return n; +} + +static int usart_set_attributes(int minor, const struct termios *term) +{ + return -1; +} + +const console_fns bcm2835_usart_fns = { + .deviceProbe = libchip_serial_default_probe, + .deviceFirstOpen = usart_first_open, + .deviceLastClose = usart_last_close, + .deviceRead = usart_read_polled, + .deviceWrite = usart_write_support_polled, + .deviceInitialize = usart_initialize, + .deviceWritePolled = usart_write_polled, + .deviceSetAttributes = usart_set_attributes, + .deviceOutputUsesInterrupts = false +}; diff --git a/bsps/arm/realview-pbx-a9/console/console-config.c b/bsps/arm/realview-pbx-a9/console/console-config.c new file mode 100644 index 0000000000..66dcfa6803 --- /dev/null +++ b/bsps/arm/realview-pbx-a9/console/console-config.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include + +#include +#include +#include +#include +#include + +static arm_pl011_context pl011_context = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("PL011"), + .regs = (volatile pl011 *) 0x10009000, + .irq = RVPBXA9_IRQ_UART_0, + .initial_baud = 115200 +}; + +static arm_pl050_context pl050_context = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("PL050"), + .regs = (volatile pl050 *) 0x10007000, + .irq = RVPBXA9_IRQ_KMI1, + .initial_baud = 115200 +}; + +static void output_char(char c) +{ + arm_pl011_write_polled(&pl011_context.base, c); +} + +static bool pl011_probe(rtems_termios_device_context *base) +{ + BSP_output_char = output_char; + + return arm_pl011_probe(base); +} + +static void output_char_init(char c) +{ + pl011_probe(&pl011_context.base); + output_char(c); +} + +BSP_output_char_function_type BSP_output_char = output_char_init; + +BSP_polling_getchar_function_type BSP_poll_char = NULL; + +const console_device console_device_table[] = { + { + .device_file = "/dev/ttyS0", + .probe = pl011_probe, + .handler = &arm_pl011_fns, + .context = &pl011_context.base + }, { + .device_file = SERIAL_MOUSE_DEVICE_PS2, + .probe = console_device_probe_default, + .handler = &arm_pl050_fns, + .context = &pl050_context.base + } +}; + +const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table); diff --git a/bsps/arm/rtl22xx/console/lpc22xx_uart.h b/bsps/arm/rtl22xx/console/lpc22xx_uart.h new file mode 100644 index 0000000000..f6ae249672 --- /dev/null +++ b/bsps/arm/rtl22xx/console/lpc22xx_uart.h @@ -0,0 +1,187 @@ +/** + * @file + * @ingroup rtl22xx_uart + * @brief UART support. + */ + +#ifndef LPC22XX_UART_H +#define LPC22XX_UART_H + +/** + * @defgroup rtl22xx_uart UART Support + * @ingroup arm_rtl22xx + * @brief UART (Universal Asynchronous Reciever/Transmitter) Support + * @{ + */ + +#define FIFODEEP 16 + +#define BD115200 115200 +#define BD38400 38400 +#define BD9600 9600 + +/** @brief PINSEL0 Value for UART0 */ +#define U0_PINSEL (0x00000005) +/** @brief PINSEL0 Mask for UART0 */ +#define U0_PINMASK (0x0000000F) +/** @brief PINSEL0 Value for UART1 */ +#define U1_PINSEL (0x00050000) +/** @brief PINSEL0 Mask for UART1 */ +#define U1_PINMASK (0x000F0000) + +/** + * @name Uart line control register bit descriptions + * @{ + */ + +#define LCR_WORDLENTH_BIT 0 +#define LCR_STOPBITSEL_BIT 2 +#define LCR_PARITYENBALE_BIT 3 +#define LCR_PARITYSEL_BIT 4 +#define LCR_BREAKCONTROL_BIT 6 +#define LCR_DLAB_BIT 7 + +/** @} */ + +/** + * @name Line Control Register bit definitions + * @{ + */ + +/** @brief 5-bit character length */ +#define ULCR_CHAR_5 (0 << 0) +/** @brief 6-bit character length */ +#define ULCR_CHAR_6 (1 << 0) +/** @brief 7-bit character length */ +#define ULCR_CHAR_7 (2 << 0) +/** @brief 8-bit character length */ +#define ULCR_CHAR_8 (3 << 0) +/** @brief no stop bits */ +#define ULCR_STOP_0 (0 << 2) +/** @brief 1 stop bit */ +#define ULCR_STOP_1 (1 << 2) +/** @brief No Parity */ +#define ULCR_PAR_NO (0 << 3) +/** @brief Odd Parity */ +#define ULCR_PAR_ODD (1 << 3) +/** @brief Even Parity */ +#define ULCR_PAR_EVEN (3 << 3) +/** @brief MARK "1" Parity */ +#define ULCR_PAR_MARK (5 << 3) +/** @brief SPACE "0" Paruty */ +#define ULCR_PAR_SPACE (7 << 3) +/** @brief Output BREAK line condition */ +#define ULCR_BREAK_ENABLE (1 << 6) +/** @brief Enable Divisor Latch Access */ +#define ULCR_DLAB_ENABLE (1 << 7) + +/** @} */ + +/** + * @name Modem Control Register bit definitions + * @{ + */ + +/** @brief Data Terminal Ready */ +#define UMCR_DTR (1 << 0) +/** @brief Request To Send */ +#define UMCR_RTS (1 << 1) +/** @brief Loopback */ +#define UMCR_LB (1 << 4) + +/** @} */ + +/** + * @name Line Status Register bit definitions + * @{ + */ + +/** @brief Receive Data Ready */ +#define ULSR_RDR (1 << 0) +/** @brief Overrun Error */ +#define ULSR_OE (1 << 1) +/** @brief Parity Error */ +#define ULSR_PE (1 << 2) +/** @brief Framing Error */ +#define ULSR_FE (1 << 3) +/** @brief Break Interrupt */ +#define ULSR_BI (1 << 4) +/** @brief Transmit Holding Register Empty */ +#define ULSR_THRE (1 << 5) +/** @brief Transmitter Empty */ +#define ULSR_TEMT (1 << 6) +/** @brief Error in Receive FIFO */ +#define ULSR_RXFE (1 << 7) +#define ULSR_ERR_MASK 0x1E + +/** @} */ + +/** + * @name Modem Status Register bit definitions + * @{ + */ + +/** @brief Delta Clear To Send */ +#define UMSR_DCTS (1 << 0) +/** @brief Delta Data Set Ready */ +#define UMSR_DDSR (1 << 1) +/** @brief Trailing Edge Ring Indicator */ +#define UMSR_TERI (1 << 2) +/** @brief Delta Data Carrier Detect */ +#define UMSR_DDCD (1 << 3) +/** @brief Clear To Send */ +#define UMSR_CTS (1 << 4) +/** @brief Data Set Ready */ +#define UMSR_DSR (1 << 5) +/** @brief Ring Indicator */ +#define UMSR_RI (1 << 6) +/** @brief Data Carrier Detect */ +#define UMSR_DCD (1 << 7) + +/** @} */ + +/** + * @name Uart Interrupt Identification + * @{ + */ + +#define IIR_RSL 0x3 +#define IIR_RDA 0x2 +#define IIR_CTI 0x6 +#define IIR_THRE 0x1 + +/** @} */ + +/** + * @name Uart Interrupt Enable Type + * @{ + */ + +#define IER_RBR 0x1 +#define IER_THRE 0x2 +#define IER_RLS 0x4 + +/** @} */ + +/** + * @name Uart Receiver Errors + * @{ + */ + +#define RC_FIFO_OVERRUN_ERR 0x1 +#define RC_OVERRUN_ERR 0x2 +#define RC_PARITY_ERR 0x4 +#define RC_FRAMING_ERR 0x8 +#define RC_BREAK_IND 0x10 + +/** @} */ + +typedef enum { + UART0 = 0, + UART1 +} LPC_UartChanel_t; + +/** @} */ + +#endif + diff --git a/bsps/arm/rtl22xx/console/uart.c b/bsps/arm/rtl22xx/console/uart.c new file mode 100644 index 0000000000..2952e74508 --- /dev/null +++ b/bsps/arm/rtl22xx/console/uart.c @@ -0,0 +1,283 @@ +/* + * console driver for RTL22xx UARTs + * + * If you want the driver to be interrupt driven, you + * need to write the ISR, and in the ISR insert the + * chars into termios's queue. + */ + +/* + * Copyright (c) By ray + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include /* Must be before libio.h */ +#include +#include +#include + +/* Put the CPU (or UART) specific header file #include here */ +#include +#include "lpc22xx_uart.h" + +#include +#include + +/* How many serial ports? */ +#define NUM_DEVS 1 + +int dbg_dly; + +/* static function prototypes */ +static int uart_first_open(int major, int minor, void *arg); +static int uart_last_close(int major, int minor, void *arg); +static int uart_read(int minor); +static ssize_t uart_write(int minor, const char *buf, size_t len); +static void uart_init(int minor); +static void uart_write_polled(int minor, char c); +static int uart_set_attributes(int minor, const struct termios *t); + +/* These are used by code in console.c */ +unsigned long Console_Configuration_Count = NUM_DEVS; + +/* Pointers to functions for handling the UART. */ +const console_fns uart_fns = { + libchip_serial_default_probe, + uart_first_open, + uart_last_close, + uart_read, + uart_write, + uart_init, + uart_write_polled, /* not used in this driver */ + uart_set_attributes, + FALSE /* TRUE if interrupt driven, FALSE if not. */ +}; + +/* + * There's one item in array for each UART. + * + * Some of these fields are marked "NOT USED". They are not used + * by console.c, but may be used by drivers in libchip + */ +console_tbl Console_Configuration_Ports[] = { +{ + "/dev/com0", /* sDeviceName */ + SERIAL_CUSTOM, /* deviceType */ + &uart_fns, /* pDeviceFns */ + NULL, /* deviceProbe */ + NULL, /* pDeviceFlow */ + 0, /* ulMargin - NOT USED */ + 0, /* ulHysteresis - NOT USED */ + NULL, /* pDeviceParams */ + 0, /* ulCtrlPort1 - NOT USED */ + 0, /* ulCtrlPort2 - NOT USED */ + 0, /* ulDataPort - NOT USED */ + NULL, /* getRegister - NOT USED */ + NULL, /* setRegister - NOT USED */ + NULL, /* getData - NOT USED */ + NULL, /* setData - NOT USED */ + 0, /* ulClock - NOT USED */ + 0 /* ulIntVector - NOT USED */ +} +#if 0 +{ + "/dev/com1", /* sDeviceName */ + SERIAL_CUSTOM, /* deviceType */ + &uart_fns, /* pDeviceFns */ + NULL, /* deviceProbe */ + NULL, /* pDeviceFlow */ + 0, /* ulMargin - NOT USED */ + 0, /* ulHysteresis - NOT USED */ + NULL, /* pDeviceParams */ + 0, /* ulCtrlPort1 - NOT USED */ + 0, /* ulCtrlPort2 - NOT USED */ + 0, /* ulDataPort - NOT USED */ + NULL, /* getRegister - NOT USED */ + NULL, /* setRegister - NOT USED */ + NULL, /* getData - NOT USED */ + NULL, /* setData - NOT USED */ + 0, /* ulClock - NOT USED */ + 0 /* ulIntVector - NOT USED */ +} +#endif +}; + +/* + * This is called the first time each device is opened. If the driver + * is interrupt driven, you should enable interrupts here. Otherwise, + * it's probably safe to do nothing. + * + * Since micromonitor already set up the UART, we do nothing. + */ +static int uart_first_open(int major, int minor, void *arg) +{ + return 0; +} + +/* + * This is called the last time each device is closed. If the driver + * is interrupt driven, you should disable interrupts here. Otherwise, + * it's probably safe to do nothing. + */ +static int uart_last_close(int major, int minor, void *arg) +{ + return 0; +} + +/* + * Read one character from UART. + * + * Return -1 if there's no data, otherwise return + * the character in lowest 8 bits of returned int. + */ +static int uart_read(int minor) +{ + char c; + + switch (minor) { + case 0: + if (U0LSR & ULSR_RDR) { + c = U0RBR; + return c; + } + return -1; + case 1: + if (U1LSR & ULSR_RDR) { + c = U1RBR; + return c; + } + return -1; + default: + break; + } + printk("Unknown console minor number %d\n", minor); + return -1; +} + +/* + * Write buffer to UART + * + * return 1 on success, -1 on error + */ +static ssize_t uart_write(int minor, const char *buf, size_t len) +{ + size_t i; + + switch (minor) { + case 0: + for (i = 0; i < len; i++) { + while (!(U0LSR & ULSR_THRE)) /* wait for TX buffer to empty*/ + continue; /* also either WDOG() or swap()*/ + U0THR = (char) buf[i]; + } + break; + case 1: + for (i = 0; i < len; i++) { + while (!(U0LSR & ULSR_THRE)) /* wait for TX buffer to empty*/ + continue; /* also either WDOG() or swap()*/ + U0THR = (char) buf[i]; + } + break; + default: + printk("Unknown console minor number %d\n", minor); + return -1; + } + + return len; +} + +/* Set up the UART. */ +static void uart_init(int minor) +{ +#if 0 //init will be done in bspstart.c + int baud=6; + int mode =0x03; + if(minor==0){ + // set port pins for UART0 + PINSEL0 = (PINSEL0 & ~U0_PINMASK) | U0_PINSEL; + + U0IER = 0x00; // disable all interrupts + + // set the baudrate + U0LCR = 1<<7; // select divisor latches + U0DLL = (uint8_t)baud; // set for baud low byte + U0DLM = (uint8_t)(baud >> 8); // set for baud high byte + + // set the number of characters and other + // user specified operating parameters + U0LCR = (mode & ~ULCR_DLAB_ENABLE); + U0FCR = mode>>8; /*fifo mode*/ + + // set port pins for UART1 + PINSEL0 = (PINSEL0 & ~U1_PINMASK) | U1_PINSEL; + + U1IER = 0x00; // disable all interrupts + }else if(minor==1){ + // set the baudrate + U1LCR = ULCR_DLAB_ENABLE; // select divisor latches + U1DLL = (uint8_t)baud; // set for baud low byte + U1DLM = (uint8_t)(baud >> 8); // set for baud high byte + + // set the number of characters and other + // user specified operating parameters + U1LCR = (mode & ~ULCR_DLAB_ENABLE); + U1FCR = mode>>8;/*fifo mode*/ + } + +#endif +} + +/* I'm not sure this is needed for the shared console driver. */ +static void uart_write_polled(int minor, char c) +{ + uart_write(minor, &c, 1); +} + +/* This is for setting baud rate, bits, etc. */ +static int uart_set_attributes(int minor, const struct termios *t) +{ + return 0; +} + +/* + * Write a character to the console. This is used by printk() and + * maybe other low level functions. It should not use interrupts or any + * RTEMS system calls. It needs to be very simple + */ +static void _BSP_put_char( char c ) +{ + uart_write_polled(0, c); +} + +BSP_output_char_function_type BSP_output_char = _BSP_put_char; + +static int _BSP_get_char(void) +{ + return uart_read(0); +} + +BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char; + +/* + * init USART 0¡£8 bit, 1 Stop,No checkout, BPS115200 + */ +void UART0_Ini(void) +{ + long Fdiv; + int i; + + PINSEL0 = 0x00000005; // I/O to UART0 + U0LCR = 0x83; // DLAB = 1 + Fdiv = (Fpclk >>4) / UART_BPS; // configure BPS + U0DLM = Fdiv/256; + U0DLL = Fdiv%256; + U0LCR = 0x03; + + for(i=0;i<10;i++){ + U0THR = 67; //send a C to see if is OK + while ( (U0LSR&0x40)==0 ); + } +} diff --git a/bsps/arm/smdk2410/console/uart.c b/bsps/arm/smdk2410/console/uart.c new file mode 100644 index 0000000000..06adecf239 --- /dev/null +++ b/bsps/arm/smdk2410/console/uart.c @@ -0,0 +1,242 @@ +/* + * console driver for S3C2400 UARTs + * + * This driver uses the shared console driver in + * ...../libbsp/shared/console.c + * + * If you want the driver to be interrupt driven, you + * need to write the ISR, and in the ISR insert the + * chars into termios's queue. + * + * Copyright (c) 2004 Cogent Computer Systems + * Written by Jay Monkman + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. +*/ +#include /* Must be before libio.h */ +#include +#include +#include + +/* Put the CPU (or UART) specific header file #include here */ +#include +#include +#include + +/* How many serial ports? */ +#define NUM_DEVS 1 + +int uart_poll_read(int minor); + +int dbg_dly; + +/* static function prototypes */ +static int uart_first_open(int major, int minor, void *arg); +static int uart_last_close(int major, int minor, void *arg); +static int uart_read(int minor); +static ssize_t uart_write(int minor, const char *buf, size_t len); +static void uart_init(int minor); +static void uart_write_polled(int minor, char c); +static int uart_set_attributes(int minor, const struct termios *t); + +/* These are used by code in console.c */ +unsigned long Console_Configuration_Count = NUM_DEVS; + +/* Pointers to functions for handling the UART. */ +const console_fns uart_fns = +{ + libchip_serial_default_probe, + uart_first_open, + uart_last_close, + uart_read, + uart_write, + uart_init, + uart_write_polled, /* not used in this driver */ + uart_set_attributes, + FALSE /* TRUE if interrupt driven, FALSE if not. */ +}; + +/* + * There's one item in array for each UART. + * + * Some of these fields are marked "NOT USED". They are not used + * by console.c, but may be used by drivers in libchip + * + */ +console_tbl Console_Configuration_Ports[] = { + { + "/dev/com0", /* sDeviceName */ + SERIAL_CUSTOM, /* deviceType */ + &uart_fns, /* pDeviceFns */ + NULL, /* deviceProbe */ + NULL, /* pDeviceFlow */ + 0, /* ulMargin - NOT USED */ + 0, /* ulHysteresis - NOT USED */ + NULL, /* pDeviceParams */ + 0, /* ulCtrlPort1 - NOT USED */ + 0, /* ulCtrlPort2 - NOT USED */ + 0, /* ulDataPort - NOT USED */ + NULL, /* getRegister - NOT USED */ + NULL, /* setRegister - NOT USED */ + NULL, /* getData - NOT USED */ + NULL, /* setData - NOT USED */ + 0, /* ulClock - NOT USED */ + 0 /* ulIntVector - NOT USED */ + } +}; + +/*********************************************************************/ +/* Functions called via termios callbacks (i.e. the ones in uart_fns */ +/*********************************************************************/ + +/* + * This is called the first time each device is opened. If the driver + * is interrupt driven, you should enable interrupts here. Otherwise, + * it's probably safe to do nothing. + * + * Since micromonitor already set up the UART, we do nothing. + */ +static int uart_first_open(int major, int minor, void *arg) +{ + return 0; +} + + +/* + * This is called the last time each device is closed. If the driver + * is interrupt driven, you should disable interrupts here. Otherwise, + * it's probably safe to do nothing. + */ +static int uart_last_close(int major, int minor, void *arg) +{ + return 0; +} + + +/* + * Read one character from UART. + * + * Return -1 if there's no data, otherwise return + * the character in lowest 8 bits of returned int. + */ +static int uart_read(int minor) +{ + char c; + + if (minor == 0) { + if (rUTRSTAT0 & 0x1) { + c = rURXH0 & 0xff; + return c; + } else { + return -1; + } + } else { + printk("Unknown console minor number: %d\n", minor); + return -1; + } + +} + + +/* + * Write buffer to UART + * + * return 1 on success, -1 on error + */ +static ssize_t uart_write(int minor, const char *buf, size_t len) +{ + int i; + + if (minor == 0) { + for (i = 0; i < len; i++) { + /* Wait for fifo to have room */ + while(!(rUTRSTAT0 & 0x2)) { + continue; + } + + rUTXH0 = (char) buf[i]; + } + } else { + printk("Unknown console minor number: %d\n", minor); + return -1; + } + + return 1; +} + + +/* Set up the UART. */ +static void uart_init(int minor) +{ + int i; + unsigned int reg = 0; + + /* enable UART0 */ + rCLKCON|=0x100; + + /* value is calculated so : (int)(PCLK/16./baudrate) -1 */ + reg = get_PCLK() / (16 * 115200) - 1; + + /* FIFO enable, Tx/Rx FIFO clear */ + rUFCON0 = 0x07; + rUMCON0 = 0x0; + /* Normal,No parity,1 stop,8 bit */ + rULCON0 = 0x3; + /* + * tx=level,rx=edge,disable timeout int.,enable rx error int., + * normal,interrupt or polling + */ + rUCON0 = 0x245; + rUBRDIV0 = reg; + + for (i = 0; i < 100; i++); + +} + +/* I'm not sure this is needed for the shared console driver. */ +static void uart_write_polled(int minor, char c) +{ + uart_write(minor, &c, 1); +} + +/* This is for setting baud rate, bits, etc. */ +static int uart_set_attributes(int minor, const struct termios *t) +{ + return 0; +} + +/***********************************************************************/ +/* + * The following functions are not used by TERMIOS, but other RTEMS + * functions use them instead. + */ +/***********************************************************************/ +/* + * Read from UART. This is used in the exit code, and can't + * rely on interrupts. +*/ +int uart_poll_read(int minor) +{ + return uart_read(minor); +} + + +/* + * Write a character to the console. This is used by printk() and + * maybe other low level functions. It should not use interrupts or any + * RTEMS system calls. It needs to be very simple + */ +static void _BSP_put_char( char c ) { + uart_write_polled(0, c); +} + +BSP_output_char_function_type BSP_output_char = _BSP_put_char; + +static int _BSP_get_char(void) +{ + return uart_poll_read(0); +} + +BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char; diff --git a/bsps/arm/stm32f4/console/console-config.c b/bsps/arm/stm32f4/console/console-config.c new file mode 100644 index 0000000000..6bf2d7e3b5 --- /dev/null +++ b/bsps/arm/stm32f4/console/console-config.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2012 Sebastian Huber. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include + +#include +#include +#include +#include + +console_tbl Console_Configuration_Ports [] = { + #ifdef STM32F4_ENABLE_USART_1 + { + .sDeviceName = "/dev/ttyS0", + .deviceType = SERIAL_CUSTOM, + .pDeviceFns = &stm32f4_usart_fns, + .ulCtrlPort1 = (uint32_t) STM32F4_USART_1, + .ulCtrlPort2 = 0, + .ulClock = STM32F4_USART_BAUD, + .ulIntVector = STM32F4_IRQ_USART1 + }, + #endif + #ifdef STM32F4_ENABLE_USART_2 + { + .sDeviceName = "/dev/ttyS1", + .deviceType = SERIAL_CUSTOM, + .pDeviceFns = &stm32f4_usart_fns, + .ulCtrlPort1 = (uint32_t) STM32F4_USART_2, + .ulCtrlPort2 = 1, + .ulClock = STM32F4_USART_BAUD, + .ulIntVector = STM32F4_IRQ_USART2 + }, + #endif + #ifdef STM32F4_ENABLE_USART_3 + { + .sDeviceName = "/dev/ttyS2", + .deviceType = SERIAL_CUSTOM, + .pDeviceFns = &stm32f4_usart_fns, + .ulCtrlPort1 = (uint32_t) STM32F4_USART_3, + .ulCtrlPort2 = 2, + .ulClock = STM32F4_USART_BAUD, + .ulIntVector = STM32F4_IRQ_USART3 + }, + #endif + #ifdef STM32F4_ENABLE_UART_4 + { + .sDeviceName = "/dev/ttyS3", + .deviceType = SERIAL_CUSTOM, + .pDeviceFns = &stm32f4_usart_fns, + .ulCtrlPort1 = (uint32_t) STM32F4_USART_4, + .ulCtrlPort2 = 3, + .ulClock = STM32F4_USART_BAUD, + .ulIntVector = STM32F4_IRQ_UART4 + }, + #endif + #ifdef STM32F4_ENABLE_UART_5 + { + .sDeviceName = "/dev/ttyS4", + .deviceType = SERIAL_CUSTOM, + .pDeviceFns = &stm32f4_usart_fns, + .ulCtrlPort1 = (uint32_t) STM32F4_USART_5, + .ulCtrlPort2 = 4, + .ulClock = STM32F4_USART_BAUD, + .ulIntVector = STM32F4_IRQ_UART5 + }, + #endif + #ifdef STM32F4_ENABLE_USART_6 + { + .sDeviceName = "/dev/ttyS5", + .deviceType = SERIAL_CUSTOM, + .pDeviceFns = &stm32f4_usart_fns, + .ulCtrlPort1 = (uint32_t) STM32F4_USART_6, + .ulCtrlPort2 = 5, + .ulClock = STM32F4_USART_BAUD, + .ulIntVector = STM32F4_IRQ_USART6 + }, + #endif +}; + +#define PORT_COUNT \ + (sizeof(Console_Configuration_Ports) \ + / sizeof(Console_Configuration_Ports [0])) + +unsigned long Console_Configuration_Count = PORT_COUNT; + +static void output_char(char c) +{ + const console_fns *con = + Console_Configuration_Ports [Console_Port_Minor].pDeviceFns; + + con->deviceWritePolled((int) Console_Port_Minor, c); +} + +BSP_output_char_function_type BSP_output_char = output_char; + +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/arm/stm32f4/console/usart.c b/bsps/arm/stm32f4/console/usart.c new file mode 100644 index 0000000000..24e010d6bf --- /dev/null +++ b/bsps/arm/stm32f4/console/usart.c @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2012 Sebastian Huber. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include +#include +#include +#include +#include +#include + +static volatile stm32f4_usart *usart_get_regs(const console_tbl *ct) +{ + return (stm32f4_usart *) ct->ulCtrlPort1; +} + +#if 0 +static rtems_vector_number usart_get_irq_number(const console_tbl *ct) +{ + return ct->ulIntVector; +} +#endif + +static const stm32f4_rcc_index usart_rcc_index [] = { + STM32F4_RCC_USART1, + STM32F4_RCC_USART2, + STM32F4_RCC_USART3, + STM32F4_RCC_UART4, + STM32F4_RCC_UART5, +#ifdef STM32F4_FAMILY_F4XXXX + STM32F4_RCC_USART6 +#endif /* STM32F4_FAMILY_F4XXXX */ +}; + +static stm32f4_rcc_index usart_get_rcc_index(const console_tbl *ct) +{ + return usart_rcc_index [ct->ulCtrlPort2]; +} + +static const uint8_t usart_pclk_index [] = { 1, 0, 0, 0, 0, 1 }; + +static const uint32_t usart_pclk_by_index [] = { + STM32F4_PCLK1, + STM32F4_PCLK2 +}; + +static uint32_t usart_get_pclk(const console_tbl *ct) +{ + return usart_pclk_by_index [usart_pclk_index [ct->ulCtrlPort2]]; +} + +static uint32_t usart_get_baud(const console_tbl *ct) +{ + return ct->ulClock; +} + +/* + * a = 8 * (2 - CR1[OVER8]) + * + * usartdiv = div_mantissa + div_fraction / a + * + * baud = pclk / (a * usartdiv) + * + * usartdiv = pclk / (a * baud) + * + * Calculation in integer arithmetic: + * + * 1. div_mantissa = pclk / (a * baud) + * + * 2. div_fraction = pclk / (baud - a * div_mantissa) + */ +static uint32_t usart_get_bbr( + volatile stm32f4_usart *usart, + uint32_t pclk, + uint32_t baud +) +{ + uint32_t a = 8 * (2 - ((usart->cr1 & STM32F4_USART_CR1_OVER8) != 0)); + uint32_t div_mantissa_low = pclk / (a * baud); + uint32_t div_fraction_low = pclk / (baud - a * div_mantissa_low); + uint32_t div_mantissa_high; + uint32_t div_fraction_high; + uint32_t high_err; + uint32_t low_err; + uint32_t div_mantissa; + uint32_t div_fraction; + + if (div_fraction_low < a - 1) { + div_mantissa_high = div_fraction_low; + div_fraction_high = div_fraction_low + 1; + } else { + div_mantissa_high = div_fraction_low + 1; + div_fraction_high = 0; + } + + high_err = pclk - baud * (a * div_mantissa_high + div_fraction_high); + low_err = baud * (a * div_mantissa_low + div_fraction_low) - pclk; + + if (low_err < high_err) { + div_mantissa = div_mantissa_low; + div_fraction = div_fraction_low; + } else { + div_mantissa = div_mantissa_high; + div_fraction = div_fraction_high; + } + + return STM32F4_USART_BBR_DIV_MANTISSA(div_mantissa) + | STM32F4_USART_BBR_DIV_FRACTION(div_fraction); +} + +static void usart_initialize(int minor) +{ + const console_tbl *ct = Console_Port_Tbl [minor]; + volatile stm32f4_usart *usart = usart_get_regs(ct); + uint32_t pclk = usart_get_pclk(ct); + uint32_t baud = usart_get_baud(ct); + stm32f4_rcc_index rcc_index = usart_get_rcc_index(ct); + + stm32f4_rcc_set_clock(rcc_index, true); + + usart->cr1 = 0; + usart->cr2 = 0; + usart->cr3 = 0; + usart->bbr = usart_get_bbr(usart, pclk, baud); + usart->cr1 = STM32F4_USART_CR1_UE + | STM32F4_USART_CR1_TE + | STM32F4_USART_CR1_RE; +} + +static int usart_first_open(int major, int minor, void *arg) +{ + rtems_libio_open_close_args_t *oc = (rtems_libio_open_close_args_t *) arg; + struct rtems_termios_tty *tty = (struct rtems_termios_tty *) oc->iop->data1; + const console_tbl *ct = Console_Port_Tbl [minor]; + console_data *cd = &Console_Port_Data [minor]; + + cd->termios_data = tty; + rtems_termios_set_initial_baud(tty, ct->ulClock); + + return 0; +} + +static int usart_last_close(int major, int minor, void *arg) +{ + return 0; +} + +static int usart_read_polled(int minor) +{ + const console_tbl *ct = Console_Port_Tbl [minor]; + volatile stm32f4_usart *usart = usart_get_regs(ct); + + if ((usart->sr & STM32F4_USART_SR_RXNE) != 0) { + return STM32F4_USART_DR_GET(usart->dr); + } else { + return -1; + } +} + +static void usart_write_polled(int minor, char c) +{ + const console_tbl *ct = Console_Port_Tbl [minor]; + volatile stm32f4_usart *usart = usart_get_regs(ct); + + while ((usart->sr & STM32F4_USART_SR_TXE) == 0) { + /* Wait */ + } + + usart->dr = STM32F4_USART_DR(c); +} + +static ssize_t usart_write_support_polled( + int minor, + const char *s, + size_t n +) +{ + ssize_t i = 0; + + for (i = 0; i < n; ++i) { + usart_write_polled(minor, s [i]); + } + + return n; +} + +static int usart_set_attributes(int minor, const struct termios *term) +{ + return -1; +} + +const console_fns stm32f4_usart_fns = { + .deviceProbe = libchip_serial_default_probe, + .deviceFirstOpen = usart_first_open, + .deviceLastClose = usart_last_close, + .deviceRead = usart_read_polled, + .deviceWrite = usart_write_support_polled, + .deviceInitialize = usart_initialize, + .deviceWritePolled = usart_write_polled, + .deviceSetAttributes = usart_set_attributes, + .deviceOutputUsesInterrupts = false +}; diff --git a/bsps/arm/tms570/console/printk-support.c b/bsps/arm/tms570/console/printk-support.c new file mode 100644 index 0000000000..529c5dba20 --- /dev/null +++ b/bsps/arm/tms570/console/printk-support.c @@ -0,0 +1,126 @@ +/** + * @file printk-support.c + * + * @ingroup tms570 + * + * @brief definitions of serial line for debugging. + */ + +/* + * Copyright (c) 2014 Premysl Houdek + * + * Google Summer of Code 2014 at + * Czech Technical University in Prague + * Zikova 1903/4 + * 166 36 Praha 6 + * Czech Republic + * + * Based on LPC24xx and LPC1768 BSP + * by embedded brains GmbH and others + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include + +#define TMS570_CONSOLE (&driver_context_table[0]) + +/** + * @brief Puts chars into peripheral + * + * debug functions always use serial dev 0 peripheral + * + * @retval Void + */ +static void tms570_debug_console_putc(char ch) +{ + tms570_sci_context *ctx = TMS570_CONSOLE; + volatile tms570_sci_t *regs = ctx->regs; + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + while ( ( regs->FLR & TMS570_SCI_FLR_TXRDY ) == 0) { + rtems_interrupt_flash(level); + } + regs->TD = ch; + while ( ( regs->FLR & TMS570_SCI_FLR_TX_EMPTY ) == 0) { + rtems_interrupt_flash(level); + } + rtems_interrupt_enable(level); +} + +/** + * @brief debug console output + * + * debug functions always use serial dev 0 peripheral + * + * @retval Void + */ +static void tms570_debug_console_out(char c) +{ + tms570_debug_console_putc(c); +} + +static void tms570_debug_console_init(void) +{ + tms570_sci_context *ctx = TMS570_CONSOLE; + struct termios term; + + tms570_sci_initialize(ctx); + memset(&term, 0, sizeof(term)); + term.c_cflag = B115200; + tms570_sci_set_attributes(&ctx->base, &term); + BSP_output_char = tms570_debug_console_out; +} + +static void tms570_debug_console_early_init(char c) +{ + tms570_debug_console_init(); + tms570_debug_console_out(c); +} + +/** + * @brief debug console input + * + * debug functions always use serial dev 0 peripheral + * + * @retval x Read char + * @retval -1 No input character available + */ +static int tms570_debug_console_in( void ) +{ + tms570_sci_context *ctx = TMS570_CONSOLE; + volatile tms570_sci_t *regs = ctx->regs; + rtems_interrupt_level level; + int c; + + rtems_interrupt_disable(level); + + if ( regs->FLR & TMS570_SCI_FLR_RXRDY ) { + c = (unsigned char) regs->RD; + } else { + c = -1; + } + + rtems_interrupt_enable(level); + + return c; +} + +BSP_output_char_function_type BSP_output_char = + tms570_debug_console_early_init; + +BSP_polling_getchar_function_type BSP_poll_char = tms570_debug_console_in; + +RTEMS_SYSINIT_ITEM( + tms570_debug_console_init, + RTEMS_SYSINIT_BSP_START, + RTEMS_SYSINIT_ORDER_LAST +); diff --git a/bsps/arm/tms570/console/tms570-sci.c b/bsps/arm/tms570/console/tms570-sci.c new file mode 100644 index 0000000000..48986e9a2e --- /dev/null +++ b/bsps/arm/tms570/console/tms570-sci.c @@ -0,0 +1,642 @@ +/** + * @file tms570-sci.c + * + * @ingroup tms570 + * + * @brief Serial communication interface (SCI) functions definitions. + */ + +/* + * Copyright (c) 2014 Premysl Houdek + * + * Google Summer of Code 2014 at + * Czech Technical University in Prague + * Zikova 1903/4 + * 166 36 Praha 6 + * Czech Republic + * + * Based on LPC24xx and LPC1768 BSP + * by embedded brains GmbH and others + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TMS570_SCI_BUFFER_SIZE 1 + +/** + * @brief Table including all serial drivers + * + * Definitions of all serial drivers + */ +tms570_sci_context driver_context_table[] = { + { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("TMS570 SCI1"), + .device_name = "/dev/console", + /* TMS570 UART peripheral use subset of LIN registers which are equivalent + * to SCI ones + */ + .regs = (volatile tms570_sci_t *) &TMS570_LIN, + .irq = TMS570_IRQ_SCI_LEVEL_0, + }, + { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("TMS570 SCI2"), + .device_name = "/dev/ttyS1", + .regs = &TMS570_SCI, + .irq = TMS570_IRQ_SCI2_LEVEL_0, + } +}; + +void tms570_sci_initialize(tms570_sci_context *ctx) +{ + uint32_t rx_pin = 1 << 1; + uint32_t tx_pin = 1 << 2; + + /* Resec SCI peripheral */ + ctx->regs->GCR0 = TMS570_SCI_GCR0_RESET * 0; + ctx->regs->GCR0 = TMS570_SCI_GCR0_RESET * 1; + + /* Clear all interrupt sources */ + ctx->regs->CLEARINT = 0xffffffff; + + /* Map all interrupts to SCI INT0 line */ + ctx->regs->CLEARINTLVL = 0xffffffff; + + ctx->regs->GCR1 = TMS570_SCI_GCR1_TXENA * 0 | + TMS570_SCI_GCR1_RXENA * 0 | + TMS570_SCI_GCR1_CONT * 0 | /* continue operation when debugged */ + TMS570_SCI_GCR1_LOOP_BACK * 0 | + TMS570_SCI_GCR1_POWERDOWN * 0 | + TMS570_SCI_GCR1_SLEEP * 0 | + TMS570_SCI_GCR1_SWnRST * 0 | /* reset state */ + TMS570_SCI_GCR1_CLOCK * 1 | /* internal clock */ + TMS570_SCI_GCR1_TIMING_MODE * 1 | + TMS570_SCI_GCR1_COMM_MODE * 0; + + /* Setup connection of SCI peripheral Rx and Tx pins */ + ctx->regs->PIO0 = rx_pin * 1 | tx_pin * 1; /* Rx and Tx pins are not GPIO */ + ctx->regs->PIO3 = rx_pin * 0 | tx_pin * 0; /* Default output low */ + ctx->regs->PIO1 = rx_pin * 0 | tx_pin * 0; /* Input when not used by SCI */ + ctx->regs->PIO6 = rx_pin * 0 | tx_pin * 0; /* No open drain */ + ctx->regs->PIO7 = rx_pin * 0 | tx_pin * 0; /* Pull-up/down enabled */ + ctx->regs->PIO8 = rx_pin * 1 | tx_pin * 1; /* Select pull-up */ + + /* Bring device out of software reset */ + ctx->regs->GCR1 |= TMS570_SCI_GCR1_SWnRST; +} + +/** + * @brief Serial drivers init function + * + * Initialize all serial drivers specified in driver_context_table + * + * @param[in] major + * @param[in] minor + * @param[in] arg + * @retval RTEMS_SUCCESSFUL Initialization completed + */ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code sc; +#if CONSOLE_USE_INTERRUPTS + const rtems_termios_device_handler *handler = &tms570_sci_handler_interrupt; +#else + const rtems_termios_device_handler *handler = &tms570_sci_handler_polled; +#endif + + /* + * Initialize the Termios infrastructure. If Termios has already + * been initialized by another device driver, then this call will + * have no effect. + */ + rtems_termios_initialize(); + + /* Initialize each device */ + for ( + minor = 0; + minor < RTEMS_ARRAY_SIZE(driver_context_table); + ++minor + ) { + tms570_sci_context *ctx = &driver_context_table[minor]; + + tms570_sci_initialize(ctx); + + /* + * Install this device in the file system and Termios. In order + * to use the console (i.e. being able to do printf, scanf etc. + * on stdin, stdout and stderr), one device must be registered as + * "/dev/console" (CONSOLE_DEVICE_NAME). + */ + sc = rtems_termios_device_install( + ctx->device_name, + handler, + NULL, + &ctx->base + ); + if ( sc != RTEMS_SUCCESSFUL ) { + bsp_fatal(BSP_FATAL_CONSOLE_NO_DEV); + } + } + return RTEMS_SUCCESSFUL; +} + +/** + * @brief Reads chars from HW + * + * Reads chars from HW peripheral specified in driver context. + * TMS570 does not have HW buffer for serial line so this function can + * return only 0 or 1 char + * + * @param[in] ctx context of the driver + * @param[out] buf read data buffer + * @param[in] N size of buffer + * @retval x Number of read chars from peripherals + */ +static int tms570_sci_read_received_chars( + tms570_sci_context * ctx, + char * buf, + int N) +{ + if ( N < 1 ) { + return 0; + } + if ( ctx->regs->RD != 0 ) { + buf[0] = ctx->regs->RD; + return 1; + } + return 0; +} + +/** + * @brief Enables RX interrupt + * + * Enables RX interrupt source of SCI peripheral + * specified in the driver context. + * + * @param[in] ctx context of the driver + * @retval Void + */ +static void tms570_sci_enable_interrupts(tms570_sci_context * ctx) +{ + ctx->regs->SETINT = TMS570_SCI_SETINT_SET_RX_INT; +} + +/** + * @brief Disables RX interrupt + * + * Disables RX interrupt source of SCI peripheral specified in the driver + * context. + * + * @param[in] ctx context of the driver + * @retval Void + */ +static void tms570_sci_disable_interrupts(tms570_sci_context * ctx) +{ + ctx->regs->CLEARINT = TMS570_SCI_CLEARINT_CLR_RX_INT; +} + +/** + * @brief Check whether driver has put char in HW + * + * Check whether driver has put char in HW. + * This information is read from the driver context not from a peripheral. + * TMS570 does not have write data buffer asociated with SCI + * so the return can be only 0 or 1. + * + * @param[in] ctx context of the driver + * @retval x + */ +static int tms570_sci_transmitted_chars(tms570_sci_context * ctx) +{ + int ret; + + ret = ctx->tx_chars_in_hw; + if ( ret == 1 ) { + ctx->tx_chars_in_hw = 0; + return 1; + } + return ret; +} + +/** + * @brief Set attributes of the HW peripheral + * + * Sets attributes of the HW peripheral (parity, baud rate, etc.) + * + * @param[in] base context of the driver + * @param[in] t termios driver + * @retval true peripheral setting is changed + */ +bool tms570_sci_set_attributes( + rtems_termios_device_context *base, + const struct termios *t +) +{ + tms570_sci_context *ctx = (tms570_sci_context *) base; + rtems_interrupt_lock_context lock_context; + int32_t bauddiv; + int32_t baudrate; + uint32_t flr_tx_ready = TMS570_SCI_FLR_TX_EMPTY; + /* + * Test for TMS570_SCI_FLR_TXRDY is not necessary + * because both SCITD and SCITXSHF has to be empty + * to TX_EMPTY be asserted. But there is no interrupt + * option for TX_EMPTY. Polling is used isntead. + */ + + /* Baud rate */ + baudrate = rtems_termios_baud_to_number(cfgetospeed(t)); + + rtems_termios_device_lock_acquire(base, &lock_context); + + while ( (ctx->regs->GCR1 & TMS570_SCI_GCR1_TXENA) && + (ctx->regs->FLR & flr_tx_ready) != flr_tx_ready) { + /* + * There are pending characters in the hardware, + * change in the middle of the character Tx leads + * to disturb of the character and SCI engine + */ + rtems_interval tw; + + rtems_termios_device_lock_release(base, &lock_context); + + tw = rtems_clock_get_ticks_per_second(); + tw = tw * 5 / baudrate + 1; + rtems_task_wake_after( tw ); + + rtems_termios_device_lock_acquire(base, &lock_context); + } + + ctx->regs->GCR1 &= ~( TMS570_SCI_GCR1_SWnRST | TMS570_SCI_GCR1_TXENA | + TMS570_SCI_GCR1_RXENA ); + + ctx->regs->GCR1 &= ~TMS570_SCI_GCR1_STOP; /*one stop bit*/ + ctx->regs->FORMAT = TMS570_SCI_FORMAT_CHAR(0x7); + + switch ( t->c_cflag & ( PARENB|PARODD ) ) { + case ( PARENB|PARODD ): + /* Odd parity */ + ctx->regs->GCR1 &= ~TMS570_SCI_GCR1_PARITY; + ctx->regs->GCR1 |= TMS570_SCI_GCR1_PARITY_ENA; + break; + + case PARENB: + /* Even parity */ + ctx->regs->GCR1 |= TMS570_SCI_GCR1_PARITY; + ctx->regs->GCR1 |= TMS570_SCI_GCR1_PARITY_ENA; + break; + + default: + case 0: + case PARODD: + /* No Parity */ + ctx->regs->GCR1 &= ~TMS570_SCI_GCR1_PARITY_ENA; + } + + /* Apply baudrate to the hardware */ + baudrate *= 2 * 16; + bauddiv = (BSP_PLL_OUT_CLOCK + baudrate / 2) / baudrate; + ctx->regs->BRS = bauddiv; + + ctx->regs->GCR1 |= TMS570_SCI_GCR1_SWnRST | TMS570_SCI_GCR1_TXENA | + TMS570_SCI_GCR1_RXENA; + + rtems_termios_device_lock_release(base, &lock_context); + + return true; +} + +/** + * @brief sci interrupt handler + * + * Handler checks which interrupt occured and provides nessesary maintenance + * dequeue characters in termios driver whether character is send succesfully + * enqueue characters in termios driver whether character is recieved + * + * @param[in] arg rtems_termios_tty + * @retval Void + */ +static void tms570_sci_interrupt_handler(void * arg) +{ + rtems_termios_tty *tty = arg; + tms570_sci_context *ctx = rtems_termios_get_device_context(tty); + char buf[TMS570_SCI_BUFFER_SIZE]; + size_t n; + + /* + * Check if we have received something. + */ + if ( (ctx->regs->FLR & TMS570_SCI_FLR_RXRDY ) == TMS570_SCI_FLR_RXRDY ) { + n = tms570_sci_read_received_chars(ctx, buf, TMS570_SCI_BUFFER_SIZE); + if ( n > 0 ) { + /* Hand the data over to the Termios infrastructure */ + rtems_termios_enqueue_raw_characters(tty, buf, n); + } + } + /* + * Check if we have something transmitted. + */ + if ( (ctx->regs->FLR & TMS570_SCI_FLR_TXRDY ) == TMS570_SCI_FLR_TXRDY ) { + n = tms570_sci_transmitted_chars(ctx); + if ( n > 0 ) { + /* + * Notify Termios that we have transmitted some characters. It + * will call now the interrupt write function if more characters + * are ready for transmission. + */ + rtems_termios_dequeue_characters(tty, n); + } + } +} + +/** + * @brief sci write function called from interrupt + * + * Nonblocking write function. Writes characters to HW peripheral + * TMS570 does not have write data buffer asociated with SCI + * so only one character can be written. + * + * @param[in] base context of the driver + * @param[in] buf buffer of characters pending to send + * @param[in] len size of the buffer + * @retval Void + */ +static void tms570_sci_interrupt_write( + rtems_termios_device_context *base, + const char *buf, + size_t len +) +{ + tms570_sci_context *ctx = (tms570_sci_context *) base; + + if ( len > 0 ) { + /* start UART TX, this will result in an interrupt when done */ + ctx->regs->TD = *buf; + /* character written - raise count*/ + ctx->tx_chars_in_hw = 1; + /* Enable TX interrupt (interrupt is edge-triggered) */ + ctx->regs->SETINT = (1<<8); + + } else { + /* No more to send, disable TX interrupts */ + ctx->regs->CLEARINT = (1<<8); + /* Tell close that we sent everything */ + } +} + +/** + * @brief sci write function + * + * Blocking write function. Waits until HW peripheral is ready and then writes + * character to HW peripheral. Writes all characters in the buffer. + * + * @param[in] base context of the driver + * @param[in] buf buffer of characters pending to send + * @param[in] len size of the buffer + * @retval Void + */ +static void tms570_sci_poll_write( + rtems_termios_device_context *base, + const char *buf, + size_t n +) +{ + tms570_sci_context *ctx = (tms570_sci_context *) base; + size_t i; + + /* Write */ + + for ( i = 0; i < n; ++i ) { + while ( (ctx->regs->FLR & TMS570_SCI_FLR_TX_EMPTY ) == 0) { + ; + } + ctx->regs->TD = buf[i]; + } +} + +/** + * @brief See if there is recieved charakter to read + * + * read the RX flag from peripheral specified in context + * + * @param[in] ctx context of the driver + * @retval 0 No character to read + * @retval x Character ready to read + */ +static int TMS570_sci_can_read_char( + tms570_sci_context * ctx +) +{ + return ctx->regs->FLR & TMS570_SCI_FLR_RXRDY; +} + +/** + * @brief reads character from peripheral + * + * reads the recieved character from peripheral specified in context + * + * @param[in] ctx context of the driver + * @retval x Character + */ +static char TMS570_sci_read_char( + tms570_sci_context * ctx +) +{ + return ctx->regs->RD; +} + +/** + * @brief sci read function + * + * check if there is recieved character to be read and reads it. + * + * @param[in] base context of the driver + * @retval -1 No character to be read + * @retval x Read character + */ +static int tms570_sci_poll_read(rtems_termios_device_context *base) +{ + tms570_sci_context *ctx = (tms570_sci_context *) base; + + /* Check if a character is available */ + if ( TMS570_sci_can_read_char(ctx) ) { + return TMS570_sci_read_char(ctx); + } else { + return -1; + } +} + +/** + * @brief initialization of the driver + * + * initialization of the HW peripheral specified in contex of the driver. + * This function is called only once when opening the driver. + * + * @param[in] tty Termios control + * @param[in] ctx context of the driver + * @param[in] term Termios attributes + * @param[in] args + * @retval false Error occured during initialization + * @retval true Driver is open and ready + */ +static bool tms570_sci_poll_first_open( + rtems_termios_tty *tty, + rtems_termios_device_context *ctx, + struct termios *term, + rtems_libio_open_close_args_t *args +) +{ + bool ok; + + rtems_termios_set_best_baud(term, TMS570_SCI_BAUD_RATE); + ok = tms570_sci_set_attributes(ctx, term); + if ( !ok ) { + return false; + } + return true; +} + +/** + * @brief initialization of the interrupt driven driver + * + * calls tms570_sci_poll_first_open function. + * install and enables interrupts. + * + * @param[in] tty Termios control + * @param[in] base context of the driver + * @param[in] args + * @retval false Error occured during initialization + * @retval true Driver is open and ready + */ +static bool tms570_sci_interrupt_first_open( + rtems_termios_tty *tty, + rtems_termios_device_context *base, + struct termios *term, + rtems_libio_open_close_args_t *args +) +{ + tms570_sci_context *ctx = (tms570_sci_context *) base; + rtems_status_code sc; + bool ret; + + ret = tms570_sci_poll_first_open(tty, base, term, args); + if ( ret == false ) { + return false; + } + + /* Register Interrupt handler */ + sc = rtems_interrupt_handler_install(ctx->irq, + ctx->device_name, + RTEMS_INTERRUPT_SHARED, + tms570_sci_interrupt_handler, + tty + ); + if ( sc != RTEMS_SUCCESSFUL ) { + return false; + } + tms570_sci_enable_interrupts(ctx); + return true; +} + +/** + * @brief closes sci peripheral + * + * @param[in] tty Termios control + * @param[in] base context of the driver + * @param[in] args + * @retval false Error occured during initialization + * @retval true Driver is open and ready + */ +static void tms570_sci_poll_last_close( + rtems_termios_tty *tty, + rtems_termios_device_context *base, + rtems_libio_open_close_args_t *args +) +{ + ; +} + +/** + * @brief closes sci peripheral of interrupt driven driver + * + * calls tms570_sci_poll_last_close and disables interrupts + * + * @param[in] tty Termios control + * @param[in] base context of the driver + * @param[in] args + * @retval false Error occured during initialization + * @retval true Driver is open and ready + */ +static void tms570_sci_interrupt_last_close( + rtems_termios_tty *tty, + rtems_termios_device_context *base, + rtems_libio_open_close_args_t *args +) +{ + tms570_sci_context *ctx = (tms570_sci_context *) base; + rtems_interrupt_lock_context lock_context; + rtems_interval tw; + int32_t baudrate; + + /* Turn off RX interrupts */ + rtems_termios_device_lock_acquire(base, &lock_context); + tms570_sci_disable_interrupts(ctx); + rtems_termios_device_lock_release(base, &lock_context); + + tw = rtems_clock_get_ticks_per_second(); + baudrate = rtems_termios_baud_to_number(cfgetospeed(&tty->termios)); + tw = tw * 10 / baudrate + 1; + while ( ( ctx->regs->FLR & TMS570_SCI_FLR_TX_EMPTY ) == 0 ) { + rtems_task_wake_after(tw); + } + + /* uninstall ISR */ + rtems_interrupt_handler_remove(ctx->irq, tms570_sci_interrupt_handler, tty); + + tms570_sci_poll_last_close(tty, base, args); +} + +/** + * @brief Struct containing definitions of polled driver functions. + * + * Encapsulates polled driver functions. + * Use of this table is determited by not defining TMS570_USE_INTERRUPTS + */ +const rtems_termios_device_handler tms570_sci_handler_polled = { + .first_open = tms570_sci_poll_first_open, + .last_close = tms570_sci_poll_last_close, + .poll_read = tms570_sci_poll_read, + .write = tms570_sci_poll_write, + .set_attributes = tms570_sci_set_attributes, + .mode = TERMIOS_POLLED +}; + +/** + * @brief Struct containing definitions of interrupt driven driver functions. + * + * Encapsulates interrupt driven driver functions. + * Use of this table is determited by defining TMS570_USE_INTERRUPTS + */ +const rtems_termios_device_handler tms570_sci_handler_interrupt = { + .first_open = tms570_sci_interrupt_first_open, + .last_close = tms570_sci_interrupt_last_close, + .poll_read = NULL, + .write = tms570_sci_interrupt_write, + .set_attributes = tms570_sci_set_attributes, + .mode = TERMIOS_IRQ_DRIVEN +}; diff --git a/bsps/arm/xilinx-zynq/console/console-config.c b/bsps/arm/xilinx-zynq/console/console-config.c new file mode 100644 index 0000000000..ce7da2f114 --- /dev/null +++ b/bsps/arm/xilinx-zynq/console/console-config.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include + +#include +#include + +#include + +zynq_uart_context zynq_uart_instances[2] = { + { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 0" ), + .regs = (volatile struct zynq_uart *) 0xe0000000, + .irq = ZYNQ_IRQ_UART_0 + }, { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 1" ), + .regs = (volatile struct zynq_uart *) 0xe0001000, + .irq = ZYNQ_IRQ_UART_1 + } +}; + +rtems_status_code console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + size_t i; + + rtems_termios_initialize(); + + for (i = 0; i < RTEMS_ARRAY_SIZE(zynq_uart_instances); ++i) { + char uart[] = "/dev/ttySX"; + + uart[sizeof(uart) - 2] = (char) ('0' + i); + rtems_termios_device_install( + &uart[0], + &zynq_uart_handler, + NULL, + &zynq_uart_instances[i].base + ); + + if (i == BSP_CONSOLE_MINOR) { + link(&uart[0], CONSOLE_DEVICE_NAME); + } + } + + return RTEMS_SUCCESSFUL; +} diff --git a/bsps/arm/xilinx-zynq/console/debug-console.c b/bsps/arm/xilinx-zynq/console/debug-console.c new file mode 100644 index 0000000000..38c0050e90 --- /dev/null +++ b/bsps/arm/xilinx-zynq/console/debug-console.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include + +#include + +#include + +static void zynq_debug_console_out(char c) +{ + rtems_termios_device_context *base = + &zynq_uart_instances[BSP_CONSOLE_MINOR].base; + + zynq_uart_write_polled(base, c); +} + +static void zynq_debug_console_init(void) +{ + rtems_termios_device_context *base = + &zynq_uart_instances[BSP_CONSOLE_MINOR].base; + + zynq_uart_initialize(base); + BSP_output_char = zynq_debug_console_out; +} + +static void zynq_debug_console_early_init(char c) +{ + rtems_termios_device_context *base = + &zynq_uart_instances[BSP_CONSOLE_MINOR].base; + + zynq_uart_initialize(base); + zynq_debug_console_out(c); +} + +static int zynq_debug_console_in(void) +{ + rtems_termios_device_context *base = + &zynq_uart_instances[BSP_CONSOLE_MINOR].base; + + return zynq_uart_read_polled(base); +} + +BSP_output_char_function_type BSP_output_char = zynq_debug_console_early_init; + +BSP_polling_getchar_function_type BSP_poll_char = zynq_debug_console_in; + +RTEMS_SYSINIT_ITEM( + zynq_debug_console_init, + RTEMS_SYSINIT_BSP_START, + RTEMS_SYSINIT_ORDER_LAST +); diff --git a/bsps/arm/xilinx-zynq/console/zynq-uart.c b/bsps/arm/xilinx-zynq/console/zynq-uart.c new file mode 100644 index 0000000000..fa91f3f46e --- /dev/null +++ b/bsps/arm/xilinx-zynq/console/zynq-uart.c @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include + +#include + +/* + * Make weak and let the user override. + */ +uint32_t zynq_uart_input_clock(void) __attribute__ ((weak)); + +uint32_t zynq_uart_input_clock(void) +{ + return ZYNQ_CLOCK_UART; +} + +static int zynq_cal_baud_rate(uint32_t baudrate, + uint32_t* brgr, + uint32_t* bauddiv, + uint32_t modereg) +{ + uint32_t brgr_value; /* Calculated value for baud rate generator */ + uint32_t calcbaudrate; /* Calculated baud rate */ + uint32_t bauderror; /* Diff between calculated and requested baud rate */ + uint32_t best_error = 0xFFFFFFFF; + uint32_t percenterror; + uint32_t bdiv; + uint32_t inputclk = zynq_uart_input_clock(); + + /* + * Make sure the baud rate is not impossilby large. + * Fastest possible baud rate is Input Clock / 2. + */ + if ((baudrate * 2) > inputclk) { + return -1; + } + /* + * Check whether the input clock is divided by 8 + */ + if(modereg & ZYNQ_UART_MODE_CLKS) { + inputclk = inputclk / 8; + } + + /* + * Determine the Baud divider. It can be 4to 254. + * Loop through all possible combinations + */ + for (bdiv = 4; bdiv < 255; bdiv++) { + + /* + * Calculate the value for BRGR register + */ + brgr_value = inputclk / (baudrate * (bdiv + 1)); + + /* + * Calculate the baud rate from the BRGR value + */ + calcbaudrate = inputclk/ (brgr_value * (bdiv + 1)); + + /* + * Avoid unsigned integer underflow + */ + if (baudrate > calcbaudrate) { + bauderror = baudrate - calcbaudrate; + } + else { + bauderror = calcbaudrate - baudrate; + } + + /* + * Find the calculated baud rate closest to requested baud rate. + */ + if (best_error > bauderror) { + *brgr = brgr_value; + *bauddiv = bdiv; + best_error = bauderror; + } + } + + /* + * Make sure the best error is not too large. + */ + percenterror = (best_error * 100) / baudrate; +#define XUARTPS_MAX_BAUD_ERROR_RATE 3 /* max % error allowed */ + if (XUARTPS_MAX_BAUD_ERROR_RATE < percenterror) { + return -1; + } + + return 0; +} + +void zynq_uart_initialize(rtems_termios_device_context *base) +{ + zynq_uart_context *ctx = (zynq_uart_context *) base; + volatile zynq_uart *regs = ctx->regs; + uint32_t brgr = 0x3e; + uint32_t bauddiv = 0x6; + + zynq_cal_baud_rate(ZYNQ_UART_DEFAULT_BAUD, &brgr, &bauddiv, regs->mode); + + regs->control &= ~(ZYNQ_UART_CONTROL_RXEN | ZYNQ_UART_CONTROL_TXEN); + regs->control = ZYNQ_UART_CONTROL_RXDIS + | ZYNQ_UART_CONTROL_TXDIS + | ZYNQ_UART_CONTROL_RXRES + | ZYNQ_UART_CONTROL_TXRES; + regs->mode = ZYNQ_UART_MODE_CHMODE(ZYNQ_UART_MODE_CHMODE_NORMAL) + | ZYNQ_UART_MODE_PAR(ZYNQ_UART_MODE_PAR_NONE) + | ZYNQ_UART_MODE_CHRL(ZYNQ_UART_MODE_CHRL_8); + regs->baud_rate_gen = ZYNQ_UART_BAUD_RATE_GEN_CD(brgr); + regs->baud_rate_div = ZYNQ_UART_BAUD_RATE_DIV_BDIV(bauddiv); + regs->rx_fifo_trg_lvl = ZYNQ_UART_RX_FIFO_TRG_LVL_RTRIG(0); + regs->rx_timeout = ZYNQ_UART_RX_TIMEOUT_RTO(0); + regs->control = ZYNQ_UART_CONTROL_RXEN + | ZYNQ_UART_CONTROL_TXEN + | ZYNQ_UART_CONTROL_RSTTO; +} + +#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS +static void zynq_uart_interrupt(void *arg) +{ + rtems_termios_tty *tty = arg; + zynq_uart_context *ctx = rtems_termios_get_device_context(tty); + volatile zynq_uart *regs = ctx->regs; + uint32_t channel_sts; + + if ((regs->irq_sts & (ZYNQ_UART_TIMEOUT | ZYNQ_UART_RTRIG)) != 0) { + regs->irq_sts = ZYNQ_UART_TIMEOUT | ZYNQ_UART_RTRIG; + + do { + char c = (char) ZYNQ_UART_TX_RX_FIFO_FIFO_GET(regs->tx_rx_fifo); + + rtems_termios_enqueue_raw_characters(tty, &c, 1); + + channel_sts = regs->channel_sts; + } while ((channel_sts & ZYNQ_UART_CHANNEL_STS_REMPTY) == 0); + } else { + channel_sts = regs->channel_sts; + } + + if (ctx->transmitting && (channel_sts & ZYNQ_UART_CHANNEL_STS_TEMPTY) != 0) { + rtems_termios_dequeue_characters(tty, 1); + } +} +#endif + +static bool zynq_uart_first_open( + rtems_termios_tty *tty, + rtems_termios_device_context *base, + struct termios *term, + rtems_libio_open_close_args_t *args +) +{ +#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS + zynq_uart_context *ctx = (zynq_uart_context *) base; + volatile zynq_uart *regs = ctx->regs; + rtems_status_code sc; +#endif + + rtems_termios_set_initial_baud(tty, ZYNQ_UART_DEFAULT_BAUD); + zynq_uart_initialize(base); + +#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS + regs->rx_timeout = 32; + regs->rx_fifo_trg_lvl = ZYNQ_UART_FIFO_DEPTH / 2; + regs->irq_dis = 0xffffffff; + regs->irq_sts = 0xffffffff; + regs->irq_en = ZYNQ_UART_RTRIG | ZYNQ_UART_TIMEOUT; + sc = rtems_interrupt_handler_install( + ctx->irq, + "UART", + RTEMS_INTERRUPT_SHARED, + zynq_uart_interrupt, + tty + ); + if (sc != RTEMS_SUCCESSFUL) { + return false; + } +#endif + + return true; +} + +#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS +static void zynq_uart_last_close( + rtems_termios_tty *tty, + rtems_termios_device_context *base, + rtems_libio_open_close_args_t *args +) +{ + zynq_uart_context *ctx = (zynq_uart_context *) base; + + rtems_interrupt_handler_remove(ctx->irq, zynq_uart_interrupt, tty); +} +#endif + +int zynq_uart_read_polled(rtems_termios_device_context *base) +{ + zynq_uart_context *ctx = (zynq_uart_context *) base; + volatile zynq_uart *regs = ctx->regs; + + if ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_REMPTY) != 0) { + return -1; + } else { + return ZYNQ_UART_TX_RX_FIFO_FIFO_GET(regs->tx_rx_fifo); + } +} + +void zynq_uart_write_polled( + rtems_termios_device_context *base, + char c +) +{ + zynq_uart_context *ctx = (zynq_uart_context *) base; + volatile zynq_uart *regs = ctx->regs; + + while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TFUL) != 0) { + /* Wait */ + } + + regs->tx_rx_fifo = ZYNQ_UART_TX_RX_FIFO_FIFO(c); +} + +static void zynq_uart_write_support( + rtems_termios_device_context *base, + const char *buf, + size_t len +) +{ +#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS + zynq_uart_context *ctx = (zynq_uart_context *) base; + volatile zynq_uart *regs = ctx->regs; + + if (len > 0) { + ctx->transmitting = true; + regs->irq_sts = ZYNQ_UART_TEMPTY; + regs->irq_en = ZYNQ_UART_TEMPTY; + regs->tx_rx_fifo = ZYNQ_UART_TX_RX_FIFO_FIFO(buf[0]); + } else { + ctx->transmitting = false; + regs->irq_dis = ZYNQ_UART_TEMPTY; + } +#else + ssize_t i; + + for (i = 0; i < len; ++i) { + zynq_uart_write_polled(base, buf[i]); + } +#endif +} + +static bool zynq_uart_set_attributes( + rtems_termios_device_context *context, + const struct termios *term +) +{ +#if 0 + volatile zynq_uart *regs = zynq_uart_get_regs(minor); + uint32_t brgr = 0; + uint32_t bauddiv = 0; + int rc; + + rc = zynq_cal_baud_rate(115200, &brgr, &bauddiv, regs->mode); + if (rc != 0) + return rc; + + regs->control &= ~(ZYNQ_UART_CONTROL_RXEN | ZYNQ_UART_CONTROL_TXEN); + regs->baud_rate_gen = ZYNQ_UART_BAUD_RATE_GEN_CD(brgr); + regs->baud_rate_div = ZYNQ_UART_BAUD_RATE_DIV_BDIV(bauddiv); + regs->control |= ZYNQ_UART_CONTROL_RXEN | ZYNQ_UART_CONTROL_TXEN; + + return true; +#else + return false; +#endif +} + +const rtems_termios_device_handler zynq_uart_handler = { + .first_open = zynq_uart_first_open, + .set_attributes = zynq_uart_set_attributes, + .write = zynq_uart_write_support, +#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS + .last_close = zynq_uart_last_close, + .mode = TERMIOS_IRQ_DRIVEN +#else + .poll_read = zynq_uart_read_polled, + .mode = TERMIOS_POLLED +#endif +}; + +void zynq_uart_reset_tx_flush(zynq_uart_context *ctx) +{ + volatile zynq_uart *regs = ctx->regs; + int c = 4; + + while (c-- > 0) + zynq_uart_write_polled(&ctx->base, '\r'); + + while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TEMPTY) == 0) { + /* Wait */ + } +} diff --git a/bsps/bfin/TLL6527M/console/console.c b/bsps/bfin/TLL6527M/console/console.c new file mode 100644 index 0000000000..1871bdbb9d --- /dev/null +++ b/bsps/bfin/TLL6527M/console/console.c @@ -0,0 +1,181 @@ +/** + *@file console.c + * + *@brief + * - This file implements uart console for TLL6527M. TLL6527M has BF527 with + * second uart (uart-1) connected to the console. + * + * Target: TLL6527v1-0 + * Compiler: + * + * COPYRIGHT (c) 2010 by ECE Northeastern University. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license + * + * @author Rohan Kangralkar, ECE, Northeastern University + * (kangralkar.r@husky.neu.edu) + * + * LastChange: + */ + +#include +#include +#include +#include +#include + +#include +#include + +/*************************************************** +LOCAL DEFINES + ***************************************************/ + + +/*************************************************** +STATIC GLOBALS + ***************************************************/ +/** + * Declaration of UART + */ +static bfin_uart_channel_t channels[] = { + {"/dev/console", + UART1_BASE_ADDRESS, + DMA10_BASE_ADDRESS, + DMA11_BASE_ADDRESS, + CONSOLE_USE_INTERRUPTS, + UART_USE_DMA, + CONSOLE_BAUDRATE, + NULL, + 0, + 0} +}; + +/** + * Over all configuration + */ +static bfin_uart_config_t config = { + SCLK, + sizeof(channels) / sizeof(channels[0]), + channels +}; + + +#if CONSOLE_USE_INTERRUPTS +/** + * The Rx and Tx isr will get the same argument + * The isr will have to find if it was the rx that caused the interrupt or + * the tx + */ +static bfin_isr_t bfinUARTISRs[] = { +#if UART_USE_DMA + /* For First uart */ + {IRQ_DMA10_UART1_RX, bfinUart_rxDmaIsr, (void *)&channels[0], 0}, + {IRQ_DMA11_UART1_TX, bfinUart_txDmaIsr, (void *)&channels[0], 0}, + /* For second uart */ +#else + /* For First uart */ + {IRQ_DMA10_UART1_RX, bfinUart_rxIsr, &channels[0], 0}, + {IRQ_DMA11_UART1_TX, bfinUart_txIsr, &channels[0], 0}, + /* For second uart */ +#endif +}; +#endif + + +static void TLL6527_BSP_output_char(char c) { + + bfin_uart_poll_write(0, c); +} + +static int TLL6527_BSP_poll_char(void) { + + return bfin_uart_poll_read(0); +} + +BSP_output_char_function_type BSP_output_char = TLL6527_BSP_output_char; +BSP_polling_getchar_function_type BSP_poll_char = TLL6527_BSP_poll_char; + + + +rtems_device_driver console_close(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) { + + return rtems_termios_close(arg); +} + +rtems_device_driver console_read(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) { + + return rtems_termios_read(arg); +} + +rtems_device_driver console_write(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) { + + return rtems_termios_write(arg); +} + +rtems_device_driver console_control(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) { + + return rtems_termios_ioctl(arg); +} + + + +/* + * Open entry point + */ +rtems_device_driver console_open(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) { + + return bfin_uart_open(major, minor, arg); +} + + + +/** + * + * This routine initializes the console IO driver. + * + * Parameters + * @param major major number + * @param minor minor number + * + * Output parameters: NONE + * + * @return void + */ +rtems_device_driver console_initialize(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) { + rtems_status_code status = RTEMS_NOT_DEFINED; +#if CONSOLE_USE_INTERRUPTS + int i = 0; +#endif + + status = bfin_uart_initialize(major, &config); + if (status != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(status); + } + +#if CONSOLE_USE_INTERRUPTS + for (i = 0; i < sizeof(bfinUARTISRs) / sizeof(bfinUARTISRs[0]); i++) { + bfin_interrupt_register(&bfinUARTISRs[i]); +#if INTERRUPT_USE_TABLE +#else + bfin_interrupt_enable(&bfinUARTISRs[i], 1); +#endif + } +#endif + + return RTEMS_SUCCESSFUL; +} diff --git a/bsps/bfin/bf537Stamp/console/console.c b/bsps/bfin/bf537Stamp/console/console.c new file mode 100644 index 0000000000..e9fe24cda1 --- /dev/null +++ b/bsps/bfin/bf537Stamp/console/console.c @@ -0,0 +1,141 @@ +/* Console driver for bf537Stamp + */ + +/* + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + + +#include +#include +#include +#include +#include + +#include +#include +#include + +/* +#undef CONSOLE_USE_INTERRUPTS +#define CONSOLE_USE_INTERRUPTS 1 +*/ + +static bfin_uart_channel_t channels[] = { + {"/dev/console", + UART0_BASE_ADDRESS, + 0, + 0, + CONSOLE_USE_INTERRUPTS, + 0, + #ifdef CONSOLE_FORCE_BAUD + CONSOLE_FORCE_BAUD, + #else + 0, + #endif + NULL, + 0, + 0} + +#if (!BFIN_ON_SKYEYE) +, + {"/dev/tty1", + UART1_BASE_ADDRESS, + CONSOLE_USE_INTERRUPTS, + 0, + NULL, + 0} +#endif +}; + +static bfin_uart_config_t config = { + SCLK, + sizeof(channels) / sizeof(channels[0]), + channels +}; + +#if CONSOLE_USE_INTERRUPTS +static bfin_isr_t bfinUARTISRs[] = { + {SIC_DMA8_UART0_RX_VECTOR, bfinUart_rxIsr, 0, 0, NULL}, + {SIC_DMA10_UART1_RX_VECTOR, bfinUart_rxIsr, 0, 0, NULL}, + {SIC_DMA9_UART0_TX_VECTOR, bfinUart_txIsr, 0, 0, NULL}, + {SIC_DMA11_UART1_TX_VECTOR, bfinUart_txIsr, 0, 0, NULL} +}; +#endif + + +static void bf537Stamp_BSP_output_char(char c) { + + bfin_uart_poll_write(0, c); +} + +static int bf537Stamp_BSP_poll_char(void) { + + return bfin_uart_poll_read(0); +} + +BSP_output_char_function_type BSP_output_char = bf537Stamp_BSP_output_char; +BSP_polling_getchar_function_type BSP_poll_char = bf537Stamp_BSP_poll_char; + +rtems_device_driver console_initialize(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) { + rtems_status_code status; +#if CONSOLE_USE_INTERRUPTS + int i; +#endif + + status = bfin_uart_initialize(major, &config); +#if CONSOLE_USE_INTERRUPTS + for (i = 0; i < sizeof(bfinUARTISRs) / sizeof(bfinUARTISRs[0]); i++) { + bfin_interrupt_register(&bfinUARTISRs[i]); + bfin_interrupt_enable(&bfinUARTISRs[i], TRUE); + } +#endif + + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + return RTEMS_SUCCESSFUL; +} + +rtems_device_driver console_open(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) { + + return bfin_uart_open(major, minor, arg); +} + +rtems_device_driver console_close(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) { + + return rtems_termios_close(arg); +} + +rtems_device_driver console_read(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) { + + return rtems_termios_read(arg); +} + +rtems_device_driver console_write(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) { + + return rtems_termios_write(arg); +} + +rtems_device_driver console_control(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) { + + return rtems_termios_ioctl(arg); +} + diff --git a/bsps/bfin/eZKit533/console/console-io.c b/bsps/bfin/eZKit533/console/console-io.c new file mode 100644 index 0000000000..5bafb3a094 --- /dev/null +++ b/bsps/bfin/eZKit533/console/console-io.c @@ -0,0 +1,126 @@ +/* console-io.c + * + * This file contains the hardware specific portions of the TTY driver + * for the serial ports for ezkit533. + * + * Copyright (c) 2006 by Atos Automacao Industrial Ltda. + * written by Alain Schaefer + * and Antonio Giovanini + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + + +#include +#include +#include +#include +#include + +#include +#include +#include + +static bfin_uart_channel_t channels[] = { + {"/dev/console", + UART0_BASE_ADDRESS, + 0, + 0, + CONSOLE_USE_INTERRUPTS, + 0, +#ifdef CONSOLE_FORCE_BAUD + CONSOLE_FORCE_BAUD, +#else + 0, +#endif + NULL, + 0, + 0} +}; + +static bfin_uart_config_t config = { + SCLK, + sizeof(channels) / sizeof(channels[0]), + channels +}; + +#if CONSOLE_USE_INTERRUPTS +static bfin_isr_t bfinUARTISRs[] = { + {SIC_DMA6_UART0_RX_VECTOR, bfinUart_rxIsr, 0, 0, NULL}, + {SIC_DMA7_UART0_TX_VECTOR, bfinUart_txIsr, 0, 0, NULL}, +}; +#endif + + +static void eZKit533_BSP_output_char(char c) { + + bfin_uart_poll_write(0, c); +} + +static int eZKit533_BSP_poll_char(void) { + + return bfin_uart_poll_read(0); +} + +BSP_output_char_function_type BSP_output_char = eZKit533_BSP_output_char; +BSP_polling_getchar_function_type BSP_poll_char = eZKit533_BSP_poll_char; + +rtems_device_driver console_initialize(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) { + rtems_status_code status; +#if CONSOLE_USE_INTERRUPTS + int i; +#endif + + status = bfin_uart_initialize(major, &config); +#if CONSOLE_USE_INTERRUPTS + for (i = 0; i < sizeof(bfinUARTISRs) / sizeof(bfinUARTISRs[0]); i++) { + bfin_interrupt_register(&bfinUARTISRs[i]); + bfin_interrupt_enable(&bfinUARTISRs[i], TRUE); + } +#endif + + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + return RTEMS_SUCCESSFUL; +} + +rtems_device_driver console_open(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) { + + return bfin_uart_open(major, minor, arg); +} + +rtems_device_driver console_close(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) { + + return rtems_termios_close(arg); +} + +rtems_device_driver console_read(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) { + + return rtems_termios_read(arg); +} + +rtems_device_driver console_write(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) { + + return rtems_termios_write(arg); +} + +rtems_device_driver console_control(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) { + + return rtems_termios_ioctl(arg); +} + diff --git a/bsps/epiphany/epiphany_sim/console/console-io.c b/bsps/epiphany/epiphany_sim/console/console-io.c new file mode 100644 index 0000000000..e3da54389f --- /dev/null +++ b/bsps/epiphany/epiphany_sim/console/console-io.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2015 University of York. + * Hesham ALMatary + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +static void outbyte_console( char ); +static char inbyte_console( void ); + +void console_initialize_hardware(void) +{ + /* Do nothing */ +} + +/* Epiphany simulator would handle this system call */ +static void outbyte_console(char c) +{ + register int chan asm("r0") = STDOUT_FILENO; + register void* addr asm("r1") = &c; + register int len asm("r2") = 1; + + /* Invoke write system call to be handled by Epiphany simulator */ + __asm__ __volatile__ ("trap 0" : : "r" (chan), "r" (addr), "r" (len)); +} + +static char inbyte_console(void) +{ + char c; + register int chan asm("r0") = STDIN_FILENO; + register void* addr asm("r1") = &c; + register int len asm("r2") = 1; + + /* Invoke read system call to be handled by Epiphany simulator */ + asm ("trap 1" :: "r" (chan), "r" (addr), "r" (len)); + return c; +} + +/* + * console_outbyte_polled + * + * This routine transmits a character using polling. + */ +void console_outbyte_polled( + int port, + char ch +) +{ + outbyte_console( ch ); +} + +/* + * console_inbyte_nonblocking + * + * This routine polls for a character. + */ + +int console_inbyte_nonblocking(int port) +{ + char c; + + c = inbyte_console(); + if (!c) + return -1; + return (int) c; +} + +/* + * To support printk + */ + +#include + +static void Epiphany_output_char(char c) { console_outbyte_polled( 0, c ); } + +BSP_output_char_function_type BSP_output_char = Epiphany_output_char; +BSP_polling_getchar_function_type BSP_poll_char = + (void *)console_inbyte_nonblocking; diff --git a/bsps/i386/pc386/console/conscfg.c b/bsps/i386/pc386/console/conscfg.c new file mode 100644 index 0000000000..a4ae88626f --- /dev/null +++ b/bsps/i386/pc386/console/conscfg.c @@ -0,0 +1,198 @@ +/** + * @file + * + * This file contains the libchip configuration information + * to instantiate the libchip driver for the VGA console + * and serial ports on a PC. + */ + +/* + * COPYRIGHT (c) 1989-2014, 2016. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#if BSP_ENABLE_VGA +#include +#endif +#include +#include "../../shared/dev/serial/legacy-console.h" + +#if BSP_ENABLE_VGA +#define VGA_CONSOLE_FUNCTIONS &vgacons_fns +#endif + +#if BSP_ENABLE_COM1_COM4 + #if 0 + #define COM_CONSOLE_FUNCTIONS &ns16550_fns_polled + #else + #define COM_CONSOLE_FUNCTIONS &ns16550_fns + #endif + + /* + * Base IO for UART + */ + #define COM1_BASE_IO 0x3F8 + #define COM2_BASE_IO 0x3E8 + #define COM3_BASE_IO 0x2F8 + #define COM4_BASE_IO 0x2E8 + + #define CLOCK_RATE (115200 * 16) + + static uint8_t com_get_register(uint32_t addr, uint8_t i) + { + register uint8_t val; + + inport_byte( (addr + i), val ); + return val; + } + + static void com_set_register(uint32_t addr, uint8_t i, uint8_t val) + { + outport_byte( (addr + i), val ); + } +#endif + +/* + * Default to the PC VGA console if present and configured. + */ +console_tbl Console_Configuration_Ports[] = { +#if BSP_ENABLE_VGA + /* + * If present the VGA console must always be minor 0. + * See console_control. + */ + { + "/dev/vgacons", /* sDeviceName */ + VGA_CONSOLE, /* deviceType */ + VGA_CONSOLE_FUNCTIONS, /* pDeviceFns */ + vgacons_probe, /* deviceProbe */ + NULL, /* pDeviceFlow */ + 16, /* ulMargin */ + 8, /* ulHysteresis */ + (void *) NULL, /* NULL */ /* pDeviceParams */ + 0x00000000, /* ulCtrlPort1 */ + 0x00000000, /* ulCtrlPort2 */ + 0x00000000, /* ulDataPort */ + NULL, /* getRegister */ + NULL, /* setRegister */ + NULL,/* unused */ /* getData */ + NULL,/* unused */ /* setData */ + 0x0, /* ulClock */ + 0x0 /* ulIntVector -- base for port */ + }, +#endif +}; + +unsigned long Console_Configuration_Count = + (sizeof(Console_Configuration_Ports)/sizeof(console_tbl)); + +static console_tbl Legacy_Ports[] = { +#if BSP_ENABLE_COM1_COM4 + { + "/dev/com1", /* sDeviceName */ + SERIAL_NS16550, /* deviceType */ + COM_CONSOLE_FUNCTIONS, /* pDeviceFns */ + NULL, /* deviceProbe */ + NULL, /* pDeviceFlow */ + 16, /* ulMargin */ + 8, /* ulHysteresis */ + (void *) 9600, /* Baud Rate */ /* pDeviceParams */ + COM1_BASE_IO, /* ulCtrlPort1 */ + 0x00000000, /* ulCtrlPort2 */ + COM1_BASE_IO, /* ulDataPort */ + com_get_register, /* getRegister */ + com_set_register, /* setRegister */ + NULL,/* unused */ /* getData */ + NULL,/* unused */ /* setData */ + CLOCK_RATE, /* ulClock */ + BSP_UART_COM1_IRQ /* ulIntVector -- base for port */ + }, + { + "/dev/com2", /* sDeviceName */ + SERIAL_NS16550, /* deviceType */ + COM_CONSOLE_FUNCTIONS, /* pDeviceFns */ + NULL, /* deviceProbe */ + NULL, /* pDeviceFlow */ + 16, /* ulMargin */ + 8, /* ulHysteresis */ + (void *) 9600, /* Baud Rate */ /* pDeviceParams */ + COM2_BASE_IO, /* ulCtrlPort1 */ + 0x00000000, /* ulCtrlPort2 */ + COM2_BASE_IO, /* ulDataPort */ + com_get_register, /* getRegister */ + com_set_register, /* setRegister */ + NULL,/* unused */ /* getData */ + NULL,/* unused */ /* setData */ + CLOCK_RATE, /* ulClock */ + BSP_UART_COM2_IRQ /* ulIntVector -- base for port */ + }, + { + "/dev/com3", /* sDeviceName */ + SERIAL_NS16550, /* deviceType */ + COM_CONSOLE_FUNCTIONS, /* pDeviceFns */ + NULL, /* deviceProbe */ + NULL, /* pDeviceFlow */ + 16, /* ulMargin */ + 8, /* ulHysteresis */ + (void *) 9600, /* Baud Rate */ /* pDeviceParams */ + COM3_BASE_IO, /* ulCtrlPort1 */ + 0x00000000, /* ulCtrlPort2 */ + COM3_BASE_IO, /* ulDataPort */ + com_get_register, /* getRegister */ + com_set_register, /* setRegister */ + NULL,/* unused */ /* getData */ + NULL,/* unused */ /* setData */ + CLOCK_RATE, /* ulClock */ + BSP_UART_COM3_IRQ /* ulIntVector -- base for port */ + }, + { + "/dev/com4", /* sDeviceName */ + SERIAL_NS16550, /* deviceType */ + COM_CONSOLE_FUNCTIONS, /* pDeviceFns */ + NULL, /* deviceProbe */ + NULL, /* pDeviceFlow */ + 16, /* ulMargin */ + 8, /* ulHysteresis */ + (void *) 9600, /* Baud Rate */ /* pDeviceParams */ + COM4_BASE_IO, /* ulCtrlPort1 */ + 0x00000000, /* ulCtrlPort2 */ + COM4_BASE_IO, /* ulDataPort */ + com_get_register, /* getRegister */ + com_set_register, /* setRegister */ + NULL,/* unused */ /* getData */ + NULL,/* unused */ /* setData */ + CLOCK_RATE, /* ulClock */ + BSP_UART_COM4_IRQ /* ulIntVector -- base for port */ + }, +#endif +}; + +#define Legacy_Port_Count \ + (sizeof(Legacy_Ports)/sizeof(console_tbl)) + +void legacy_uart_probe(void) +{ +#if BSP_ENABLE_COM1_COM4 + const char *opt; + /* + * Check the command line to see if com1-com4 are disabled. + */ + opt = bsp_cmdline_arg("--disable-com1-com4"); + if ( opt ) { + printk( "COM1-COM4: disabled\n" ); + } else { + if (Legacy_Port_Count) { + printk("Legacy UART Ports: COM1-COM4\n"); + console_register_devices( Legacy_Ports, Legacy_Port_Count ); + } + } +#endif +} diff --git a/bsps/i386/pc386/console/console_control.c b/bsps/i386/pc386/console/console_control.c new file mode 100644 index 0000000000..a04ae2bc3b --- /dev/null +++ b/bsps/i386/pc386/console/console_control.c @@ -0,0 +1,71 @@ +/* + * This file is an extension of the generic console driver + * shell used by all console drivers using libchip, it contains + * the console_control routine, This bsp needs its own version + * of this method to handle the keyboard and mouse as a single + * device. + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#if BSP_ENABLE_VGA +#include +#endif +#include "../../shared/dev/serial/legacy-console.h" + +/* + * console_control + * + * this routine uses the termios driver to process io + */ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ +#if BSP_ENABLE_VGA + if (minor == 0) { + rtems_libio_ioctl_args_t *args = arg; + + switch (args->command) { + default: + if( vt_ioctl( args->command, (unsigned long)args->buffer ) != 0 ) + return rtems_termios_ioctl (arg); + break; + + case MW_UID_REGISTER_DEVICE: + printk( "SerialMouse: reg=%s\n", (const char*) args->buffer ); + register_kbd_msg_queue( args->buffer, 0 ); + break; + + case MW_UID_UNREGISTER_DEVICE: + unregister_kbd_msg_queue( 0 ); + break; + } + + args->ioctl_return = 0; + return RTEMS_SUCCESSFUL; + } +#endif + return rtems_termios_ioctl (arg); +} diff --git a/bsps/i386/pc386/console/console_select.c b/bsps/i386/pc386/console/console_select.c new file mode 100644 index 0000000000..1c064fb271 --- /dev/null +++ b/bsps/i386/pc386/console/console_select.c @@ -0,0 +1,250 @@ +/** + * @file + * + * @ingroup Console + * + * @brief pc386 console select + * + * This file contains a routine to select the console based upon a number + * of criteria. + */ + +/* + * COPYRIGHT (c) 2011-2012, 2016. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "../../shared/dev/serial/legacy-console.h" +#ifdef RTEMS_RUNTIME_CONSOLE_SELECT + #include +#endif + +/* + * Method to return true if the device associated with the + * minor number probs available. + */ +static bool bsp_Is_Available( rtems_device_minor_number minor ) +{ + console_tbl *cptr = Console_Port_Tbl[minor]; + + /* + * First perform the configuration dependent probe, then the + * device dependent probe + */ + if ((!cptr->deviceProbe || cptr->deviceProbe(minor)) && + cptr->pDeviceFns->deviceProbe(minor)) { + return true; + } + return false; +} + +/* + * Method to return the first available device. + */ +static rtems_device_minor_number bsp_First_Available_Device( void ) +{ + rtems_device_minor_number minor; + + for (minor=0; minor < Console_Port_Count ; minor++) { + console_tbl *cptr = Console_Port_Tbl[minor]; + + /* + * First perform the configuration dependent probe, then the + * device dependent probe + */ + + if ((!cptr->deviceProbe || cptr->deviceProbe(minor)) && + cptr->pDeviceFns->deviceProbe(minor)) { + return minor; + } + } + + /* + * Error No devices were found. We will want to bail here. + */ + rtems_fatal_error_occurred(RTEMS_IO_ERROR); +} + +static bool parse_printk_or_console( + const char *param, + rtems_device_minor_number *minor_out +) +{ + static const char *opt; + const char *option; + const char *comma; + size_t length; + size_t index; + rtems_device_minor_number minor; + console_tbl *conscfg; + + /* + * Check the command line for the type of mode the console is. + */ + opt = bsp_cmdline_arg(param); + if ( !opt ) { + return false; + } + + /* + * Fine the length, there can be more command line visible. + */ + length = 0; + while ((opt[length] != ' ') && (opt[length] != '\0')) { + ++length; + if (length > NAME_MAX) { + printk("invalid option (%s): too long\n", param); + return false; + } + } + + /* + * Only match up to a comma or NULL + */ + index = 0; + while ((opt[index] != '=') && (index < length)) { + ++index; + } + + if (opt[index] != '=') { + printk("invalid option (%s): no equals\n", param); + return false; + } + + ++index; + option = &opt[index]; + + while ((opt[index] != ',') && (index < length)) { + ++index; + } + + if (opt[index] == ',') + comma = &opt[index]; + else + comma = NULL; + + length = &opt[index] - option; + + conscfg = console_find_console_entry( option, length, &minor ); + if ( conscfg == NULL ) { + return false; + } + + *minor_out = minor; + if (comma) { + option = comma + 1; + if (strncmp (option, "115200", sizeof ("115200") - 1) == 0) + conscfg->pDeviceParams = (void *)115200; + else if (strncmp (option, "57600", sizeof ("57600") - 1) == 0) + conscfg->pDeviceParams = (void *)57600; + else if (strncmp (option, "38400", sizeof ("38400") - 1) == 0) + conscfg->pDeviceParams = (void *)38400; + else if (strncmp (option, "19200", sizeof ("19200") - 1) == 0) + conscfg->pDeviceParams = (void *)19200; + else if (strncmp (option, "9600", sizeof ("9600") - 1) == 0) + conscfg->pDeviceParams = (void *)9600; + else if (strncmp (option, "4800", sizeof ("4800") - 1) == 0) + conscfg->pDeviceParams = (void *)4800; + } + + return true; +} + +/* + * Helper to retrieve device name + */ +static inline const char *get_name( + rtems_device_minor_number minor +) +{ + return Console_Port_Tbl[minor]->sDeviceName; +} + +/* + * Parse the arguments early so the printk and console ports are + * set appropriately. + */ +void pc386_parse_console_arguments(void) +{ + rtems_device_minor_number minor; + rtems_device_minor_number minor_console = 0; + rtems_device_minor_number minor_printk = 0; + + /* + * Assume that if only --console is specified, that printk() should + * follow that selection by default. + */ + if ( parse_printk_or_console( "--console=", &minor ) ) { + minor_console = minor; + minor_printk = minor; + } + + /* + * But if explicitly specified, attempt to honor it. + */ + if ( parse_printk_or_console( "--printk=", &minor ) ) { + minor_printk = minor; + } + + printk( "Console: %s printk: %s\n", + get_name(minor_console),get_name(minor_printk) ); + + /* + * Any output after this can cause problems until termios is initialised. + */ + Console_Port_Minor = minor_console; + BSPPrintkPort = minor_printk; +} + +/* + * This handles the selection of the console after the devices are + * initialized. + */ +void bsp_console_select(void) +{ + #ifdef RTEMS_RUNTIME_CONSOLE_SELECT + /* + * WARNING: This code is really needed any more and should be removed. + * references to COM1 and COM2 like they are wrong. + */ + if ( BSP_runtime_console_select ) + BSP_runtime_console_select(&BSPPrintkPort, &Console_Port_Minor); + + /* + * If no video card, fall back to serial port console + */ + if((Console_Port_Minor == BSP_CONSOLE_VGA) + && (*(unsigned char*) NB_MAX_ROW_ADDR == 0) + && (*(unsigned short*)NB_MAX_COL_ADDR == 0)) { + Console_Port_Minor = BSP_CONSOLE_COM2; + BSPPrintkPort = BSP_CONSOLE_COM1; + } + #endif + + /* + * If the device that was selected isn't available then + * let the user know and select the first available device. + */ + if ( !bsp_Is_Available( Console_Port_Minor ) ) { + printk( + "Error finding %s setting console to first available\n", + get_name(Console_Port_Minor) + ); + Console_Port_Minor = bsp_First_Available_Device(); + } +} diff --git a/bsps/i386/pc386/console/defkeymap.c b/bsps/i386/pc386/console/defkeymap.c new file mode 100644 index 0000000000..a6bf5103a1 --- /dev/null +++ b/bsps/i386/pc386/console/defkeymap.c @@ -0,0 +1,262 @@ +/* Do not edit this file! It was automatically generated by */ +/* loadkeys --mktable defkeymap.map > defkeymap.c */ + +#include +#include +#include + +u_short plain_map[NR_KEYS] = { + 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, + 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b, + 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +u_short shift_map[NR_KEYS] = { + 0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, + 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, + 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, + 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53, + 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a, + 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, + 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e, + 0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +u_short altgr_map[NR_KEYS] = { + 0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200, + 0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200, + 0xfb71, 0xfb77, 0xf918, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201, 0xf702, 0xf914, 0xfb73, + 0xf917, 0xf919, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf200, + 0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xf916, 0xfb76, + 0xf915, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c, + 0xf703, 0xf200, 0xf207, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911, + 0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b, + 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +u_short ctrl_map[NR_KEYS] = { + 0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e, + 0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf200, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf204, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +u_short shift_ctrl_map[NR_KEYS] = { + 0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c, + 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +u_short alt_map[NR_KEYS] = { + 0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, + 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, + 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, + 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, + 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, + 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, + 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf907, + 0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901, + 0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +u_short ctrl_alt_map[NR_KEYS] = { + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c, + 0xf703, 0xf200, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf200, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +ushort *key_maps[MAX_NR_KEYMAPS] = { + plain_map, shift_map, altgr_map, 0, + ctrl_map, shift_ctrl_map, 0, 0, + alt_map, 0, 0, 0, + ctrl_alt_map, 0 +}; + +unsigned int keymap_count = 7; + +/* + * Philosophy: most people do not define more strings, but they who do + * often want quite a lot of string space. So, we statically allocate + * the default and allocate dynamically in chunks of 512 bytes. + */ + +char func_buf[] = { + '\033', '[', '[', 'A', 0, + '\033', '[', '[', 'B', 0, + '\033', '[', '[', 'C', 0, + '\033', '[', '[', 'D', 0, + '\033', '[', '[', 'E', 0, + '\033', '[', '1', '7', '~', 0, + '\033', '[', '1', '8', '~', 0, + '\033', '[', '1', '9', '~', 0, + '\033', '[', '2', '0', '~', 0, + '\033', '[', '2', '1', '~', 0, + '\033', '[', '2', '3', '~', 0, + '\033', '[', '2', '4', '~', 0, + '\033', '[', '2', '5', '~', 0, + '\033', '[', '2', '6', '~', 0, + '\033', '[', '2', '8', '~', 0, + '\033', '[', '2', '9', '~', 0, + '\033', '[', '3', '1', '~', 0, + '\033', '[', '3', '2', '~', 0, + '\033', '[', '3', '3', '~', 0, + '\033', '[', '3', '4', '~', 0, + '\033', '[', '1', '~', 0, + '\033', '[', '2', '~', 0, + '\033', '[', '3', '~', 0, + '\033', '[', '4', '~', 0, + '\033', '[', '5', '~', 0, + '\033', '[', '6', '~', 0, + '\033', '[', 'M', 0, + '\033', '[', 'P', 0, +}; + +char *funcbufptr = func_buf; +int funcbufsize = sizeof(func_buf); +int funcbufleft = 0; /* space left */ + +char *func_table[MAX_NR_FUNC] = { + func_buf + 0, + func_buf + 5, + func_buf + 10, + func_buf + 15, + func_buf + 20, + func_buf + 25, + func_buf + 31, + func_buf + 37, + func_buf + 43, + func_buf + 49, + func_buf + 55, + func_buf + 61, + func_buf + 67, + func_buf + 73, + func_buf + 79, + func_buf + 85, + func_buf + 91, + func_buf + 97, + func_buf + 103, + func_buf + 109, + func_buf + 115, + func_buf + 120, + func_buf + 125, + func_buf + 130, + func_buf + 135, + func_buf + 140, + func_buf + 145, + 0, + 0, + func_buf + 149, + 0, +}; + +struct kbdiacr accent_table[MAX_DIACR] = { + {'`', 'A', '\300'}, {'`', 'a', '\340'}, + {'\'', 'A', '\301'}, {'\'', 'a', '\341'}, + {'^', 'A', '\302'}, {'^', 'a', '\342'}, + {'~', 'A', '\303'}, {'~', 'a', '\343'}, + {'"', 'A', '\304'}, {'"', 'a', '\344'}, + {'O', 'A', '\305'}, {'o', 'a', '\345'}, + {'0', 'A', '\305'}, {'0', 'a', '\345'}, + {'A', 'A', '\305'}, {'a', 'a', '\345'}, + {'A', 'E', '\306'}, {'a', 'e', '\346'}, + {',', 'C', '\307'}, {',', 'c', '\347'}, + {'`', 'E', '\310'}, {'`', 'e', '\350'}, + {'\'', 'E', '\311'}, {'\'', 'e', '\351'}, + {'^', 'E', '\312'}, {'^', 'e', '\352'}, + {'"', 'E', '\313'}, {'"', 'e', '\353'}, + {'`', 'I', '\314'}, {'`', 'i', '\354'}, + {'\'', 'I', '\315'}, {'\'', 'i', '\355'}, + {'^', 'I', '\316'}, {'^', 'i', '\356'}, + {'"', 'I', '\317'}, {'"', 'i', '\357'}, + {'-', 'D', '\320'}, {'-', 'd', '\360'}, + {'~', 'N', '\321'}, {'~', 'n', '\361'}, + {'`', 'O', '\322'}, {'`', 'o', '\362'}, + {'\'', 'O', '\323'}, {'\'', 'o', '\363'}, + {'^', 'O', '\324'}, {'^', 'o', '\364'}, + {'~', 'O', '\325'}, {'~', 'o', '\365'}, + {'"', 'O', '\326'}, {'"', 'o', '\366'}, + {'/', 'O', '\330'}, {'/', 'o', '\370'}, + {'`', 'U', '\331'}, {'`', 'u', '\371'}, + {'\'', 'U', '\332'}, {'\'', 'u', '\372'}, + {'^', 'U', '\333'}, {'^', 'u', '\373'}, + {'"', 'U', '\334'}, {'"', 'u', '\374'}, + {'\'', 'Y', '\335'}, {'\'', 'y', '\375'}, + {'T', 'H', '\336'}, {'t', 'h', '\376'}, + {'s', 's', '\337'}, {'"', 'y', '\377'}, + {'s', 'z', '\337'}, {'i', 'j', '\377'}, +}; + +unsigned int accent_table_size = 68; diff --git a/bsps/i386/pc386/console/exar17d15x.c b/bsps/i386/pc386/console/exar17d15x.c new file mode 100644 index 0000000000..5cf615ac86 --- /dev/null +++ b/bsps/i386/pc386/console/exar17d15x.c @@ -0,0 +1,224 @@ +/** + * @file + * + * @brief Driver for Exar XR17D15x Multiport UARTs + * + * This driver supports 2, 4 or 8 port Exar parts which are NS16550 + * compatible. + */ + +/* + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "../../shared/dev/serial/legacy-console.h" + +#define MAX_BOARDS 4 + +/* + * This is the rate for the clock internal to the parts. + */ +#define EXAR_CLOCK_RATE (921600*16) + +/* + * Supported PCI Ids + */ +#define PCI_VENDOR_ID_EXAR 0x13A8 +#define PCI_VENDOR_ID_EXAR_XR17D158 0x0158 +#define PCI_VENDOR_ID_EXAR_XR17D154 0x0154 +#define PCI_VENDOR_ID_EXAR_XR17D152 0x0152 + +/* + * Structure to manage each instance found. + */ +typedef struct { + uint16_t vendor; + uint16_t device; + uint8_t ports; +} exar_parts_t; + +static exar_parts_t Supported[] = { + { PCI_VENDOR_ID_EXAR, PCI_VENDOR_ID_EXAR_XR17D158, 8 }, + { PCI_VENDOR_ID_EXAR, PCI_VENDOR_ID_EXAR_XR17D154, 4 }, + { PCI_VENDOR_ID_EXAR, PCI_VENDOR_ID_EXAR_XR17D152, 2 }, + { 0, 0, 0 } +}; + +/* + * Information saved from PCI scan + */ +typedef struct { + bool found; + uint32_t base; + uint8_t irq; + uint8_t bus; + uint8_t slot; + uint8_t ports; +} exar17d15x_conf_t; + +/* + * Register Access Routines + */ +static uint8_t xr17d15x_get_register(uint32_t addr, uint8_t i) +{ + uint8_t val = 0; + volatile uint8_t *reg = (volatile uint8_t *)(addr + i); + + val = *reg; + // printk( "RD %p -> 0x%02x\n", reg, val ); + return val; +} + +static void xr17d15x_set_register(uint32_t addr, uint8_t i, uint8_t val) +{ + volatile uint8_t *reg = (volatile uint8_t *)(addr + i); + + // printk( "WR %p <- 0x%02x\n", reg, val ); + *reg = val; +} + +rtems_device_driver exar17d15x_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor_arg, + void *arg +) +{ + // int pbus, pdev, pfun; + exar17d15x_conf_t conf[MAX_BOARDS]; + int boards = 0; + int b = 0; + int p; + console_tbl *ports; + console_tbl *port_p; + int pbus; + int pdev; + int pfun; + int status; + int instance; + int i; + int total_ports = 0; + + for ( b=0 ; bsDeviceName = strdup( name ); + port_p->deviceType = SERIAL_NS16550; + #if 1 + port_p->pDeviceFns = &ns16550_fns_polled; + #else + port_p->pDeviceFns = &ns16550_fns; + #endif + + port_p->deviceProbe = NULL; + port_p->pDeviceFlow = NULL; + port_p->ulMargin = 16; + port_p->ulHysteresis = 8; + port_p->pDeviceParams = (void *) 9600; + port_p->ulCtrlPort1 = conf[b].base + (p * 0x0200); + port_p->ulCtrlPort2 = 0; /* NA */ + port_p->ulDataPort = 0; /* NA */ + port_p->getRegister = xr17d15x_get_register; + port_p->setRegister = xr17d15x_set_register; + port_p->getData = NULL; /* NA */ + port_p->setData = NULL; /* NA */ + port_p->ulClock = EXAR_CLOCK_RATE; + port_p->ulIntVector = conf[b].irq; + + port_p++; + } /* end ports */ + } /* end boards */ + + /* + * Register the devices + */ + if ( boards ) + console_register_devices( ports, total_ports ); + + return RTEMS_SUCCESSFUL; +} diff --git a/bsps/i386/pc386/console/fb_cirrus.c b/bsps/i386/pc386/console/fb_cirrus.c new file mode 100644 index 0000000000..bb05b5a338 --- /dev/null +++ b/bsps/i386/pc386/console/fb_cirrus.c @@ -0,0 +1,766 @@ +/* + * FB driver for Cirrus GD5446 graphic hardware. + * Tested to be compatible with QEMU GD5446 emulation but not on real HW. + * + * Copyright (c) 2012 - Alexandru-Sever Horin (alex.sever.h@gmail.com). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + * The code is based on next information sources: + * - CL-GD5446 Technical Reference Manual, 1996, Second Edition + * - RTEMS fb_vga.c - Rosimildo da Silva ( rdasilva@connecttel.com ) + * - Cirrus xf86 driver - used as VGA hardware setup sequence documentation + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +/* flag to limit driver to protect against multiple opens */ +static Atomic_Flag driver_mutex; + +/* screen information for the VGA driver + * standard structures + */ +static struct fb_var_screeninfo fb_var; +static struct fb_fix_screeninfo fb_fix; + +#define CIRRUS_VENDOR_ID 0x1013 +#define CIRRUS_GD5446_DEVICE_ID 0x00b8 + +typedef struct _DisplayModeRec { + struct _DisplayModeRec *prev; + struct _DisplayModeRec *next; + char *name; /* identifier for the mode */ + int type; + + /* These are the values that the user sees/provides */ + int Clock; /* pixel clock freq (kHz) */ + int HDisplay; /* horizontal timing */ + int HSyncStart; + int HSyncEnd; + int HTotal; + int HSkew; + int VDisplay; /* vertical timing */ + int VSyncStart; + int VSyncEnd; + int VTotal; + int VScan; + int Flags; + + /* These are the values the hardware uses */ + int ClockIndex; + int SynthClock; /* Actual clock freq to + * be programmed (kHz) */ + int CrtcHDisplay; + int CrtcHBlankStart; + int CrtcHSyncStart; + int CrtcHSyncEnd; + int CrtcHBlankEnd; + int CrtcHTotal; + int CrtcHSkew; + int CrtcVDisplay; + int CrtcVBlankStart; + int CrtcVSyncStart; + int CrtcVSyncEnd; + int CrtcVBlankEnd; + int CrtcVTotal; + int CrtcHAdjusted; + int CrtcVAdjusted; + int PrivSize; + int32_t *Private; + int PrivFlags; + + float HSync, VRefresh; +} DisplayModeRec, *DisplayModePtr; + +static DisplayModeRec available_modes[] = { + { + .Clock = 31500 , + .HDisplay = 640 , + .HSyncStart = 664 , + .HSyncEnd = 704 , + .HTotal = 832 , + .HSkew = 0 , + .VDisplay = 480 , /* vertical timing */ + .VSyncStart = 489 , + .VSyncEnd = 491 , + .VTotal = 520 , + .VScan = 0, + .Flags = 0 + }, + { + .Clock = 40000 , + .HDisplay = 800 , + .HSyncStart = 840 , + .HSyncEnd = 968 , + .HTotal = 1056 , + .HSkew = 0 , + .VDisplay = 600 , /* vertical timing */ + .VSyncStart = 601 , + .VSyncEnd = 605 , + .VTotal = 628 , + .VScan = 0, + .Flags = 0 + }, +}; +static DisplayModePtr active_mode; + +/* The display mode used for the board hardcoded in the following define + * Index in above structure + */ +#define CIRRUS_DISPLAY_MODE 0 + +/* The display bytes per pixel used for the board hardcoded in the following define + * Index in above structure + */ +#define CIRRUS_DEFAULT_BPP 24 + +/* cirrus board information */ +struct cirrus_board_str{ + int pci_bus; + int pci_device; + int pci_function; + void *reg_base; +}; + +static struct cirrus_board_str cirrus_board_info; + +/* + * get information from the board + */ +static int +cirrus_pci_read( struct cirrus_board_str *cirrus_board, uint32_t *mem_base, uint32_t *cirrus_register_base) +{ + int r; + + r = pci_read_config_dword( + cirrus_board->pci_bus, cirrus_board->pci_device, cirrus_board->pci_function, + PCI_BASE_ADDRESS_0, mem_base); + if( r != PCIB_ERR_SUCCESS) + return RTEMS_UNSATISFIED; + + r = pci_read_config_dword( + cirrus_board->pci_bus, cirrus_board->pci_device, cirrus_board->pci_function, + PCI_BASE_ADDRESS_1, cirrus_register_base); + if( r != PCIB_ERR_SUCCESS) + return RTEMS_UNSATISFIED; + + *mem_base &= PCI_BASE_ADDRESS_MEM_MASK; + *cirrus_register_base &= PCI_BASE_ADDRESS_MEM_MASK; + + return RTEMS_SUCCESSFUL; +} + +static inline int +fb_cirrus_read_config_dword( + struct cirrus_board_str *fbst, + unsigned char where, + uint32_t *pval) +{ + return pci_read_config_dword( + fbst->pci_bus, fbst->pci_device, fbst->pci_function, + where, pval); +} + +static inline int +fb_cirrus_write_config_dword( + struct cirrus_board_str *fbst, + unsigned char where, + uint32_t val) +{ + return pci_write_config_dword( + fbst->pci_bus, fbst->pci_device, fbst->pci_function, + where, val); +} + +static inline void +fb_cirrus_write_reg8 ( + const struct cirrus_board_str *fbst, + unsigned int reg, + unsigned int val) +{ + *(volatile uint8_t*)((char *)fbst->reg_base + reg) = val; +} + +static inline unsigned int +fb_cirrus_read_reg8 ( + const struct cirrus_board_str *fbst, + unsigned int reg) +{ + return *(volatile uint8_t*)((char *)fbst->reg_base + reg); +} + +#define SEQ_INDEX 0x04 +#define SEQ_DATA 0x05 + +static inline void +fb_cirrus_write_seq_reg ( + const struct cirrus_board_str *fbst, + unsigned int reg, + unsigned int val) +{ + fb_cirrus_write_reg8(fbst, SEQ_INDEX, reg); + fb_cirrus_write_reg8(fbst, SEQ_DATA, val); +} + +static inline unsigned int +fb_cirrus_read_seq_reg ( + const struct cirrus_board_str *fbst, + unsigned int reg) +{ + fb_cirrus_write_reg8(fbst, SEQ_INDEX, reg); + return fb_cirrus_read_reg8(fbst, SEQ_DATA); +} + +#define CRT_INDEX 0x14 +#define CRT_DATA 0x15 + +static inline void +fb_cirrus_write_crt_reg ( + const struct cirrus_board_str *fbst, + unsigned int reg, + unsigned int val) +{ + fb_cirrus_write_reg8(fbst, CRT_INDEX, reg); + fb_cirrus_write_reg8(fbst, CRT_DATA, val); +} + +static inline unsigned int +fb_cirrus_read_crt_reg ( + const struct cirrus_board_str *fbst, + unsigned int reg) +{ + fb_cirrus_write_reg8(fbst, CRT_INDEX, reg); + return fb_cirrus_read_reg8(fbst, CRT_DATA); +} + +#define GDC_INDEX 0x0E +#define GDC_DATA 0x0F + +static inline void +fb_cirrus_write_gdc_reg ( + const struct cirrus_board_str *fbst, + unsigned int reg, + unsigned int val) +{ + fb_cirrus_write_reg8(fbst, GDC_INDEX, reg); + fb_cirrus_write_reg8(fbst, GDC_DATA, val); +} + +static inline unsigned int +fb_cirrus_read_gdc_reg ( + const struct cirrus_board_str *fbst, + unsigned int reg) +{ + fb_cirrus_write_reg8(fbst, GDC_INDEX, reg); + return fb_cirrus_read_reg8(fbst, GDC_DATA); +} + +#define VGA_DAC_MASK 0x06 + +static inline void +fb_cirrus_write_hdr_reg ( + const struct cirrus_board_str *fbst, + unsigned int val) +{ + volatile unsigned int dummy RTEMS_UNUSED; + dummy = fb_cirrus_read_reg8(fbst, VGA_DAC_MASK); + dummy = fb_cirrus_read_reg8(fbst, VGA_DAC_MASK); + dummy = fb_cirrus_read_reg8(fbst, VGA_DAC_MASK); + dummy = fb_cirrus_read_reg8(fbst, VGA_DAC_MASK); + fb_cirrus_write_reg8(fbst, VGA_DAC_MASK, val); +} + +/* Functionality to support multiple VGA frame buffers can be added easily, + * but is not supported at this moment because there is no need for two or + * more "classic" VGA adapters. Multiple frame buffer drivers may be + * implemented and If we had implement it they would be named as "/dev/fb0", + * "/dev/fb1", "/dev/fb2" and so on. + */ + +/* + * fb_cirrus device driver INITIALIZE entry point. + */ +rtems_device_driver +frame_buffer_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + int res; + + printk( "FB_CIRRUS -- driver initializing..\n" ); + + res = pci_find_device( + CIRRUS_VENDOR_ID, + CIRRUS_GD5446_DEVICE_ID, + minor, + &cirrus_board_info.pci_bus, + &cirrus_board_info.pci_device, + &cirrus_board_info.pci_function + ); + + if ( res != PCIB_ERR_SUCCESS ) { + printk( "FB_CIRRUS initialize -- device not found\n" ); + + return RTEMS_UNSATISFIED; + } + else{ + printk( "FB_CIRRUS -- driver initializing..\n" ); + /* + * Register the device + */ + status = rtems_io_register_name (FRAMEBUFFER_DEVICE_0_NAME, major, 0); + if (status != RTEMS_SUCCESSFUL) { + printk("Error registering " FRAMEBUFFER_DEVICE_0_NAME + " FB_CIRRUS framebuffer device!\n"); + rtems_fatal_error_occurred( status ); + } + + _Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE); + + return RTEMS_SUCCESSFUL; + } +} + +/* + * This function is used to initialize the Start Address - the first + * displayed location in the video memory. + * Usually mandatory + */ +static void +cirrus_adjust_frame( struct cirrus_board_str *board, int x, int y) +{ + uint32_t Base; + uint8_t tmp; + + Base = ((y * fb_var.xres + x) >> 3); + if (fb_var.bits_per_pixel != 1) + Base *= (fb_var.bits_per_pixel >> 2); + + printk("FB_CIRRUS: cirrus_adjust_frame %d %d >>> %d %x\n", x, y, Base, Base); + + if ((Base & ~0x000FFFFF) != 0) { + printk("FB_CIRRUS: Internal error: cirrus_adjust_frame: cannot handle overflow\n"); + return; + } + + fb_cirrus_write_crt_reg( board, 0x0C, (Base >> 8) & 0xff); + fb_cirrus_write_crt_reg( board, 0x0D, Base & 0xff); + + tmp = fb_cirrus_read_crt_reg( board, 0x1B); + tmp &= 0xF2; + tmp |= (Base >> 16) & 0x01; + tmp |= (Base >> 15) & 0x0C; + fb_cirrus_write_crt_reg( board, 0x1B, tmp); + + tmp = fb_cirrus_read_crt_reg( board, 0x1D); + tmp &= 0x7F; + tmp |= (Base >> 12) & 0x80; + fb_cirrus_write_crt_reg( board, 0x1D, tmp); +} + +static int +cirrus_set_mode(DisplayModePtr mode) +{ + int depthcode = fb_var.bits_per_pixel;; + int width; + int HDiv2 = 0, VDiv2 = 0; + const struct cirrus_board_str *cirrus_board_ptr = &cirrus_board_info; + int temp; + int hdr = -1; + + printk("FB_CIRRUS: mode %d bpp, %d Hz %d %d %d %d %d %d %d %d\n", + fb_var.bits_per_pixel, + mode->Clock, + mode->HDisplay, + mode->HSyncStart, + mode->HSyncEnd, + mode->HTotal, + mode->VDisplay, + mode->VSyncStart, + mode->VSyncEnd, + mode->VTotal); + + if ( mode->Clock > 85500 ) { + /* The actual DAC register value is set later. */ + /* The CRTC is clocked at VCLK / 2, so we must half the */ + /* horizontal timings. */ + if (!mode->CrtcHAdjusted) { + mode->HDisplay >>= 1; + mode->HSyncStart >>= 1; + mode->HTotal >>= 1; + mode->HSyncEnd >>= 1; + mode->SynthClock >>= 1; + mode->CrtcHAdjusted = TRUE; + } + depthcode += 64; + HDiv2 = 1; + } + if (mode->VTotal >= 1024 ) { + /* For non-interlaced vertical timing >= 1024, the vertical timings */ + /* are divided by 2 and VGA CRTC 0x17 bit 2 is set. */ + if (!mode->CrtcVAdjusted) { + mode->VDisplay >>= 1; + mode->VSyncStart >>= 1; + mode->VSyncEnd >>= 1; + mode->VTotal >>= 1; + mode->CrtcVAdjusted = TRUE; + } + VDiv2 = 1; + } + + /**************************************************** + * Sequential registers + */ + fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x00, 0x00); + fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x01, 0x01); + fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x02, 0x0F); + fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x03, 0x00); + fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x04, 0x0E); + + /**************************************************** + * CRTC Controller Registers + */ + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x00, (mode->HTotal >> 3) - 5 ); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x01, (mode->HDisplay >> 3) - 1); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x02, (mode->HSyncStart >> 3) - 1); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x03, ((mode->HSyncEnd >> 3) & 0x1F) | 0x80); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x04, (mode->HSyncStart >> 3)); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x05, + (((mode->HSyncEnd >> 3) & 0x20 ) << 2 ) + | (((mode->HSyncEnd >> 3)) & 0x1F)); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x06, (mode->VTotal - 2) & 0xFF); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x07, + (((mode->VTotal -2) & 0x100) >> 8 ) + | (((mode->VDisplay -1) & 0x100) >> 7 ) + | ((mode->VSyncStart & 0x100) >> 6 ) + | (((mode->VSyncStart) & 0x100) >> 5 ) + | 0x10 + | (((mode->VTotal -2) & 0x200) >> 4 ) + | (((mode->VDisplay -1) & 0x200) >> 3 ) + | ((mode->VSyncStart & 0x200) >> 2 )); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x08, 0x00); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x09, ((mode->VSyncStart & 0x200) >>4) | 0x40); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0A, 0x00); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0B, 0x00); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0C, 0x00); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0D, 0x00); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0E, 0x00); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0F, 0x00); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x10, mode->VSyncStart & 0xFF); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x11, (mode->VSyncEnd & 0x0F) | 0x20); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x12, (mode->VDisplay -1) & 0xFF); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x13, 0x00); /* no interlace */ + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x14, 0x00); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x15, mode->VSyncStart & 0xFF); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x16, (mode->VSyncStart +1) & 0xFF); + + temp = 0xAF; + if(VDiv2) + temp |= 0x04; + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x17, temp); + + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x18, 0xFF); + + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x1A , + (((mode->HTotal >> 3) & 0xC0 ) >> 2) + | (((mode->VTotal - 2) & 0x300 ) >> 2)); + + width = fb_fix.line_length >> 3; + if (fb_var.bits_per_pixel == 1) + width <<= 2; + if(width >= 0xFF) + printk("FB_CIRRUS: Warning line size over the limit ... reduce bpp or width resolution"); + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x13, width); + /* Offset extension (see CR13) */ + temp = fb_cirrus_read_crt_reg( cirrus_board_ptr, 0x1B); + temp &= 0xAF; + temp |= (width >> (3+4)) & 0x10; + temp |= (width >> (3+3)) & 0x40; + temp |= 0x22; + fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x1B, temp); + + /**************************************************** + * Sequential register + * Enable linear mode and high-res packed pixel mode + */ + temp = fb_cirrus_read_seq_reg( cirrus_board_ptr, 0x07); + temp &= 0xe0; + switch (depthcode) { + case 1: + case 4: + temp |= 0x10; + break; + case 8: + temp |= 0x11; + break; + case 64+8: + temp |= 0x17; + break; + case 15: + temp |= 0x17; + hdr = 0xC0; /* 5:5:5 Sierra */ + break; + case 16: + temp |= 0x17; + hdr = 0xC1; /* 5:6:5 XGA mode */ + break; + case 24: + temp |= 0x15; + hdr = 0xC5; /* 8:8:8 16M colors */ + break; + case 32: + temp |= 0x19; + hdr = 0xC5; /* 8:8:8 16M colors */ + break; + default: + printk("FB_CIRRUS: Cannot Initialize display to requested mode\n"); + printk("FB_CIRRUS: returning RTEMS_UNSATISFIED on depthcode %d\n", depthcode); + return RTEMS_UNSATISFIED; + } + fb_cirrus_write_seq_reg( cirrus_board_ptr, 0x07, temp); + /* this just set packed pixel mode with according bpp */ + + /**************************************************** + * HDR Register + */ + if(hdr > 0) + fb_cirrus_write_hdr_reg( cirrus_board_ptr, hdr); + + /**************************************************** + * Graphic Data Controller Registers + */ + temp = fb_cirrus_read_gdc_reg( cirrus_board_ptr, 0x12); + if (HDiv2) + temp |= 0x20; + else + temp &= ~0x20; + fb_cirrus_write_gdc_reg( cirrus_board_ptr, 0x12, temp); + + /* Enable high-color modes */ + fb_cirrus_write_gdc_reg(cirrus_board_ptr, 0x05, 0x40); + + /* VGA graphics mode */ + fb_cirrus_write_gdc_reg(cirrus_board_ptr, 0x06, 0x01); + + return TRUE; +} + +static void +cirrus_prepare_mode( void ) +{ + + active_mode = &available_modes[CIRRUS_DISPLAY_MODE]; + + fb_var.bits_per_pixel = CIRRUS_DEFAULT_BPP; + + fb_var.xres = active_mode->HDisplay; + fb_var.yres = active_mode->VDisplay; + + fb_fix.line_length = (fb_var.xres * fb_var.bits_per_pixel + 7) / 8; + + fb_fix.type = FB_TYPE_PACKED_PIXELS; + fb_fix.visual = FB_VISUAL_TRUECOLOR; + +} + +/* + * fb_cirrus device driver OPEN entry point + */ +rtems_device_driver +frame_buffer_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + int r; + uint32_t smem_start, regs_start; + + if (_Atomic_Flag_test_and_set(&driver_mutex, ATOMIC_ORDER_ACQUIRE) != 0 ) { + printk( "FB_CIRRUS could not lock driver_mutex\n" ); + + return RTEMS_UNSATISFIED; + } + + r = cirrus_pci_read(&cirrus_board_info, &smem_start, ®s_start); + if ( r == RTEMS_UNSATISFIED ) + return RTEMS_UNSATISFIED; + + fb_fix.smem_start = (volatile char *)smem_start; + fb_fix.smem_len = 0x1000000; + cirrus_board_info.reg_base = (void *)regs_start; + + cirrus_prepare_mode(); + + cirrus_set_mode( active_mode ); + + cirrus_adjust_frame( &cirrus_board_info, 0, 0); + + if (1) { + uint32_t pixmask; + int x, y; + + if(fb_var.bits_per_pixel == 32) + pixmask = 0xffffff; + else + pixmask = (1 << fb_var.bits_per_pixel) - 1; + + printk("FB_CIRRUS: mode set, test patter output\n"); + + for(y = 0; y < fb_var.yres; y++) { + for(x = 0; x < fb_var.xres; x++) { + uint32_t color; + char *addr = (char *)fb_fix.smem_start; + addr += y * fb_fix.line_length; + addr += x * fb_var.bits_per_pixel / 8; + color = x & 1 ? 0 : y & 1 ? pixmask & 0x000ff00f : pixmask; + if(y == fb_var.yres - 1) { + if((x > 0) && (x < fb_var.xres-1)) + color = pixmask & 0x00555555; + } + switch (fb_var.bits_per_pixel) { + case 8: *(volatile uint8_t*) addr = color; + break; + case 16: *(volatile uint16_t*) addr = color; + break; + case 24: *(volatile uint32_t*) addr = + (*(volatile uint32_t*) addr & 0xff000000) | color; + break; + case 32: *(volatile uint32_t*) addr = color; + break; + } + } + } + } + + return RTEMS_SUCCESSFUL; + +} + +/* + * fb_cirrus device driver CLOSE entry point + */ +rtems_device_driver +frame_buffer_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + _Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE); + + /* restore previous state. for VGA this means return to text mode. + * leave out if graphics hardware has been initialized in + * frame_buffer_initialize() */ + + /* VGA text mode */ + fb_cirrus_write_gdc_reg(&cirrus_board_info, 0x06, 0x00); + + printk( "FB_CIRRUS: close called.\n" ); + return RTEMS_SUCCESSFUL; +} + +/* + * fb_cirrus device driver READ entry point. + */ +rtems_device_driver +frame_buffer_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; + rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count; + memcpy(rw_args->buffer, (const void *) (fb_fix.smem_start + rw_args->offset), rw_args->bytes_moved); + return RTEMS_SUCCESSFUL; +} + +/* + * frame_buffer device driver WRITE entry point. + */ +rtems_device_driver +frame_buffer_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; + rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count; + memcpy( (void *) (fb_fix.smem_start + rw_args->offset), rw_args->buffer, rw_args->bytes_moved); + return RTEMS_SUCCESSFUL; +} + +static int +get_fix_screen_info( struct fb_fix_screeninfo *info ) +{ + *info = fb_fix; + return 0; +} + +static int +get_var_screen_info( struct fb_var_screeninfo *info ) +{ + *info = fb_var; + return 0; +} + +/* + * IOCTL entry point -- This method is called to carry + * all services of this interface. + */ +rtems_device_driver +frame_buffer_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_libio_ioctl_args_t *args = arg; + + printk( "FB_CIRRUS ioctl called, cmd=%x\n", args->command ); + + switch( args->command ) { + case FBIOGET_FSCREENINFO: + args->ioctl_return = get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer ); + break; + case FBIOGET_VSCREENINFO: + args->ioctl_return = get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer ); + break; + case FBIOPUT_VSCREENINFO: + /* not implemented yet */ + args->ioctl_return = -1; + return RTEMS_UNSATISFIED; + case FBIOGETCMAP: + /* no palette - truecolor mode */ + args->ioctl_return = -1; + return RTEMS_UNSATISFIED; + case FBIOPUTCMAP: + /* no palette - truecolor mode */ + args->ioctl_return = -1; + return RTEMS_UNSATISFIED; + default: + args->ioctl_return = 0; + break; + } + return RTEMS_SUCCESSFUL; +} diff --git a/bsps/i386/pc386/console/fb_vesa_rm.c b/bsps/i386/pc386/console/fb_vesa_rm.c new file mode 100644 index 0000000000..1c42956fce --- /dev/null +++ b/bsps/i386/pc386/console/fb_vesa_rm.c @@ -0,0 +1,1004 @@ +/** + * @file fb_vesa_rm.c + * + * @ingroup i386_pc386 + * + * @brief FB driver for graphic hardware compatible with VESA Bios Extension + * Real mode interface utilized + * Tested on real HW. + * + * Public sources related: + * - VESA BIOS EXTENSION (VBE) Core Function Standard, Ver: 3.0, Sep 16, 1998 + * - VESA Enhanced Extended Display Identification Data (E-EDID) Standard + * Release A, Revision 2, September 25, 2006 + * + * Hardware is completely initialized upon boot of the system. + * Therefore there is no way to change graphics mode later. + * + * Interrupt 0x10 is used for entering graphics BIOS. + * + * Driver reads parameter from multiboot command line to setup video: + * "--video=x[-]" + * "--video=auto" - try EDID to find mode that fits the display attached best + * "--video=none" / "--video=off" - do not initialize the driver + * If cmdline parameter is not specified the rtems_fb_default_mode + * variable content is tested (see doc below). + * Command line option has higher priority. rtems_fb_default_mode is probed + * only if cmdline "--video=" is not specified at all. + * + * If neither of the above options is specified the driver is not initialized. + */ + +/* + * Copyright (c) 2014 - CTU in Prague + * Jan Doležal ( dolezj21@fel.cvut.cz ) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + * The code for rtems_buffer_* functions was greatly + * inspired or coppied from: + * - RTEMS fb_cirrus.c - Alexandru-Sever Horin (alex.sever.h@gmail.com) + */ + +#include + +#include + +#include +#include +#include + +#include + +#include + +#include +#include + +#include + +#include + +#define FB_VESA_NAME "FB_VESA_RM" + +/** + * @brief Allows to enable initialization of VESA real mode driver from + * an application by setting the value of this variable to non null value in + * user's module. The value of this variable will be then updated + * when linked with application's object. + * + * Further the value should point to string in the following format: + * "x[-]" - e.g. "1024x768-32" + * "auto" - try EDID to find mode that fits the display attached best + * "none" / "off" - do not initialize the driver + * the given parameters are used if applicable. + * + * Command line argument "--video=" has priority over this string. + */ +const char * const rtems_fb_default_mode; + +/** + * @brief Initializes VBE framebuffer during bootup. + * + * utilizes switches to real mode interrupts and therefore must be + * called during bootup before tick is set up and real-time + * interrupt vectors utilized + */ +void vesa_realmode_bootup_init(void); + +/* flag to limit driver to protect against multiple opens */ +static Atomic_Flag driver_mutex; + +/* screen information for the VGA driver + * standard structures - from RTEMS fb interface + */ +static struct fb_var_screeninfo fb_var; +static struct fb_fix_screeninfo fb_fix; + +static int32_t vbe_used_mode; + +uint32_t VBE_controller_information( VBE_vbe_info_block *info_block, + uint16_t queried_VBE_Version) +{ + uint16_t size; + VBE_vbe_info_block *VBE_buffer = + (VBE_vbe_info_block *)i386_get_default_rm_buffer(&size); + i386_realmode_interrupt_registers parret; + parret.reg_eax = VBE_RetVBEConInf; + uint16_t seg, off; + i386_Physical_to_real(VBE_buffer, &seg, &off); + parret.reg_edi = (uint32_t)off; + parret.reg_es = seg; + /* indicate to graphic's bios that VBE2.0 extended information is desired */ + if (queried_VBE_Version >= 0x200) + { + memcpy( + &VBE_buffer->VbeSignature, + VBE20plus_SIGNATURE, + sizeof(VBE_buffer->VbeSignature) + ); + } + if (i386_real_interrupt_call(INTERRUPT_NO_VIDEO_SERVICES, &parret) == 0) + return -1; + if ((parret.reg_eax & 0xFFFF) == + (VBE_callSuccessful<<8 | VBE_functionSupported)) + { + *info_block = *VBE_buffer; + } + return (parret.reg_eax & 0xFFFF); +} + +uint32_t VBE_mode_information( VBE_mode_info_block *info_block, + uint16_t mode_number) +{ + uint16_t size; + VBE_mode_info_block *VBE_buffer = + (VBE_mode_info_block *)i386_get_default_rm_buffer(&size); + i386_realmode_interrupt_registers parret; + parret.reg_eax = VBE_RetVBEModInf; + parret.reg_ecx = mode_number; + uint16_t seg, off; + i386_Physical_to_real(VBE_buffer, &seg, &off); + parret.reg_edi = (uint32_t)off; + parret.reg_es = seg; + if (i386_real_interrupt_call(INTERRUPT_NO_VIDEO_SERVICES, &parret) == 0) + return -1; + if ((parret.reg_eax & 0xFFFF) == + (VBE_callSuccessful<<8 | VBE_functionSupported)) + { + *info_block = *VBE_buffer; + } + return (parret.reg_eax & 0xFFFF); +} + +uint32_t VBE_set_mode( uint16_t mode_number, + VBE_CRTC_info_block *info_block) +{ + uint16_t size; + VBE_CRTC_info_block *VBE_buffer = + (VBE_CRTC_info_block *)i386_get_default_rm_buffer(&size); + i386_realmode_interrupt_registers parret; + /* copy CRTC */ + *VBE_buffer = *info_block; + parret.reg_eax = VBE_SetVBEMod; + parret.reg_ebx = mode_number; + uint16_t seg, off; + i386_Physical_to_real(VBE_buffer, &seg, &off); + parret.reg_edi = (uint32_t)off; + parret.reg_es = seg; + if (i386_real_interrupt_call(INTERRUPT_NO_VIDEO_SERVICES, &parret) == 0) + return -1; + return (parret.reg_eax & 0xFFFF); +} + +uint32_t VBE_current_mode(uint16_t *mode_number) +{ + i386_realmode_interrupt_registers parret; + parret.reg_eax = VBE_RetCurVBEMod; + if (i386_real_interrupt_call(INTERRUPT_NO_VIDEO_SERVICES, &parret) == 0) + return -1; + *mode_number = (uint16_t)parret.reg_ebx; + return (parret.reg_eax & 0xFFFF); +} + +uint32_t VBE_report_DDC_capabilities(uint16_t controller_unit_number, + uint8_t *seconds_to_transfer_EDID_block, + uint8_t *DDC_level_supported) +{ + i386_realmode_interrupt_registers parret; + parret.reg_eax = VBE_DisDatCha; + parret.reg_ebx = VBEDDC_Capabilities; + parret.reg_ecx = controller_unit_number; + parret.reg_edi = 0; + parret.reg_es = 0; + if (i386_real_interrupt_call(INTERRUPT_NO_VIDEO_SERVICES, &parret) == 0) + return -1; + *seconds_to_transfer_EDID_block = (uint8_t)parret.reg_ebx >> 8; + *DDC_level_supported = (uint8_t)parret.reg_ebx; + return (parret.reg_eax & 0xFFFF); +} + +uint32_t VBE_read_EDID(uint16_t controller_unit_number, + uint16_t EDID_block_number, + EDID_edid1 *buffer) +{ + uint16_t size; + EDID_edid1 *VBE_buffer = (EDID_edid1*)i386_get_default_rm_buffer(&size); + i386_realmode_interrupt_registers parret; + parret.reg_eax = VBE_DisDatCha; + parret.reg_ebx = VBEDDC_ReadEDID; + parret.reg_ecx = controller_unit_number; + parret.reg_edx = EDID_block_number; + uint16_t seg, off; + i386_Physical_to_real(VBE_buffer, &seg, &off); + parret.reg_edi = (uint32_t)off; + parret.reg_es = seg; + if (i386_real_interrupt_call(INTERRUPT_NO_VIDEO_SERVICES, &parret) == 0) + return -1; + if ((parret.reg_eax & 0xFFFF) == + (VBE_callSuccessful<<8 | VBE_functionSupported)) + { + *buffer = *VBE_buffer; + } + return (parret.reg_eax & 0xFFFF); +} + +/** + * @brief Basic graphic's mode parameters + */ +typedef struct { + /** number of the graphic's mode */ + uint16_t mode_number; + /** number of pixels in one line */ + uint16_t resX; + /** number of lines */ + uint16_t resY; + /** bits per pixel */ + uint8_t bpp; +} Mode_params; + +typedef enum { + NO_SUITABLE_MODE = -1, + BAD_FORMAT = -2, + AUTO_SELECT = -3, + DONT_INIT = -4, + NO_MODE_REQ = -5, +} mode_err_ret_val; + +/** + * @brief Find mode by resolution in the given list of modes + * + * finds mode in \p mode_list of \p list_length length according to resolution + * given in \p searched_resolution . If bpp is given in that struct as well + * mode with such color depth and resolution is searched for. Otherwise bpp + * has to be zero. Mode number found is returned and also filled into + * \p searched_resolution . bpp is also filled into \p searchedResolution if it + * was 0 before call. + * + * @param[in] mode_list list of modes to be searched + * @param[in] list_length number of modes in the list + * @param[in,out] searched_resolution element filled with searched resolution + * or/and bpp; mode_number is filled in if appropriate mode found + * @retval mode number satisfying given parameters + * @retval -1 no suitable mode found + */ +static int32_t find_mode_by_resolution(Mode_params *mode_list, + uint8_t list_length, + Mode_params *searched_resolution) +{ + uint8_t i = 0; + while (i < list_length) + { + if (searched_resolution->resX == mode_list[i].resX && + searched_resolution->resY == mode_list[i].resY) + { + if (searched_resolution->bpp==0 || + searched_resolution->bpp==mode_list[i].bpp) + { + searched_resolution->bpp = mode_list[i].bpp; + searched_resolution->mode_number = mode_list[i].mode_number; + return mode_list[i].mode_number; + } + } + i++; + } + return NO_SUITABLE_MODE; +} + +/** + * @brief Find mode given in string format. + * + * expected format + * x[-] + * numbers , and are decadic + * + * @param[in] mode_list list of modes to be searched + * @param[in] list_length number of modes in the list + * @param[in] video_string string to be parsed + * @retval video mode number to be set + * @retval -1 no suitable mode found + * @retval -2 bad format of the video_string + * @retval -3 automatic mode selection requested + * @retval -4 request to not initialize graphics + * @retval -5 no mode requested/empty video string + */ +static int32_t find_mode_from_string(Mode_params *mode_list, + uint8_t list_length, + const char *video_string) +{ + const char* opt; + Mode_params cmdline_mode; + char* endptr; + cmdline_mode.bpp = 16; /* default bpp */ + opt = video_string; + if (opt) + { + if (strncmp(opt, "auto", 4) == 0) + return AUTO_SELECT; + if (strncmp(opt, "none", 4) == 0 || + strncmp(opt, "off", 3) == 0) + { + return DONT_INIT; + } + cmdline_mode.resX = strtol(opt, &endptr, 10); + if (*endptr != 'x') + { + return BAD_FORMAT; + } + opt = endptr+1; + cmdline_mode.resY = strtol(opt, &endptr, 10); + switch (*endptr) + { + case '-': + opt = endptr+1; + if (strlen(opt) <= 2) + cmdline_mode.bpp = strtol(opt, &endptr, 10); + else + { + cmdline_mode.bpp = strtol(opt, &endptr, 10); + if (*endptr != ' ') + { + return BAD_FORMAT; + } + } + case ' ': + case 0: + break; + default: + return BAD_FORMAT; + } + + return find_mode_by_resolution(mode_list, list_length, &cmdline_mode); + } + return NO_MODE_REQ; +} + +/** + * @brief Find mode given within command line. + * + * Parse command line option "--video=" if available. + * expected format + * --video=x[-] + * numbers , and are decadic + * + * @param[in] mode_list list of modes to be searched + * @param[in] list_length number of modes in the list + * @retval video mode number to be set + * @retval -1 no suitable mode found + * @retval -2 bad format of the video_string + * @retval -3 automatic mode selection requested + * @retval -4 request to not initialize graphics + * @retval -5 no mode requested/empty video string + */ +static int32_t find_mode_using_cmdline(Mode_params *mode_list, + uint8_t list_length) +{ + const char* opt; + opt = bsp_cmdline_arg("--video="); + if (opt) + { + opt += sizeof("--video=")-1; + return find_mode_from_string(mode_list, list_length, opt); + } + return NO_MODE_REQ; +} + +/** + * @brief Find mode number best fitting to monitor attached + * + * @param[in] mode_list list of modes to be searched + * @param[in] list_length number of modes in the list + * @retval video mode number to be set + * @retval -1 on parsing error or when no suitable mode found + */ +static int32_t find_mode_using_EDID( Mode_params *mode_list, + uint8_t list_length) +{ + EDID_edid1 edid; + uint8_t checksum, iterator; + uint8_t index, j; + Mode_params EDIDmode; + checksum = 0; + iterator = 0; + EDIDmode.bpp = 0; + if (VBE_read_EDID(0, 0, &edid) != + (VBE_callSuccessful<<8 | VBE_functionSupported)) + { + printk(FB_VESA_NAME " Function 15h (read EDID) not supported.\n"); + return -1; + } +/* version of EDID structure */ + if (edid.Version == 1) + { /* EDID version 1 */ + while (iterator < sizeof(EDID_edid1)) + { + checksum += *((uint8_t *)&edid+iterator); + iterator++; + } + if (checksum) + /* not implemented: try to read EDID again */ + printk(FB_VESA_NAME " EDID v1 checksum failed\n"); + + /* try to find Detailed Timing Descriptor (defined in BASE EDID) + in controller mode list; first should be preffered mode */ + index = 0; + while (index < 4) + { + /* skip if it is monitor descriptor */ + if (edid.dtd_md[index].md.Flag0[0] == 0 && + edid.dtd_md[index].md.Flag0[1] == 0 && + edid.dtd_md[index].md.Flag1 == 0) + { + index++; + continue; + } + EDIDmode.resX = DTD_horizontal_active(&edid.dtd_md[0].dtd); + EDIDmode.resY = DTD_vertical_active(&edid.dtd_md[0].dtd); + if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != + -1) + return EDIDmode.mode_number; + + index++; + } + /* try to find Detailed Timing Descriptor (defined in optional EXTENSION + Blocks) in controller mode list */ + if (edid.ExtensionFlag > 0) + { + /* not implemented */ + } + /* try to find CVT (defined in BASE EDID) in controller mode list */ + index = 1; + while (index < 4) + { + if (edid.dtd_md[index].md.DataTypeTag == + EDID_DTT_CVT3ByteTimingCodes && + edid.dtd_md[index].md.Flag0[0] == 0 && + edid.dtd_md[index].md.Flag0[1] == 0 && + edid.dtd_md[index].md.Flag1 == 0 && + edid.dtd_md[index].md.Flag2 == 0) + { + EDID_CVT_timing_codes_3B *cvt = (EDID_CVT_timing_codes_3B *) + &edid.dtd_md[index].md.DescriptorData[0]; + j = 0; + while (j < 4) + { + EDIDmode.resY = edid1_CVT_addressable_lines_high( + &cvt->cvt[j] + ); + switch (edid1_CVT_aspect_ratio(&cvt->cvt[j])) + { + case EDID_CVT_AspectRatio_4_3: + EDIDmode.resX = (EDIDmode.resY*4)/3; + break; + case EDID_CVT_AspectRatio_16_9: + EDIDmode.resX = (EDIDmode.resY*16)/9; + break; + case EDID_CVT_AspectRatio_16_10: + EDIDmode.resX = (EDIDmode.resY*16)/10; + break; + case EDID_CVT_AspectRatio_15_9: + EDIDmode.resX = (EDIDmode.resY*15)/9; + break; + } + EDIDmode.resX = (EDIDmode.resX/8)*8; + if (find_mode_by_resolution( + mode_list, list_length, &EDIDmode) != -1) + return EDIDmode.mode_number; + + j++; + } + } + index++; + } + /* try to find CVT (defined in optional EXTENSION Blocks) + in controller mode list */ + /* not implemented */ + /* try to find Standard Timings (listed in BASE EDID) + in controller mode list */ + index = 0; + while (index < 8) + { + /* check if descriptor is unused */ + if (edid1_STI_is_unused(&edid.STI[index])) + { + index++; + continue; + } + EDIDmode.resX = (edid.STI[index].HorizontalActivePixels+31)*8; + switch (edid.STI[index].ImageAspectRatio_RefreshRate & + EDID1_STI_ImageAspectRatioMask) + { + case EDID_STI_AspectRatio_16_10: + EDIDmode.resY = (EDIDmode.resX*10)/16; + break; + case EDID_STI_AspectRatio_4_3: + EDIDmode.resY = (EDIDmode.resX*3)/4; + break; + case EDID_STI_AspectRatio_5_4: + EDIDmode.resY = (EDIDmode.resX*4)/5; + break; + case EDID_STI_AspectRatio_16_9: + EDIDmode.resY = (EDIDmode.resX*9)/16; + break; + } + if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != + -1) + return EDIDmode.mode_number; + + index++; + } + /* try to find Standard Timings (listed in optional EXTENSION Blocks) + in controller mode list */ + /* not implemented */ + /* use Established Timings */ + if (edid1_established_tim(&edid, EST_1280x1024_75Hz)) + { + EDIDmode.resX = 1280; + EDIDmode.resY = 1024; + EDIDmode.bpp = 0; + if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != + -1) + return EDIDmode.mode_number; + } + if (edid1_established_tim(&edid, EST_1152x870_75Hz)) + { + EDIDmode.resX = 1152; + EDIDmode.resY = 870; + EDIDmode.bpp = 0; + if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != + -1) + return EDIDmode.mode_number; + } + if (edid1_established_tim(&edid, EST_1024x768_75Hz) || + edid1_established_tim(&edid, EST_1024x768_70Hz) || + edid1_established_tim(&edid, EST_1024x768_60Hz) || + edid1_established_tim(&edid, EST_1024x768_87Hz)) + { + EDIDmode.resX = 1024; + EDIDmode.resY = 768; + EDIDmode.bpp = 0; + if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != + -1) + return EDIDmode.mode_number; + } + if (edid1_established_tim(&edid, EST_832x624_75Hz)) + { + EDIDmode.resX = 832; + EDIDmode.resY = 624; + EDIDmode.bpp = 0; + if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != + -1) + return EDIDmode.mode_number; + } + if (edid1_established_tim(&edid, EST_800x600_60Hz) || + edid1_established_tim(&edid, EST_800x600_56Hz) || + edid1_established_tim(&edid, EST_800x600_75Hz) || + edid1_established_tim(&edid, EST_800x600_72Hz)) + { + EDIDmode.resX = 800; + EDIDmode.resY = 600; + EDIDmode.bpp = 0; + if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != + -1) + return EDIDmode.mode_number; + } + if (edid1_established_tim(&edid, EST_720x400_88Hz) || + edid1_established_tim(&edid, EST_720x400_70Hz)) + { + EDIDmode.resX = 720; + EDIDmode.resY = 400; + EDIDmode.bpp = 0; + if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != + -1) + return EDIDmode.mode_number; + } + if (edid1_established_tim(&edid, EST_640x480_75Hz) || + edid1_established_tim(&edid, EST_640x480_72Hz) || + edid1_established_tim(&edid, EST_640x480_67Hz) || + edid1_established_tim(&edid, EST_640x480_60Hz)) + { + EDIDmode.resX = 640; + EDIDmode.resY = 480; + EDIDmode.bpp = 0; + if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != + -1) + return EDIDmode.mode_number; + } + } + else + printk(FB_VESA_NAME " error reading EDID: unsupported version\n"); + return -1; +} + +void vesa_realmode_bootup_init(void) +{ + uint32_t vbe_ret_val; + uint16_t size; + VBE_vbe_info_block *vib = (VBE_vbe_info_block *) + i386_get_default_rm_buffer(&size); + vbe_ret_val = VBE_controller_information(vib, 0x300); + if (vbe_ret_val == -1) + { + printk(FB_VESA_NAME " error calling real mode interrupt.\n"); + return; + } + if (vbe_ret_val != (VBE_callSuccessful<<8 | VBE_functionSupported)) + { + printk(FB_VESA_NAME " Function 00h (read VBE info block)" + "not supported.\n"); + } +/* Helper array is later filled with mode numbers and their parameters + sorted from the biggest values to the smalest where priorities of + parameters are from the highest to the lowest: resolution X, + resolution Y, bits per pixel. + The array is used for search the monitor provided parameters in EDID + structure and if found we set such mode using corresponding + VESA function. */ +#define MAX_NO_OF_SORTED_MODES 100 + Mode_params sorted_mode_params[MAX_NO_OF_SORTED_MODES]; + + uint16_t *vmpSegOff = (uint16_t *)&vib->VideoModePtr; + uint16_t *modeNOPtr = (uint16_t*) + i386_Real_to_physical(*(vmpSegOff+1), *vmpSegOff); + uint16_t iterator = 0; + + if (*(uint16_t*)vib->VideoModePtr == VBE_STUB_VideoModeList) + { + printk(FB_VESA_NAME " VBE Core not implemented!\n"); + } + else + { + /* prepare list of modes */ + while (*(modeNOPtr+iterator) != VBE_END_OF_VideoModeList && + *(modeNOPtr+iterator) != 0) + { /* some bios implementations ends the list incorrectly with 0 */ + if (iterator < MAX_NO_OF_SORTED_MODES) + { + sorted_mode_params[iterator].mode_number =*(modeNOPtr+iterator); + iterator ++; + } + else + break; + } + if (iterator < MAX_NO_OF_SORTED_MODES) + sorted_mode_params[iterator].mode_number = 0; + } + + VBE_mode_info_block *mib = (VBE_mode_info_block *) + i386_get_default_rm_buffer(&size); + iterator = 0; + uint8_t nextFilteredMode = 0; + uint16_t required_mode_attributes = VBE_modSupInHWMask | + VBE_ColorModeMask | VBE_GraphicsModeMask | VBE_LinFraBufModeAvaiMask; + /* get parameters of modes and filter modes according to set + required parameters */ + while (iterator < MAX_NO_OF_SORTED_MODES && + sorted_mode_params[iterator].mode_number!=0) + { + VBE_mode_information(mib, sorted_mode_params[iterator].mode_number); + if ((mib->ModeAttributes&required_mode_attributes) == + required_mode_attributes) + { + sorted_mode_params[nextFilteredMode].mode_number = + sorted_mode_params[iterator].mode_number; + sorted_mode_params[nextFilteredMode].resX = mib->XResolution; + sorted_mode_params[nextFilteredMode].resY = mib->YResolution; + sorted_mode_params[nextFilteredMode].bpp = mib->BitsPerPixel; + nextFilteredMode ++; + } + iterator ++; + } + sorted_mode_params[nextFilteredMode].mode_number = 0; + + uint8_t number_of_modes = nextFilteredMode; + + /* first search for video argument in multiboot options */ + vbe_used_mode = find_mode_using_cmdline(sorted_mode_params, + number_of_modes); + + if (vbe_used_mode == NO_MODE_REQ) { + vbe_used_mode = find_mode_from_string(sorted_mode_params, + number_of_modes, rtems_fb_default_mode); + if (vbe_used_mode != NO_MODE_REQ) { + printk(FB_VESA_NAME " using application option to select" + " video mode\n"); + } + } + else + { + printk(FB_VESA_NAME " using command line option '--video='" + "to select video mode\n"); + } + + switch (vbe_used_mode) { + case NO_SUITABLE_MODE: + printk(FB_VESA_NAME " requested mode not found\n"); + return; + case BAD_FORMAT: + printk(FB_VESA_NAME " bad format of video requested\n"); + return; + case DONT_INIT: + printk(FB_VESA_NAME " selected not to initialize graphics\n"); + return; + case NO_MODE_REQ: + printk(FB_VESA_NAME " not initialized, no video selected\n"); + return; + } + + /* sort filtered modes */ + Mode_params modeXchgPlace; + iterator = 0; + uint8_t j; + uint8_t idxBestMode; + while (iterator < number_of_modes) + { + idxBestMode = iterator; + j = iterator+1; + while (j < number_of_modes) + { + if (sorted_mode_params[j].resX > + sorted_mode_params[idxBestMode].resX) + idxBestMode = j; + else if (sorted_mode_params[j].resX == + sorted_mode_params[idxBestMode].resX) + { + if (sorted_mode_params[j].resY > + sorted_mode_params[idxBestMode].resY) + idxBestMode = j; + else if (sorted_mode_params[j].resY == + sorted_mode_params[idxBestMode].resY) + { + if (sorted_mode_params[j].bpp > + sorted_mode_params[idxBestMode].bpp) + idxBestMode = j; + } + } + j++; + } + if (idxBestMode != iterator) + { + modeXchgPlace = sorted_mode_params[iterator]; + sorted_mode_params[iterator] = sorted_mode_params[idxBestMode]; + sorted_mode_params[idxBestMode] = modeXchgPlace; + } + iterator++; + } + + if (vbe_used_mode == AUTO_SELECT) + { + printk(FB_VESA_NAME " auto video mode selected" + "\n\ttrying EDID ...\n"); + /* second search monitor for good resolution */ + vbe_used_mode = find_mode_using_EDID(sorted_mode_params, + number_of_modes); + if (vbe_used_mode == -1) + { + printk(FB_VESA_NAME" monitor's EDID video parameters not supported" + "\n\tusing mode with highest resolution, bpp\n"); + /* third set highest values */ + vbe_used_mode = sorted_mode_params[0].mode_number; + } + } + + /* fill framebuffer structs with info about selected mode */ + vbe_ret_val = VBE_mode_information(mib, vbe_used_mode); + if ((vbe_ret_val&0xff)!=VBE_functionSupported || + (vbe_ret_val>>8)!=VBE_callSuccessful) + { + printk(FB_VESA_NAME " Cannot get mode info anymore. ax=0x%lx\n", + vbe_ret_val); + } + + fb_var.xres = mib->XResolution; + fb_var.yres = mib->YResolution; + fb_var.bits_per_pixel = mib->BitsPerPixel; + fb_var.red.offset = mib->LinRedFieldPosition; + fb_var.red.length = mib->LinRedMaskSize; + fb_var.red.msb_right = 0; + fb_var.green.offset = mib->LinGreenFieldPosition; + fb_var.green.length = mib->LinGreenMaskSize; + fb_var.green.msb_right = 0; + fb_var.blue.offset = mib->LinBlueFieldPosition; + fb_var.blue.length = mib->LinBlueMaskSize; + fb_var.blue.msb_right = 0; + fb_var.transp.offset = mib->LinRsvdFieldPosition; + fb_var.transp.length = mib->LinRsvdMaskSize; + fb_var.transp.msb_right =0; + + fb_fix.smem_start = (char *)mib->PhysBasePtr; + fb_fix.line_length = mib->LinBytesPerScanLine; + fb_fix.smem_len = fb_fix.line_length*fb_var.yres; + fb_fix.type = FB_TYPE_PACKED_PIXELS; + if (fb_var.bits_per_pixel < 24) + fb_fix.visual = FB_VISUAL_DIRECTCOLOR; + else + fb_fix.visual = FB_VISUAL_TRUECOLOR; + + /* set selected mode */ + vbe_ret_val = VBE_set_mode(vbe_used_mode | VBE_linearFlatFrameBufMask, + (VBE_CRTC_info_block *)(i386_get_default_rm_buffer(&size))); + if (vbe_ret_val>>8 == VBE_callFailed) + printk(FB_VESA_NAME " VBE: Requested mode is not available."); + + if ((vbe_ret_val&0xff)!= (VBE_functionSupported | VBE_callSuccessful<<8)) + printk(FB_VESA_NAME " Call to function 2h (set VBE mode) failed. " + "ax=0x%" PRIx32 "\n", vbe_ret_val); + + vib = (void *) 0; + mib = (void *) 0; +} + +/* + * fb_vesa device driver INITIALIZE entry point. + */ +rtems_device_driver +frame_buffer_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + + printk(FB_VESA_NAME " frame buffer -- driver initializing..\n" ); + + /* + * Register the device. + */ + status = rtems_io_register_name(FRAMEBUFFER_DEVICE_0_NAME, major, 0); + if (status != RTEMS_SUCCESSFUL) + { + printk("Error registering " FRAMEBUFFER_DEVICE_0_NAME + " - " FB_VESA_NAME " frame buffer device!\n"); + rtems_fatal_error_occurred( status ); + } + + _Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE); + + return RTEMS_SUCCESSFUL; +} + +/* + * fb_vesa device driver OPEN entry point + */ +rtems_device_driver +frame_buffer_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + printk( FB_VESA_NAME " open device\n" ); + + if (_Atomic_Flag_test_and_set(&driver_mutex, ATOMIC_ORDER_ACQUIRE) != 0 ) + { + printk( FB_VESA_NAME " could not lock vesa_mutex\n" ); + + return RTEMS_UNSATISFIED; + } + + return RTEMS_SUCCESSFUL; + +} + +/* + * fb_vesa device driver CLOSE entry point + */ +rtems_device_driver +frame_buffer_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + printk( FB_VESA_NAME " close device\n" ); + _Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE); + /* restore previous state. for VGA this means return to text mode. + * leave out if graphics hardware has been initialized in + * frame_buffer_initialize() */ + + printk(FB_VESA_NAME ": close called.\n" ); + return RTEMS_SUCCESSFUL; +} + +/* + * fb_vesa device driver READ entry point. + */ +rtems_device_driver +frame_buffer_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + printk( FB_VESA_NAME " read device\n" ); + rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; + rw_args->bytes_moved = + ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? + (fb_fix.smem_len - rw_args->offset) : + rw_args->count; + memcpy(rw_args->buffer, (const void *) + (fb_fix.smem_start + rw_args->offset), rw_args->bytes_moved); + return RTEMS_SUCCESSFUL; +} + +/* + * frame_vesa device driver WRITE entry point. + */ +rtems_device_driver +frame_buffer_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + printk( FB_VESA_NAME " write device\n" ); + rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; + rw_args->bytes_moved = + ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? + (fb_fix.smem_len - rw_args->offset) : + rw_args->count; + memcpy( (void *) (fb_fix.smem_start + rw_args->offset), + rw_args->buffer, rw_args->bytes_moved); + return RTEMS_SUCCESSFUL; +} + +static int get_fix_screen_info( struct fb_fix_screeninfo *info ) +{ + *info = fb_fix; + return 0; +} + +static int get_var_screen_info( struct fb_var_screeninfo *info ) +{ + *info = fb_var; + return 0; +} + +/* + * IOCTL entry point -- This method is called to carry + * all services of this interface. + */ +rtems_device_driver +frame_buffer_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_libio_ioctl_args_t *args = arg; + + printk( FB_VESA_NAME " ioctl called, cmd=%" PRIx32 "\n", args->command ); + printk("fbxres %lu, fbyres %lu\n", fb_var.xres, fb_var.yres); + printk("fbbpp %lu\n", fb_var.bits_per_pixel); + + switch (args->command) + { + case FBIOGET_FSCREENINFO: + args->ioctl_return = + get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer ); + break; + case FBIOGET_VSCREENINFO: + args->ioctl_return = + get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer ); + break; + case FBIOPUT_VSCREENINFO: + /* not implemented yet */ + args->ioctl_return = -1; + return RTEMS_UNSATISFIED; + case FBIOGETCMAP: + /* no palette - truecolor mode */ + args->ioctl_return = -1; + return RTEMS_UNSATISFIED; + case FBIOPUTCMAP: + /* no palette - truecolor mode */ + args->ioctl_return = -1; + return RTEMS_UNSATISFIED; + default: + args->ioctl_return = 0; + break; + } + return RTEMS_SUCCESSFUL; +} diff --git a/bsps/i386/pc386/console/fb_vga.c b/bsps/i386/pc386/console/fb_vga.c new file mode 100644 index 0000000000..75ad56eb98 --- /dev/null +++ b/bsps/i386/pc386/console/fb_vga.c @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2000 - Rosimildo da Silva ( rdasilva@connecttel.com ) + * + * MODULE DESCRIPTION: + * This module implements FB driver for "Bare VGA". It uses the + * routines for "bare hardware" found in vgainit.c. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +/* these routines are defined in vgainit.c.*/ +extern void ega_hwinit( void ); +extern void ega_hwterm( void ); + +/* flag to limit driver to protect against multiple opens */ +static Atomic_Flag driver_mutex; + +/* screen information for the VGA driver */ +static struct fb_var_screeninfo fb_var = +{ + .xres = 640, + .yres = 480, + .bits_per_pixel = 4 +}; + +static struct fb_fix_screeninfo fb_fix = +{ + .smem_start = (volatile char *)0xA0000, /* buffer pointer */ + .smem_len = 0x10000, /* buffer size */ + .type = FB_TYPE_VGA_PLANES, /* type of dsplay */ + .visual = FB_VISUAL_PSEUDOCOLOR, /* color scheme used */ + .line_length = 80 /* chars per line */ +}; + + +static uint16_t red16[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, + 0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff +}; +static uint16_t green16[] = { + 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa, + 0x5555, 0x5555, 0xffff, 0xffff, 0x5555, 0x5555, 0xffff, 0xffff +}; +static uint16_t blue16[] = { + 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, + 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff +}; + +/* Functionality to support multiple VGA frame buffers can be added easily, + * but is not supported at this moment because there is no need for two or + * more "classic" VGA adapters. Multiple frame buffer drivers may be + * implemented and If we had implement it they would be named as "/dev/fb0", + * "/dev/fb1", "/dev/fb2" and so on. + */ +/* + * fbvga device driver INITIALIZE entry point. + */ +rtems_device_driver frame_buffer_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + + printk( "FBVGA -- driver initializing..\n" ); + + /* + * Register the device + */ + status = rtems_io_register_name (FRAMEBUFFER_DEVICE_0_NAME, major, 0); + if (status != RTEMS_SUCCESSFUL) { + printk("Error registering " FRAMEBUFFER_DEVICE_0_NAME + " FBVGA framebuffer device!\n"); + rtems_fatal_error_occurred( status ); + } + + _Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE); + + return RTEMS_SUCCESSFUL; +} + +/* + * fbvga device driver OPEN entry point + */ +rtems_device_driver frame_buffer_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + if (_Atomic_Flag_test_and_set(&driver_mutex, ATOMIC_ORDER_ACQUIRE) != 0 ) { + /* restore previous state. for VGA this means return to text mode. + * leave out if graphics hardware has been initialized in + * frame_buffer_initialize() + */ + ega_hwinit(); + printk( "FBVGA open called.\n" ); + return RTEMS_SUCCESSFUL; + } + + return RTEMS_UNSATISFIED; +} + +/* + * fbvga device driver CLOSE entry point + */ +rtems_device_driver frame_buffer_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + _Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE); + /* restore previous state. for VGA this means return to text mode. + * leave out if graphics hardware has been initialized in + * frame_buffer_initialize() */ + ega_hwterm(); + printk( "FBVGA close called.\n" ); + return RTEMS_SUCCESSFUL; + +/* + * fbvga device driver READ entry point. + */ +rtems_device_driver frame_buffer_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; + rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count; + memcpy(rw_args->buffer, (const void *) (fb_fix.smem_start + rw_args->offset), rw_args->bytes_moved); + return RTEMS_SUCCESSFUL; +} + +/* + * frame_buffer device driver WRITE entry point. + */ +rtems_device_driver frame_buffer_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; + rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count; + memcpy( (void *) (fb_fix.smem_start + rw_args->offset), rw_args->buffer, rw_args->bytes_moved); + return RTEMS_SUCCESSFUL; +} + +static int get_fix_screen_info( struct fb_fix_screeninfo *info ) +{ + *info = fb_fix; + return 0; +} + +static int get_var_screen_info( struct fb_var_screeninfo *info ) +{ + *info = fb_var; + return 0; +} + +static int get_palette( struct fb_cmap *cmap ) +{ + uint32_t i; + + if ( cmap->start + cmap->len >= 16 ) + return 1; + + for( i = 0; i < cmap->len; i++ ) { + cmap->red[ cmap->start + i ] = red16[ cmap->start + i ]; + cmap->green[ cmap->start + i ] = green16[ cmap->start + i ]; + cmap->blue[ cmap->start + i ] = blue16[ cmap->start + i ]; + } + return 0; +} + +static int set_palette( struct fb_cmap *cmap ) +{ + uint32_t i; + + if ( cmap->start + cmap->len >= 16 ) + return 1; + + for( i = 0; i < cmap->len; i++ ) { + red16[ cmap->start + i ] = cmap->red[ cmap->start + i ]; + green16[ cmap->start + i ] = cmap->green[ cmap->start + i ]; + blue16[ cmap->start + i ] = cmap->blue[ cmap->start + i ]; + } + return 0; +} + +/* + * IOCTL entry point -- This method is called to carry + * all services of this interface. + */ +rtems_device_driver frame_buffer_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_libio_ioctl_args_t *args = arg; + + printk( "FBVGA ioctl called, cmd=%x\n", args->command ); + + switch( args->command ) { + case FBIOGET_FSCREENINFO: + args->ioctl_return = get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer ); + break; + case FBIOGET_VSCREENINFO: + args->ioctl_return = get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer ); + break; + case FBIOPUT_VSCREENINFO: + /* not implemented yet*/ + args->ioctl_return = -1; + return RTEMS_UNSATISFIED; + case FBIOGETCMAP: + args->ioctl_return = get_palette( ( struct fb_cmap * ) args->buffer ); + break; + case FBIOPUTCMAP: + args->ioctl_return = set_palette( ( struct fb_cmap * ) args->buffer ); + break; + + default: + args->ioctl_return = 0; + break; + } + return RTEMS_SUCCESSFUL; +} diff --git a/bsps/i386/pc386/console/gdb_select.c b/bsps/i386/pc386/console/gdb_select.c new file mode 100644 index 0000000000..0fe3b2cdad --- /dev/null +++ b/bsps/i386/pc386/console/gdb_select.c @@ -0,0 +1,170 @@ +/** + * @file + * + * @ingroup GDB + * + * @brief pc386 gdb select + * + * This file contains a routine to enable and select the UART the gdb stub + * connects too. Currently limited to COM1 and COM2. See + * shared/comm/i386-stub-glue.c file. + */ + +/* + * COPYRIGHT (c) 2016. + * Chris Johns + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../../shared/dev/serial/legacy-console.h" + +/* + * Used in the stub to print output. + */ +int remote_debug; +/* + * Defined in the stub, used here. + */ +void set_debug_traps(void); + +/* + * Added here to get a valid baudrate. Needs to go once we + * move to the standard UART driver. + */ +int BSPBaseBaud; + +static bool gdb_port_probe(int minor) +{ + /* Return false as GDB has claimed the port */ + return false; +} + +void pc386_parse_gdb_arguments(void) +{ + static const char *opt; + + /* + * Check the command line to see if com1-com4 are disabled. + */ + opt = bsp_cmdline_arg("--gdb="); + if ( opt ) { + const char *option; + const char *comma; + size_t length; + size_t index; + rtems_device_minor_number minor; + uint32_t baudrate = 115200; + bool halt = false; + console_tbl *port; + + /* + * Fine the length, there can be more command line visible. + */ + length = 0; + while ((opt[length] != ' ') && (opt[length] != '\0')) { + ++length; + if (length > NAME_MAX) { + printk("invalid option (--gdb): too long\n"); + return; + } + } + + /* + * Only match up to a comma or NULL + */ + index = 0; + while ((opt[index] != '=') && (index < length)) { + ++index; + } + + if (opt[index] != '=') { + printk("invalid option (--gdb): no equals\n"); + return; + } + + ++index; + option = &opt[index]; + + while ((opt[index] != ',') && (index < length)) { + ++index; + } + + if (opt[index] == ',') + comma = &opt[index]; + else + comma = NULL; + + length = &opt[index] - option; + + port = console_find_console_entry( option, length, &minor ); + + if ( port == NULL ) { + printk("invalid option (--gdb): port not found\n"); + return; + } + + if (comma) { + option = comma + 1; + baudrate = strtoul(option, 0, 10); + switch (baudrate) { + case 115200: + case 57600: + case 38400: + case 19200: + case 9600: + case 4800: + port->pDeviceParams = (void*) baudrate; + BSPBaseBaud = baudrate; /* REMOVE ME */ + break; + default: + printk("invalid option (--gdb): bad baudrate\n"); + return; + } + } + + /* + * Provide a probe that fails so the device is not part of termios. All + * functions are polling. + */ + port->deviceProbe = gdb_port_probe; + port->pDeviceFns = &ns16550_fns_polled; + + opt = bsp_cmdline_arg("--gdb-remote-debug"); + if ( opt ) { + remote_debug = 1; + } + + opt = bsp_cmdline_arg("--gdb-break"); + if ( opt ) { + halt = true; + } + + printk("GDB stub: enable %s%s%s\n", + port->sDeviceName, + remote_debug ? ", remote-debug" : "", + halt ? ", halting" : ""); + + i386_stub_glue_init(minor); + set_debug_traps(); + i386_stub_glue_init_breakin(); + + if ( halt ) { + printk("GDB stub: waiting for remote connection..\n"); + breakpoint(); + } + } +} diff --git a/bsps/i386/pc386/console/i386kbd.h b/bsps/i386/pc386/console/i386kbd.h new file mode 100644 index 0000000000..627b37c750 --- /dev/null +++ b/bsps/i386/pc386/console/i386kbd.h @@ -0,0 +1,192 @@ +/** + * @file + * + * @ingroup i386_pc386 + * + * @brief I386 keyboard definitions. + */ + +/* + * linux/include/asm-i386/keyboard.h + * + * Created 3 Nov 1996 by Geert Uytterhoeven + */ + +/* + * This file contains the i386 architecture specific keyboard definitions + */ + +#ifndef _I386_KEYBOARD_H +#define _I386_KEYBOARD_H + +#include + +#define KEYBOARD_IRQ 1 +#define DISABLE_KBD_DURING_INTERRUPTS 0 + +extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); +extern int pckbd_getkeycode(unsigned int scancode); +extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode); +extern char pckbd_unexpected_up(unsigned char keycode); +extern void pckbd_leds(unsigned char leds); +extern void pckbd_init_hw(void); +extern unsigned char pckbd_sysrq_xlate[128]; + +#define kbd_setkeycode pckbd_setkeycode +#define kbd_getkeycode pckbd_getkeycode +#define kbd_translate pckbd_translate +#define kbd_unexpected_up pckbd_unexpected_up +#define kbd_leds pckbd_leds +#define kbd_init_hw pckbd_init_hw +#define kbd_sysrq_xlate pckbd_sysrq_xlate + +#define SYSRQ_KEY 0x54 + +/* resource allocation */ +#define kbd_request_region() /* request_region(0x60, 16, "keyboard") */ +#define kbd_request_irq(handler) /* request_irq(KEYBOARD_IRQ, handler, 0, "keyboard", NULL) */ + +/* How to access the keyboard macros on this platform. */ +#define kbd_read_input() inb(KBD_DATA_REG) +#define kbd_read_status() inb(KBD_STATUS_REG) +#define kbd_write_output(val) outb(val, KBD_DATA_REG) +#define kbd_write_command(val) outb(val, KBD_CNTL_REG) + +/* Some stoneage hardware needs delays after some operations. */ +#define kbd_pause() do { } while(0) + +/* + * Machine specific bits for the PS/2 driver + */ + +#define AUX_IRQ 12 + +#define aux_request_irq(hand, dev_id) /* request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id) */ + +#define aux_free_irq(dev_id) /* free_irq(AUX_IRQ, dev_id) */ + +/* + * include/linux/pc_keyb.h + * + * PC Keyboard And Keyboard Controller + * + * (c) 1997 Martin Mares + */ + +/* + * Configuration Switches + */ + +#undef KBD_REPORT_ERR /* Report keyboard errors */ +#define KBD_REPORT_UNKN /* Report unknown scan codes */ +#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */ +#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */ +#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */ + +#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */ +#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */ +#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */ + +/* + * Internal variables of the driver + */ + +extern unsigned char pckbd_read_mask; +extern unsigned char aux_device_present; + +/* + * Keyboard Controller Registers on normal PCs. + */ + +#define KBD_STATUS_REG 0x64 /* Status register (R) */ +#define KBD_CNTL_REG 0x64 /* Controller command register (W) */ +#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */ + +/* + * Keyboard Controller Commands + */ + +#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */ +#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */ +#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */ +#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */ +#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */ +#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */ +#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */ +#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */ +#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */ +#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */ +#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if + initiated by the auxiliary device */ +#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */ + +/* + * Keyboard Commands + */ + +#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */ +#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */ +#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */ +#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */ +#define KBD_CMD_RESET 0xFF /* Reset */ + +/* + * Keyboard Replies + */ + +#define KBD_REPLY_POR 0xAA /* Power on reset */ +#define KBD_REPLY_ACK 0xFA /* Command ACK */ +#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */ + +/* + * Status Register Bits + */ + +#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */ +#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */ +#define KBD_STAT_SELFTEST 0x04 /* Self test successful */ +#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */ +#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */ +#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */ +#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */ +#define KBD_STAT_PERR 0x80 /* Parity error */ + +#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF) + +/* + * Controller Mode Register Bits + */ + +#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */ +#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */ +#define KBD_MODE_SYS 0x04 /* The system flag (?) */ +#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */ +#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */ +#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */ +#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */ +#define KBD_MODE_RFU 0x80 + +/* + * Mouse Commands + */ + +#define AUX_SET_RES 0xE8 /* Set resolution */ +#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */ +#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */ +#define AUX_GET_SCALE 0xE9 /* Get scaling factor */ +#define AUX_SET_STREAM 0xEA /* Set stream mode */ +#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */ +#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */ +#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */ +#define AUX_RESET 0xFF /* Reset aux device */ +#define AUX_ACK 0xFA /* Command byte ACK. */ + +#define AUX_BUF_SIZE 2048 /* This might be better divisible by + three to make overruns stay in sync + but then the read function would need + a lock etc - ick */ + +#define mark_bh(x) + +#endif /* _I386_KEYBOARD_H */ diff --git a/bsps/i386/pc386/console/inch.c b/bsps/i386/pc386/console/inch.c new file mode 100644 index 0000000000..f5d5079236 --- /dev/null +++ b/bsps/i386/pc386/console/inch.c @@ -0,0 +1,300 @@ +/*-------------------------------------------------------------------------+ +| inch.c v1.1 - PC386 BSP - 1997/08/07 ++--------------------------------------------------------------------------+ +| (C) Copyright 1997 - +| - NavIST Group - Real-Time Distributed Systems and Industrial Automation +| +| http://pandora.ist.utl.pt +| +| Instituto Superior Tecnico * Lisboa * PORTUGAL ++--------------------------------------------------------------------------+ +| Disclaimer: +| +| This file is provided "AS IS" without warranty of any kind, either +| expressed or implied. ++--------------------------------------------------------------------------+ +| This code is based on: +| inch.c,v 1.3 1995/12/19 20:07:25 joel Exp - go32 BSP +| With the following copyright notice: +| With the following copyright notice: +| ************************************************************************** +| * COPYRIGHT (c) 1989-1998. +| * On-Line Applications Research Corporation (OAR). +| * +| * The license and distribution terms for this file may be +| * found in the file LICENSE in this distribution or at +| * http://www.rtems.org/license/LICENSE. +| ************************************************************************** ++--------------------------------------------------------------------------*/ + +#include +#include +#include + +/*-------------------------------------------------------------------------+ +| Constants ++--------------------------------------------------------------------------*/ +#define KBD_CTL 0x61 /* -------------------------------- */ +#define KBD_DATA 0x60 /* Ports for PC keyboard controller */ +#define KBD_STATUS 0x64 /* -------------------------------- */ + +#define KBD_BUF_SIZE 256 + +/*-------------------------------------------------------------------------+ +| Global Variables ++--------------------------------------------------------------------------*/ +static char key_map[] = +{ + 0,033,'1','2','3','4','5','6','7','8','9','0','-','=','\b','\t', + 'q','w','e','r','t','y','u','i','o','p','[',']',015,0x80, + 'a','s','d','f','g','h','j','k','l',';',047,0140,0x80, + 0134,'z','x','c','v','b','n','m',',','.','/',0x80, + '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + 0x80,0x80,0x80,'0',0177 +}; /* Keyboard scancode -> character map with no modifiers. */ + +static char shift_map[] = +{ + 0,033,'!','@','#','$','%','^','&','*','(',')','_','+','\b','\t', + 'Q','W','E','R','T','Y','U','I','O','P','{','}',015,0x80, + 'A','S','D','F','G','H','J','K','L',':',042,'~',0x80, + '|','Z','X','C','V','B','N','M','<','>','?',0x80, + '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + 0x80,0x80,0x80,0x80,'7','8','9',0x80,'4','5','6',0x80, + '1','2','3','0',177 +}; /* Keyboard scancode -> character map with SHIFT key modifier. */ + +static unsigned short kbd_buffer[KBD_BUF_SIZE]; +static uint16_t kbd_first = 0; +static uint16_t kbd_last = 0; +static uint16_t kbd_end = KBD_BUF_SIZE - 1; + +/*-------------------------------------------------------------------------+ +| Function: _IBMPC_scankey +| Description: This function can be called during a poll for input, or by +| an ISR. Basically any time you want to process a keypress. +| Global Variables: key_map, shift_map. +| Arguments: outChar - character read in case of a valid reading, +| otherwise unchanged. +| Returns: TRUE in case a valid character has been read, +| FALSE otherwise. ++--------------------------------------------------------------------------*/ +static bool +_IBMPC_scankey(char *outChar) +{ + unsigned char inChar; + static int alt_pressed = 0; + static int ctrl_pressed = 0; + static int shift_pressed = 0; + static int caps_pressed = 0; + static int extended = 0; + + *outChar = '\0'; /* default value if we return false */ + + /* Read keyboard controller, toggle enable */ + inport_byte(KBD_CTL, inChar); + outport_byte(KBD_CTL, inChar & ~0x80); + outport_byte(KBD_CTL, inChar | 0x80); + outport_byte(KBD_CTL, inChar & ~0x80); + + /* See if it has data */ + inport_byte(KBD_STATUS, inChar); + if ((inChar & 0x01) == 0) + return false; + + /* Read the data. Handle nonsense with shift, control, etc. */ + inport_byte(KBD_DATA, inChar); + + if (extended) + extended--; + + switch (inChar) + { + case 0xe0: + extended = 2; + return false; + break; + + case 0x38: + alt_pressed = 1; + return false; + break; + case 0xb8: + alt_pressed = 0; + return false; + break; + + case 0x1d: + ctrl_pressed = 1; + return false; + break; + case 0x9d: + ctrl_pressed = 0; + return false; + break; + + case 0x2a: + if (extended) + return false; + case 0x36: + shift_pressed = 1; + return false; + break; + case 0xaa: + if (extended) + return false; + case 0xb6: + shift_pressed = 0; + return false; + break; + + case 0x3a: + caps_pressed = 1; + return false; + break; + case 0xba: + caps_pressed = 0; + return false; + break; + + case 0x53: + if (ctrl_pressed && alt_pressed) + bsp_reset(); /* ctrl+alt+del -> reboot */ + break; + + /* + * Ignore unrecognized keys--usually arrow and such + */ + default: + if ((inChar & 0x80) || (inChar > 0x39)) + /* High-bit on means key is being released, not pressed */ + return false; + break; + } /* switch */ + + /* Strip high bit, look up in our map */ + inChar &= 0x7f; + if (ctrl_pressed) + { + *outChar = key_map[inChar]; + *outChar &= 037; + } + else + { + *outChar = shift_pressed ? shift_map[inChar] : key_map[inChar]; + if (caps_pressed) + { + if (*outChar >= 'A' && *outChar <= 'Z') + *outChar += 'a' - 'A'; + else if (*outChar >= 'a' && *outChar <= 'z') + *outChar -= 'a' - 'A'; + } + } + + return true; +} /* _IBMPC_scankey */ + +/*-------------------------------------------------------------------------+ +| Function: _IBMPC_chrdy +| Description: Check keyboard ISR buffer and return character if not empty. +| Global Variables: kbd_buffer, kbd_first, kbd_last. +| Arguments: c - character read if keyboard buffer not empty, otherwise +| unchanged. +| Returns: TRUE if keyboard buffer not empty, FALSE otherwise. ++--------------------------------------------------------------------------*/ +static bool +_IBMPC_chrdy(char *c) +{ +#if CCJ_REMOVED_NO_IDEA_ABOUT_THIS_CODE_OR_COMMENT + /* FIX ME!!! It doesn't work without something like the following line. + Find out why! */ + printk(""); +#endif + + /* Check buffer our ISR builds */ + if (kbd_first != kbd_last) + { + *c = kbd_buffer[kbd_first]; + + kbd_first = (kbd_first + 1) % KBD_BUF_SIZE; + return true; + } + else + return false; +} /* _IBMPC_chrdy */ + +/*-------------------------------------------------------------------------+ +| Function: _IBMPC_inch +| Description: Poll keyboard until a character is ready and return it. +| Global Variables: None. +| Arguments: None. +| Returns: character read from keyboard. ++--------------------------------------------------------------------------*/ +char +_IBMPC_inch(void) +{ + char c; + while (!_IBMPC_chrdy(&c)) + continue; + + return c; +} /* _IBMPC_inch */ + +/* + * Routine that can be used before interrupt management is initialized. + */ +int BSP_wait_polled_input(void) +{ + char c; + while (!_IBMPC_scankey(&c)) + continue; + + return c; +} + +/* + * Check if a key has been pressed. This is a non-destructive + * call, meaning, it keeps the key in the buffer. + */ +int rtems_kbpoll( void ) +{ + int rc; + + /* + * The locking or disable of interrupts does not help + * there because if interrupts are enabled after leave of this + * function the state can change without notice anyway. + */ + RTEMS_COMPILER_MEMORY_BARRIER(); + + rc = ( kbd_first != kbd_last ) ? TRUE : FALSE; + + RTEMS_COMPILER_MEMORY_BARRIER(); + + return rc; +} + +int getch( void ) +{ + int c; + + while( kbd_first == kbd_last ) + { + rtems_task_wake_after( 10 ); + } + c = kbd_buffer[ kbd_first ]; + kbd_first = (kbd_first + 1) % KBD_BUF_SIZE; + return c; +} + +void add_to_queue( unsigned short b ) +{ + unsigned int next; + kbd_buffer[ kbd_last ] = b; + next = (kbd_last == kbd_end) ? 0 : kbd_last + 1; + if( next != kbd_first ) + { + kbd_last = next; + } +} diff --git a/bsps/i386/pc386/console/kbd_parser.c b/bsps/i386/pc386/console/kbd_parser.c new file mode 100644 index 0000000000..f3d2f9c55a --- /dev/null +++ b/bsps/i386/pc386/console/kbd_parser.c @@ -0,0 +1,47 @@ +/* + * The contents of this file were formerly in console.c which + * had the following copyright notice: + * + * (C) Copyright 1997 + * NavIST Group - Real-Time Distributed Systems and Industrial Automation + * http://pandora.ist.utl.pt + * Instituto Superior Tecnico * Lisboa * PORTUGAL + * + * The original code and subsequent modifications are: + * + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include + +/* adds a kbd message to the queue */ +static void kbd_parser( void *ptr, unsigned short keycode, unsigned long mods ) +{ + struct MW_UID_MESSAGE m; + struct kbd_struct * kbd = (struct kbd_struct *)ptr; + + m.type = MV_UID_KBD; + m.m.kbd.code = keycode; + m.m.kbd.modifiers = kbd->ledflagstate; + m.m.kbd.mode = kbd->kbdmode; + /* printk( "kbd: msg: keycode=%X, mod=%X\n", keycode, mods ); */ + + uid_send_message( &m ); +} + +void register_kbd_msg_queue( char *q_name, int port ) +{ + kbd_set_driver_handler( kbd_parser ); +} + +void unregister_kbd_msg_queue( int port ) +{ + kbd_set_driver_handler( NULL ); +} diff --git a/bsps/i386/pc386/console/keyboard.c b/bsps/i386/pc386/console/keyboard.c new file mode 100644 index 0000000000..0c8991b829 --- /dev/null +++ b/bsps/i386/pc386/console/keyboard.c @@ -0,0 +1,881 @@ +/* + * Rosimildo da Silva: rdasilva@connecttel.com + */ + +#include +#include +#include +#include "i386kbd.h" +#include +#include +#include +#include + +#define SIZE(x) (sizeof(x)/sizeof((x)[0])) + +#ifndef KBD_DEFMODE +#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META)) +#endif + +#ifndef KBD_DEFLEDS +/* + * Some laptops take the 789uiojklm,. keys as number pad when NumLock + * is on. This seems a good reason to start with NumLock off. + */ +#define KBD_DEFLEDS 0 +#endif + +#ifndef KBD_DEFLOCK +#define KBD_DEFLOCK 0 +#endif + +static int kbd_test_and_set_bit(int nr, atomic_uint_least32_t * addr) +{ + uint_least32_t mask; + int retval; + + addr += nr >> 5; + mask = 1UL << (nr & 0x1f); + + retval = (atomic_fetch_or(addr, mask) & mask) != 0; + + return retval; +} + +static int kbd_test_and_clear_bit(int nr, atomic_uint_least32_t * addr) +{ + uint_least32_t mask; + int retval; + + addr += nr >> 5; + mask = 1UL << (nr & 0x1f); + + retval = (atomic_fetch_and(addr, ~mask) & mask) != 0; + + return retval; +} + +static int kbd_test_bit(int nr, atomic_uint_least32_t * addr) +{ + unsigned long mask; + + addr += nr >> 5; + mask = 1 << (nr & 0x1f); + return ((mask & atomic_load(addr)) != 0); +} + +/* + * global state includes the following, and various static variables + * in this module: prev_scancode, shift_state, diacr, npadch, dead_key_next. + * (last_console is now a global variable) + */ +#define KBD_BITS_PER_ELEMENT (sizeof(atomic_uint_least32_t)*CHAR_BIT) + +/* shift state counters.. */ +static unsigned char k_down[NR_SHIFT] = {0, }; +/* keyboard key bitmap */ +static atomic_uint_least32_t + key_down[(256 + KBD_BITS_PER_ELEMENT - 1) / KBD_BITS_PER_ELEMENT] = { 0, }; + +static int dead_key_next = 0; +/* + * In order to retrieve the shift_state (for the mouse server), either + * the variable must be global, or a new procedure must be created to + * return the value. I chose the former way. + */ +int shift_state = 0; +static int npadch = -1; /* -1 or number assembled on pad */ +static unsigned char diacr = 0; +static char rep = 0; /* flag telling character repeat */ + +/* default console for RTEMS */ +static int fg_console = 0; + +struct kbd_struct kbd_table[MAX_NR_CONSOLES]; +static struct kbd_struct * kbd = kbd_table; + +void compute_shiftstate(void); + +typedef void (*k_hand)(unsigned char value, char up_flag); +typedef void (k_handfn)(unsigned char value, char up_flag); + +static k_handfn + do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift, + do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2, + do_ignore; + +static k_hand key_handler[16] = { + do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift, + do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2, + do_ignore, do_ignore +}; + +/* Key types processed even in raw modes */ + +#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT)) + +typedef void (*void_fnp)(void); +typedef void (void_fn)(void); + +static void show_mem(void) +{ +} +static void show_state(void) +{ +} + +static void_fn do_null, enter, show_ptregs, send_intr, lastcons, caps_toggle, + num, hold, scroll_forw, scroll_back, caps_on, compose, + SAK, decr_console, incr_console, spawn_console, bare_num; + +static void_fnp spec_fn_table[] = { + do_null, enter, show_ptregs, show_mem, + show_state, send_intr, lastcons, caps_toggle, + num, hold, scroll_forw, scroll_back, + bsp_reset, caps_on, compose, SAK, + decr_console, incr_console, spawn_console, bare_num +}; + +#define SPECIALS_ALLOWED_IN_RAW_MODE (1 << KVAL(K_SAK)) + +/* maximum values each key_handler can handle */ +const int max_vals[] = { + 255, SIZE(func_table) - 1, SIZE(spec_fn_table) - 1, NR_PAD - 1, + NR_DEAD - 1, 255, 3, NR_SHIFT - 1, + 255, NR_ASCII - 1, NR_LOCK - 1, 255, + NR_LOCK - 1, 255 +}; + +const int NR_TYPES = SIZE(max_vals); + +/* N.B. drivers/macintosh/mac_keyb.c needs to call put_queue */ +static void put_queue(int); +static unsigned char handle_diacr(unsigned char); + +#ifdef CONFIG_MAGIC_SYSRQ +static int sysrq_pressed; +#endif + +/* + * Many other routines do put_queue, but I think either + * they produce ASCII, or they produce some user-assigned + * string, and in both cases we might assume that it is + * in utf-8 already. + */ +static void to_utf8(ushort c) +{ + if (c < 0x80) + put_queue(c); /* 0******* */ + else if (c < 0x800) { + put_queue(0xc0 | (c >> 6)); /* 110***** 10****** */ + put_queue(0x80 | (c & 0x3f)); + } else { + put_queue(0xe0 | (c >> 12)); /* 1110**** 10****** 10****** */ + put_queue(0x80 | ((c >> 6) & 0x3f)); + put_queue(0x80 | (c & 0x3f)); + } + /* UTF-8 is defined for words of up to 31 bits, + but we need only 16 bits here */ +} + +/* + * Translation of escaped scancodes to keycodes. + * This is now user-settable (for machines were it makes sense). + */ + +int setkeycode(unsigned int scancode, unsigned int keycode) +{ + return kbd_setkeycode(scancode, keycode); +} + +int getkeycode(unsigned int scancode) +{ + return kbd_getkeycode(scancode); +} + +void handle_scancode(unsigned char scancode, int down) +{ + unsigned char keycode; + char up_flag = down ? 0 : 0200; + char raw_mode; + + mark_bh(CONSOLE_BH); + +#if 0 + tty = ttytab? ttytab[fg_console]: NULL; + if (tty && (!tty->driver_data)) { + /* + * We touch the tty structure via the the ttytab array + * without knowing whether or not tty is open, which + * is inherently dangerous. We currently rely on that + * fact that console_open sets tty->driver_data when + * it opens it, and clears it when it closes it. + */ + tty = NULL; + } +#endif + + kbd = kbd_table + fg_console; + if ((raw_mode = (kbd->kbdmode == VC_RAW))) { + put_queue(scancode | up_flag); + /* we do not return yet, because we want to maintain + the key_down array, so that we have the correct + values when finishing RAW mode or when changing VT's */ + } + + /* + * Convert scancode to keycode + */ + if (!kbd_translate(scancode, &keycode, raw_mode)) + return; + + /* + * At this point the variable `keycode' contains the keycode. + * Note: the keycode must not be 0 (++Geert: on m68k 0 is valid). + * We keep track of the up/down status of the key, and + * return the keycode if in MEDIUMRAW mode. + */ + + if (up_flag) { + rep = 0; + if(!kbd_test_and_clear_bit(keycode, key_down)) + up_flag = kbd_unexpected_up(keycode); + } else + rep = kbd_test_and_set_bit(keycode, key_down); + +#ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */ + if (keycode == SYSRQ_KEY) { + sysrq_pressed = !up_flag; + return; + } else if (sysrq_pressed) { + if (!up_flag && sysrq_enabled) + handle_sysrq(kbd_sysrq_xlate[keycode], kbd_pt_regs, kbd, tty); + return; + } +#endif + + if (kbd->kbdmode == VC_MEDIUMRAW) { + /* soon keycodes will require more than one byte */ + put_queue(keycode + up_flag); + raw_mode = 1; /* Most key classes will be ignored */ + } + /* + * Small change in philosophy: earlier we defined repetition by + * rep = keycode == prev_keycode; + * prev_keycode = keycode; + * but now by the fact that the depressed key was down already. + * Does this ever make a difference? Yes. + */ + + /* + * Repeat a key only if the input buffers are empty or the + * characters get echoed locally. This makes key repeat usable + * with slow applications and under heavy loads. + */ + if (!rep || vc_kbd_mode(kbd,VC_REPEAT) ) { +/* + || (vc_kbd_mode(kbd,VC_REPEAT) && tty && + (L_ECHO(tty) || (tty->driver.chars_in_buffer(tty) == 0)))) { +*/ + u_short keysym; + u_char type; + + /* the XOR below used to be an OR */ + int shift_final = shift_state ^ kbd->lockstate ^ kbd->slockstate; + ushort *key_map = key_maps[shift_final]; + + if (key_map != NULL) { + keysym = key_map[keycode]; + type = KTYP(keysym); + + if (type >= 0xf0) { + type -= 0xf0; + if (raw_mode && ! (TYPES_ALLOWED_IN_RAW_MODE & (1 << type))) + return; + if (type == KT_LETTER) { + type = KT_LATIN; + if (vc_kbd_led(kbd, VC_CAPSLOCK)) { + key_map = key_maps[shift_final ^ (1<slockstate = 0; + + } else { + /* maybe only if (kbd->kbdmode == VC_UNICODE) ? */ + if (!up_flag && !raw_mode) + to_utf8(keysym); + } + } else { + /* maybe beep? */ + /* we have at least to update shift_state */ +#if 1 /* how? two almost equivalent choices follow */ + compute_shiftstate(); +#else + keysym = U(plain_map[keycode]); + type = KTYP(keysym); + if (type == KT_SHIFT) + (*key_handler[type])(keysym & 0xff, up_flag); +#endif + } + } +} + +static void ( *driver_input_handler_kbd )( void *, unsigned short, unsigned long ) = 0; +/* + */ +void kbd_set_driver_handler( + void ( *handler )( void *, unsigned short, unsigned long ) +) +{ + driver_input_handler_kbd = handler; +} + +static void put_queue(int ch) +{ + if ( driver_input_handler_kbd ) { + driver_input_handler_kbd( ( void *)kbd, (unsigned short)ch, 0 ); + } else { + add_to_queue( ch ); + } +} + +static void puts_queue(char *cp) +{ + while (*cp) { + put_queue( *cp ); + cp++; + } +} + +static void applkey(int key, char mode) +{ + static char buf[] = { 0x1b, 'O', 0x00, 0x00 }; + + buf[1] = (mode ? 'O' : '['); + buf[2] = key; + puts_queue(buf); +} + +static void enter(void) +{ + if (diacr) { + put_queue(diacr); + diacr = 0; + } + put_queue(13); + + if (vc_kbd_mode(kbd,VC_CRLF)) + put_queue(10); +} + +static void caps_toggle(void) +{ + if (rep) + return; + chg_vc_kbd_led(kbd, VC_CAPSLOCK); +} + +static void caps_on(void) +{ + if (rep) + return; + set_vc_kbd_led(kbd, VC_CAPSLOCK); +} + +static void show_ptregs(void) +{ +} + +static void hold(void) +{ + if (rep ) + return; + chg_vc_kbd_led(kbd, VC_SCROLLOCK ); +} + +static void num(void) +{ + if (vc_kbd_mode(kbd,VC_APPLIC)) + applkey('P', 1); + else + bare_num(); +} + +/* + * Bind this to Shift-NumLock if you work in application keypad mode + * but want to be able to change the NumLock flag. + * Bind this to NumLock if you prefer that the NumLock key always + * changes the NumLock flag. + */ +static void bare_num(void) +{ + if (!rep) + chg_vc_kbd_led(kbd,VC_NUMLOCK); +} + +static void lastcons(void) +{ +} + +static void decr_console(void) +{ +} + +static void incr_console(void) +{ +} + +static void send_intr(void) +{ +} + +static void scroll_forw(void) +{ +} + +static void scroll_back(void) +{ +} + +static void compose(void) +{ + dead_key_next = 1; +} + +int spawnpid, spawnsig; + +static void spawn_console(void) +{ +} + +static void SAK(void) +{ +} + +static void do_ignore(unsigned char value, char up_flag) +{ +} + +static void do_null() +{ + compute_shiftstate(); +} + +static void do_spec(unsigned char value, char up_flag) +{ + if (up_flag) + return; + if (value >= SIZE(spec_fn_table)) + return; + + if ((kbd->kbdmode == VC_RAW || kbd->kbdmode == VC_MEDIUMRAW) && + !(SPECIALS_ALLOWED_IN_RAW_MODE & (1 << value))) + return; + + spec_fn_table[value](); +} + +static void do_lowercase(unsigned char value, char up_flag) +{ +} + +static void do_self(unsigned char value, char up_flag) +{ + if (up_flag) + return; /* no action, if this is a key release */ + + if (diacr) + value = handle_diacr(value); + + if (dead_key_next) { + dead_key_next = 0; + diacr = value; + return; + } + put_queue(value); +} + +#define A_GRAVE '`' +#define A_ACUTE '\'' +#define A_CFLEX '^' +#define A_TILDE '~' +#define A_DIAER '"' +#define A_CEDIL ',' +static unsigned char ret_diacr[NR_DEAD] = + {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER, A_CEDIL }; + +/* Obsolete - for backwards compatibility only */ +static void do_dead(unsigned char value, char up_flag) +{ + value = ret_diacr[value]; + printk( " do_dead( %X ) ", value ); + do_dead2(value,up_flag); +} + +/* + * Handle dead key. Note that we now may have several + * dead keys modifying the same character. Very useful + * for Vietnamese. + */ +static void do_dead2(unsigned char value, char up_flag) +{ + if (up_flag) + return; + diacr = (diacr ? handle_diacr(value) : value); +} + +/* + * We have a combining character DIACR here, followed by the character CH. + * If the combination occurs in the table, return the corresponding value. + * Otherwise, if CH is a space or equals DIACR, return DIACR. + * Otherwise, conclude that DIACR was not combining after all, + * queue it and return CH. + */ +unsigned char handle_diacr(unsigned char ch) +{ + int d = diacr; + int i; + + diacr = 0; + + for (i = 0; i < accent_table_size; i++) { + if (accent_table[i].diacr == d && accent_table[i].base == ch) + return accent_table[i].result; + } + if (ch == ' ' || ch == d) + return d; + + put_queue(d); + return ch; +} + +static void do_cons(unsigned char value, char up_flag) +{ + if (up_flag) + return; +} + +static void do_fn(unsigned char value, char up_flag) +{ + if (up_flag) + return; + + if (value < SIZE(func_table)) { + if (func_table[value]) + puts_queue(func_table[value]); + } else + printk( "do_fn called with value=%d\n", value); +} + +static void do_pad(unsigned char value, char up_flag) +{ + static const char *pad_chars = "0123456789+-*/\015,.?()"; + static const char *app_map = "pqrstuvwxylSRQMnnmPQ"; + + if (up_flag) + return; /* no action, if this is a key release */ + + /* kludge... shift forces cursor/number keys */ + if (vc_kbd_mode(kbd,VC_APPLIC) && !k_down[KG_SHIFT]) { + applkey(app_map[value], 1); + return; + } + if (!vc_kbd_led(kbd,VC_NUMLOCK)) + switch (value) { + case KVAL(K_PCOMMA): + case KVAL(K_PDOT): + do_fn(KVAL(K_REMOVE), 0); + return; + case KVAL(K_P0): + do_fn(KVAL(K_INSERT), 0); + return; + case KVAL(K_P1): + do_fn(KVAL(K_SELECT), 0); + return; + case KVAL(K_P2): + do_cur(KVAL(K_DOWN), 0); + return; + case KVAL(K_P3): + do_fn(KVAL(K_PGDN), 0); + return; + case KVAL(K_P4): + do_cur(KVAL(K_LEFT), 0); + return; + case KVAL(K_P6): + do_cur(KVAL(K_RIGHT), 0); + return; + case KVAL(K_P7): + do_fn(KVAL(K_FIND), 0); + return; + case KVAL(K_P8): + do_cur(KVAL(K_UP), 0); + return; + case KVAL(K_P9): + do_fn(KVAL(K_PGUP), 0); + return; + case KVAL(K_P5): + applkey('G', vc_kbd_mode(kbd, VC_APPLIC)); + return; + } + + put_queue(pad_chars[value]); + + if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF)) + put_queue(10); + +} + +static void do_cur(unsigned char value, char up_flag) +{ + static const char *cur_chars = "BDCA"; + if (up_flag) + return; + + applkey(cur_chars[value], vc_kbd_mode(kbd,VC_CKMODE)); +} + +static void do_shift(unsigned char value, char up_flag) +{ + int old_state = shift_state; + + if (rep) + return; + + /* Mimic typewriter: + a CapsShift key acts like Shift but undoes CapsLock */ + if (value == KVAL(K_CAPSSHIFT)) { + value = KVAL(K_SHIFT); + if (!up_flag) + clr_vc_kbd_led(kbd, VC_CAPSLOCK); + } + + if (up_flag) { + /* handle the case that two shift or control + keys are depressed simultaneously */ + if (k_down[value]) + k_down[value]--; + } else + k_down[value]++; + + if (k_down[value]) + shift_state |= (1 << value); + else + shift_state &= ~ (1 << value); + + /* kludge */ + if (up_flag && shift_state != old_state && npadch != -1) { + if (kbd->kbdmode == VC_UNICODE) + to_utf8(npadch & 0xffff); + else + put_queue(npadch & 0xff); + npadch = -1; + } +} + +/* called after returning from RAW mode or when changing consoles - + recompute k_down[] and shift_state from key_down[] */ +/* maybe called when keymap is undefined, so that shiftkey release is seen */ +void compute_shiftstate(void) +{ + int i, j, k, sym, val; + + shift_state = 0; + for(i=0; i < SIZE(k_down); i++) + k_down[i] = 0; + + for(i=0; i < SIZE(key_down); i++) + if(atomic_load(key_down + i)) { /* skip this word if not a single bit on */ + k = i*KBD_BITS_PER_ELEMENT; + for(j=0; jledmode = LED_SHOW_IOCTL; + } else + ; + kbd->ledmode = LED_SHOW_FLAGS; + set_leds(); +} + +static struct ledptr { + unsigned int *addr; + unsigned int mask; + unsigned char valid:1; +} ledptrs[3]; + +void register_leds( + int console, + unsigned int led, + unsigned int *addr, + unsigned int mask +) +{ + struct kbd_struct *kbd = kbd_table + console; + + if (led < 3) { + ledptrs[led].addr = addr; + ledptrs[led].mask = mask; + ledptrs[led].valid = 1; + kbd->ledmode = LED_SHOW_MEM; + } else + kbd->ledmode = LED_SHOW_FLAGS; +} + +static inline unsigned char getleds(void) +{ + + struct kbd_struct *kbd = kbd_table + fg_console; + + unsigned char leds; + + if (kbd->ledmode == LED_SHOW_IOCTL) + return ledioctl; + leds = kbd->ledflagstate; + if (kbd->ledmode == LED_SHOW_MEM) { + if (ledptrs[0].valid) { + if (*ledptrs[0].addr & ledptrs[0].mask) + leds |= 1; + else + leds &= ~1; + } + if (ledptrs[1].valid) { + if (*ledptrs[1].addr & ledptrs[1].mask) + leds |= 2; + else + leds &= ~2; + } + if (ledptrs[2].valid) { + if (*ledptrs[2].addr & ledptrs[2].mask) + leds |= 4; + else + leds &= ~4; + } + } + return leds; +} + +/* + * This routine is the bottom half of the keyboard interrupt + * routine, and runs with all interrupts enabled. It does + * console changing, led setting and copy_to_cooked, which can + * take a reasonably long time. + * + * Aside from timing (which isn't really that important for + * keyboard interrupts as they happen often), using the software + * interrupt routines for this thing allows us to easily mask + * this when we don't want any of the above to happen. Not yet + * used, but this allows for easy and efficient race-condition + * prevention later on. + */ +static void kbd_bh(void) +{ + unsigned char leds = getleds(); + if (leds != ledstate) { + ledstate = leds; + kbd_leds(leds); + } +} + +void set_leds(void) +{ + kbd_bh(); +} + +int kbd_init(void) +{ + + int i; + struct kbd_struct kbd0; + kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS; + kbd0.ledmode = LED_SHOW_MEM; + kbd0.lockstate = KBD_DEFLOCK; + kbd0.slockstate = 0; + kbd0.modeflags = KBD_DEFMODE; + kbd0.kbdmode = VC_XLATE; + + for (i = 0 ; i < MAX_NR_CONSOLES ; i++) + kbd_table[i] = kbd0; + + kbd_init_hw(); + mark_bh(KEYBOARD_BH); + return 0; +} diff --git a/bsps/i386/pc386/console/outch.c b/bsps/i386/pc386/console/outch.c new file mode 100644 index 0000000000..90ffedf250 --- /dev/null +++ b/bsps/i386/pc386/console/outch.c @@ -0,0 +1,328 @@ +/* + * outch.c - This file contains code for displaying characters + * on the console uisng information that should be + * maintained by the BIOS in its data Area. + * + * Copyright (C) 1998 Eric Valette (valette@crf.canon.fr) + * Canon Centre Recherche France. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + * Till Straumann , 2003/9: + * - added handling of basic escape sequences (cursor movement + * and erasing; just enough for the line editor 'libtecla' to + * work...) + */ + +#include + +#include +#include + +#include + +extern void wr_cursor(int, unsigned short); + +#define TAB_SPACE 4 +static unsigned short *bitMapBaseAddr; +static unsigned short ioCrtBaseAddr; +static unsigned short maxCol; +static unsigned short maxRow; +static unsigned char row; +static unsigned char column; +static unsigned short attribute; +static unsigned int nLines; + +static void +scroll(void) +{ + int i, j; /* Counters */ + unsigned short *pt_scroll, *pt_bitmap; /* Pointers on the bit-map */ + + pt_bitmap = bitMapBaseAddr; + j = 0; + pt_bitmap = pt_bitmap + j; + pt_scroll = pt_bitmap + maxCol; + for (i = j; i < (maxRow - 1) * maxCol; i++) { + *pt_bitmap++ = *pt_scroll++; + } + + /* + * Blank characters are displayed on the last line. + */ + for (i = 0; i < maxCol; i++) { + *pt_bitmap++ = (short) (' ' | attribute); + } +} + +static void +doCRNL(int cr, int nl) +{ + if (nl) { + if (++row == maxRow) { + scroll(); /* Scroll the screen now */ + row = maxRow - 1; + } + nLines++; + } + if (cr) + column = 0; + /* Move cursor on the next location */ + if (cr || nl) + wr_cursor(row * maxCol + column, ioCrtBaseAddr); +} + +int (*videoHook)(char, int *)=0; + +static void +advanceCursor(void) +{ + if (++column == maxCol) + doCRNL(1,1); + else + wr_cursor(row * maxCol + column, ioCrtBaseAddr); +} + +static void +gotorc(int r, int c) +{ + column = c; + row = r; + + wr_cursor(row * maxCol + column, ioCrtBaseAddr); +} + +#define ESC ((char)27) +/* erase current location without moving the cursor */ +#define BLANK ((char)0x7f) + +static void +videoPutChar(char car) +{ + unsigned short *pt_bitmap = bitMapBaseAddr + row * maxCol + column; + + switch (car) { + case '\b': { + if (column) column--; + /* Move cursor on the previous location */ + wr_cursor(row * maxCol + column, ioCrtBaseAddr); + return; + } + case '\t': { + int i; + + i = TAB_SPACE - (column & (TAB_SPACE - 1)); + column += i; + if (column >= maxCol) { + doCRNL(1,1); + return; + } + while (i--) *pt_bitmap++ = ' ' | attribute; + wr_cursor(row * maxCol + column, ioCrtBaseAddr); + return; + } + case '\n': { + doCRNL(0,1); + return; + } + case 7: { /* Bell code must be inserted here */ + return; + } + case '\r' : { + doCRNL(1,0); + return; + } + case BLANK: { + *pt_bitmap = ' ' | attribute; + /* DONT move the cursor... */ + return; + } + default: { + *pt_bitmap = (unsigned char)car | attribute; + advanceCursor(); + return; + } + } +} + +/* trivial state machine to handle escape sequences: + * + * --------------------------------- + * | | + * | | + * KEY: esc V [ DCABHKJ esc | + * STATE: 0 -----> 27 -----> '[' ----------> -1 ----- + * ^\ \ \ \ + * KEY: | \other \ other \ other \ other + * <------------------------------------- + * + * in state '-1', the DCABHKJ cases are handled + * + * (cursor motion and screen clearing) + */ + +#define DONE (-1) + +static int +handleEscape(int oldState, char car) +{ +int rval = 0; +int ro,co; + + switch ( oldState ) { + case DONE: /* means the previous char terminated an ESC sequence... */ + case 0: + if ( 27 == car ) { + rval = 27; /* START of an ESC sequence */ + } + break; + + case 27: + if ( '[' == car ) { + rval = car; /* received ESC '[', so far */ + } else { + /* dump suppressed 'ESC'; outch will append the char */ + videoPutChar(ESC); + } + break; + + case '[': + /* handle 'ESC' '[' sequences here */ + ro = row; co = column; + rval = DONE; /* done */ + + switch (car) { + case 'D': /* left */ + if ( co > 0 ) co--; + break; + case 'C': /* right */ + if ( co < maxCol ) co++; + break; + case 'A': /* up */ + if ( ro > 0 ) ro--; + break; + case 'B': /* down */ + if ( ro < maxRow ) ro++; + break; + case 'H': /* home */ + ro = co = 0; + break; + case 'K': /* clear to end of line */ + while ( column < maxCol - 1 ) + videoPutChar(' '); + videoPutChar(BLANK); + break; + case 'J': /* clear to end of screen */ + while ( ((row < maxRow-1) || (column < maxCol-1)) ) + videoPutChar(' '); + videoPutChar(BLANK); + break; + default: + videoPutChar(ESC); + videoPutChar('['); + /* DONT move the cursor */ + ro = -1; + rval = 0; + break; + } + /* reset cursor */ + if ( ro >= 0) + gotorc(ro,co); + + default: + break; + + } + + return rval; +} + +static void +clear_screen(void) +{ + int i,j; + + for (j = 0; j <= maxRow; j++) { + for (i = 0; i <= maxCol; i++) { + videoPutChar(' '); + } + } + column = 0; + row = 0; +} + +/*-------------------------------------------------------------------------+ +| Function: _IBMPC_outch +| Description: Higher level (console) interface to consPutc. +| Global Variables: None. +| Arguments: c - character to write to console. +| Returns: Nothing. ++--------------------------------------------------------------------------*/ +void +_IBMPC_outch(char c) +{ +static int escaped = 0; + + if ( ! (escaped = handleEscape(escaped, c)) ) { + if ( '\n' == c ) + videoPutChar('\r'); + videoPutChar(c); + } +} /* _IBMPC_outch */ + +/*-------------------------------------------------------------------------+ +| Function: _IBMPC_initVideo +| Description: Video system initialization. Hook for any early setup. +| Global Variables: bitMapBaseAddr, ioCrtBaseAddr, maxCol, maxRow, row +| column, attribute, nLines; +| Arguments: None. +| Returns: Nothing. ++--------------------------------------------------------------------------*/ +void +_IBMPC_initVideo(void) +{ + unsigned char* pt = (unsigned char*) (VIDEO_MODE_ADDR); + + if (*pt == VGAMODE7) { + bitMapBaseAddr = (unsigned short*) V_MONO; + } + else { + bitMapBaseAddr = (unsigned short*) V_COLOR; + } + ioCrtBaseAddr = *(unsigned short*) DISPLAY_CRT_BASE_IO_ADDR; + maxCol = * (unsigned short*) NB_MAX_COL_ADDR; + maxRow = * (unsigned char*) NB_MAX_ROW_ADDR; + column = 0; + row = 0; + attribute = ((BLACK << 4) | WHITE)<<8; + nLines = 0; + clear_screen(); +#ifdef DEBUG_EARLY_STAGE + printk("bitMapBaseAddr = %X, display controller base IO = %X\n", + (unsigned) bitMapBaseAddr, + (unsigned) ioCrtBaseAddr); + videoPrintf("maxCol = %d, maxRow = %d\n", (unsigned) maxCol, (unsigned) maxRow); +#endif +} /* _IBMPC_initVideo */ + +/* for old DOS compatibility n-curses type of applications */ +void gotoxy( int x, int y ); +int whereX( void ); +int whereY( void ); + +void gotoxy( int x, int y ) +{ + gotorc(y,x); +} + +int whereX( void ) +{ + return row; +} + +int whereY( void ) +{ + return column; +} diff --git a/bsps/i386/pc386/console/pc_keyb.c b/bsps/i386/pc386/console/pc_keyb.c new file mode 100644 index 0000000000..b6f0eb216a --- /dev/null +++ b/bsps/i386/pc386/console/pc_keyb.c @@ -0,0 +1,627 @@ +/* + * linux/drivers/char/pc_keyb.c + * + * Separation of the PC low-level part by Geert Uytterhoeven, May 1997 + * See keyboard.c for the whole history. + * + * Major cleanup by Martin Mares, May 1997 + * + * Combined the keyboard and PS/2 mouse handling into one file, + * because they share the same hardware. + * Johan Myreen 1998-10-08. + * + * Code fixes to handle mouse ACKs properly. + * C. Scott Ananian 1999-01-29. + * + * Ported to RTEMS by Rosimildo da Silva + */ + +#include +#include +#include + +#include +#include +#include "i386kbd.h" + +static unsigned char handle_kbd_event(void); +static void kbd_write_command_w(int data); +static void kbd_write_output_w(int data); + +/* Some configuration switches are present in the include file... */ + +/* Simple translation table for the SysRq keys */ + +#ifdef CONFIG_MAGIC_SYSRQ +unsigned char pckbd_sysrq_xlate[128] = + "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */ + "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */ + "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */ + "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */ + "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */ + "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ + "\r\000/"; /* 0x60 - 0x6f */ +#endif + +/* used only by send_data - set by keyboard_interrupt */ +static volatile unsigned char reply_expected = 0; +static volatile unsigned char acknowledge = 0; +static volatile unsigned char resend = 0; + +/* + * Translation of escaped scancodes to keycodes. + * This is now user-settable. + * The keycodes 1-88,96-111,119 are fairly standard, and + * should probably not be changed - changing might confuse X. + * X also interprets scancode 0x5d (KEY_Begin). + * + * For 1-88 keycode equals scancode. + */ + +#define E0_KPENTER 96 +#define E0_RCTRL 97 +#define E0_KPSLASH 98 +#define E0_PRSCR 99 +#define E0_RALT 100 +#define E0_BREAK 101 /* (control-pause) */ +#define E0_HOME 102 +#define E0_UP 103 +#define E0_PGUP 104 +#define E0_LEFT 105 +#define E0_RIGHT 106 +#define E0_END 107 +#define E0_DOWN 108 +#define E0_PGDN 109 +#define E0_INS 110 +#define E0_DEL 111 + +#define E1_PAUSE 119 + +/* + * The keycodes below are randomly located in 89-95,112-118,120-127. + * They could be thrown away (and all occurrences below replaced by 0), + * but that would force many users to use the `setkeycodes' utility, where + * they needed not before. It does not matter that there are duplicates, as + * long as no duplication occurs for any single keyboard. + */ +#define SC_LIM 89 + +#define FOCUS_PF1 85 /* actual code! */ +#define FOCUS_PF2 89 +#define FOCUS_PF3 90 +#define FOCUS_PF4 91 +#define FOCUS_PF5 92 +#define FOCUS_PF6 93 +#define FOCUS_PF7 94 +#define FOCUS_PF8 95 +#define FOCUS_PF9 120 +#define FOCUS_PF10 121 +#define FOCUS_PF11 122 +#define FOCUS_PF12 123 + +#define JAP_86 124 +/* tfj@olivia.ping.dk: + * The four keys are located over the numeric keypad, and are + * labelled A1-A4. It's an rc930 keyboard, from + * Regnecentralen/RC International, Now ICL. + * Scancodes: 59, 5a, 5b, 5c. + */ +#define RGN1 124 +#define RGN2 125 +#define RGN3 126 +#define RGN4 127 + +static unsigned char high_keys[128 - SC_LIM] = { + RGN1, RGN2, RGN3, RGN4, 0, 0, 0, /* 0x59-0x5f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */ + 0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12, /* 0x68-0x6f */ + 0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3, /* 0x70-0x77 */ + FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7, /* 0x78-0x7b */ + FOCUS_PF8, JAP_86, FOCUS_PF10, 0 /* 0x7c-0x7f */ +}; + +/* BTC */ +#define E0_MACRO 112 +/* LK450 */ +#define E0_F13 113 +#define E0_F14 114 +#define E0_HELP 115 +#define E0_DO 116 +#define E0_F17 117 +#define E0_KPMINPLUS 118 +/* + * My OmniKey generates e0 4c for the "OMNI" key and the + * right alt key does nada. [kkoller@nyx10.cs.du.edu] + */ +#define E0_OK 124 +/* + * New microsoft keyboard is rumoured to have + * e0 5b (left window button), e0 5c (right window button), + * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU] + * [or: Windows_L, Windows_R, TaskMan] + */ +#define E0_MSLW 125 +#define E0_MSRW 126 +#define E0_MSTM 127 + +static unsigned char e0_keys[128] = { + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */ + 0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0, /* 0x18-0x1f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */ + 0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR, /* 0x30-0x37 */ + E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP, /* 0x38-0x3f */ + E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME, /* 0x40-0x47 */ + E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */ + E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0, /* 0x50-0x57 */ + 0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0, /* 0x58-0x5f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */ + 0, 0, 0, 0, 0, 0, 0, E0_MACRO, /* 0x68-0x6f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */ + 0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */ +}; + +static void mdelay( unsigned long t ) +{ + Wait_X_ms( t ); +} + +int pckbd_setkeycode(unsigned int scancode, unsigned int keycode) +{ + if (scancode < SC_LIM || scancode > 255 || keycode > 127) + return -EINVAL; + if (scancode < 128) + high_keys[scancode - SC_LIM] = keycode; + else + e0_keys[scancode - 128] = keycode; + return 0; +} + +int pckbd_getkeycode(unsigned int scancode) +{ + return + (scancode < SC_LIM || scancode > 255) ? -EINVAL : + (scancode < 128) ? high_keys[scancode - SC_LIM] : + e0_keys[scancode - 128]; +} + +static int do_acknowledge(unsigned char scancode) +{ + if (reply_expected) { + /* Unfortunately, we must recognise these codes only if we know they + * are known to be valid (i.e., after sending a command), because there + * are some brain-damaged keyboards (yes, FOCUS 9000 again) which have + * keys with such codes :( + */ + if (scancode == KBD_REPLY_ACK) { + acknowledge = 1; + reply_expected = 0; + return 0; + } else if (scancode == KBD_REPLY_RESEND) { + resend = 1; + reply_expected = 0; + return 0; + } + /* Should not happen... */ + printk( "keyboard reply expected - got %02x\n", scancode); + } + return 1; +} + +int pckbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode) +{ + static int prev_scancode = 0; + + /* special prefix scancodes.. */ + if (scancode == 0xe0 || scancode == 0xe1) { + prev_scancode = scancode; + return 0; + } + + /* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */ + if (scancode == 0x00 || scancode == 0xff) { + prev_scancode = 0; + return 0; + } + + scancode &= 0x7f; + + if (prev_scancode) { + /* + * usually it will be 0xe0, but a Pause key generates + * e1 1d 45 e1 9d c5 when pressed, and nothing when released + */ + if (prev_scancode != 0xe0) { + if (prev_scancode == 0xe1 && scancode == 0x1d) { + prev_scancode = 0x100; + return 0; + } else if (prev_scancode == 0x100 && scancode == 0x45) { + *keycode = E1_PAUSE; + prev_scancode = 0; + } else { +#ifdef KBD_REPORT_UNKN + if (!raw_mode) + printk("keyboard: unknown e1 escape sequence\n"); +#endif + prev_scancode = 0; + return 0; + } + } else { + prev_scancode = 0; + /* + * The keyboard maintains its own internal caps lock and + * num lock statuses. In caps lock mode E0 AA precedes make + * code and E0 2A follows break code. In num lock mode, + * E0 2A precedes make code and E0 AA follows break code. + * We do our own book-keeping, so we will just ignore these. + */ + /* + * For my keyboard there is no caps lock mode, but there are + * both Shift-L and Shift-R modes. The former mode generates + * E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs. + * So, we should also ignore the latter. - aeb@cwi.nl + */ + if (scancode == 0x2a || scancode == 0x36) + return 0; + + if (e0_keys[scancode]) + *keycode = e0_keys[scancode]; + else { +#ifdef KBD_REPORT_UNKN + if (!raw_mode) + printk( "keyboard: unknown scancode e0 %02x\n", + scancode); +#endif + return 0; + } + } + } else if (scancode >= SC_LIM) { + /* This happens with the FOCUS 9000 keyboard + Its keys PF1..PF12 are reported to generate + 55 73 77 78 79 7a 7b 7c 74 7e 6d 6f + Moreover, unless repeated, they do not generate + key-down events, so we have to zero up_flag below */ + /* Also, Japanese 86/106 keyboards are reported to + generate 0x73 and 0x7d for \ - and \ | respectively. */ + /* Also, some Brazilian keyboard is reported to produce + 0x73 and 0x7e for \ ? and KP-dot, respectively. */ + + *keycode = high_keys[scancode - SC_LIM]; + if (!*keycode) { + if (!raw_mode) { +#ifdef KBD_REPORT_UNKN + printk( "keyboard: unrecognized scancode (%02x)" + " - ignored\n", scancode); +#endif + } + return 0; + } + } else + *keycode = scancode; + return 1; +} + +char pckbd_unexpected_up(unsigned char keycode) +{ + /* unexpected, but this can happen: maybe this was a key release for a + FOCUS 9000 PF key; if we want to see it, we have to clear up_flag */ + if (keycode >= SC_LIM || keycode == 85) + return 0; + else + return 0200; +} + +static void kb_wait(void) +{ + unsigned long timeout = KBC_TIMEOUT; + + do { + /* + * "handle_kbd_event()" will handle any incoming events + * while we wait - keypresses or mouse movement. + */ + unsigned char status = handle_kbd_event(); + + if (! (status & KBD_STAT_IBF)) + return; + mdelay(1); + timeout--; + } while (timeout); +#ifdef KBD_REPORT_TIMEOUTS + printk( "Keyboard timed out[1]\n"); +#endif +} + +/* + * This reads the keyboard status port, and does the + * appropriate action. + * + * It requires that we hold the keyboard controller + * spinlock. + */ +static unsigned char handle_kbd_event(void) +{ + unsigned char status = kbd_read_status(); + unsigned int work = 10000; + + while (status & KBD_STAT_OBF) { + unsigned char scancode; + + scancode = kbd_read_input(); + if (status & KBD_STAT_MOUSE_OBF) { +#if 0 + handle_mouse_event(scancode); +#endif + } else { + if (do_acknowledge(scancode)) + handle_scancode(scancode, !(scancode & 0x80)); + mark_bh(KEYBOARD_BH); + } + + status = kbd_read_status(); + + if(!work--) + { + printk( "pc_keyb: controller jammed (0x%02X).\n", status); + break; + } + return status; + } + + /* + * the commands to set the leds for some reason, returns 0x14, 0x16 + * and I am intepreting as an ACK, because the original code from + * Linux was timeing out here... + */ + acknowledge = 1; + reply_expected = 0; + resend = 0; + return status; +} + +void keyboard_interrupt(void *unused) +{ + handle_kbd_event(); +} + +/* + * send_data sends a character to the keyboard and waits + * for an acknowledge, possibly retrying if asked to. Returns + * the success status. + * + * Don't use 'jiffies', so that we don't depend on interrupts + */ +static int send_data(unsigned char data) +{ + int retries = 3; + + do { + unsigned long timeout = KBD_TIMEOUT; + + acknowledge = 0; /* Set by interrupt routine on receipt of ACK. */ + resend = 0; + reply_expected = 1; + kbd_write_output_w(data); + for (;;) { + if (acknowledge) + return 1; + if (resend) + break; + mdelay(1); + if (!--timeout) { +#ifdef KBD_REPORT_TIMEOUTS + printk("Keyboard timeout[2]\n"); +#endif + return 0; + } + } + } while (retries-- > 0); +#ifdef KBD_REPORT_TIMEOUTS + printk( "keyboard: Too many NACKs -- noisy kbd cable?\n"); +#endif + return 0; +} + +void pckbd_leds(unsigned char leds) +{ + if (!send_data(KBD_CMD_SET_LEDS) || !send_data(leds)) + send_data(KBD_CMD_ENABLE); /* re-enable kbd if any errors */ +} + +/* + * In case we run on a non-x86 hardware we need to initialize both the + * keyboard controller and the keyboard. On a x86, the BIOS will + * already have initialized them. + * + * Some x86 BIOSes do not correctly initialize the keyboard, so the + * "kbd-reset" command line options can be given to force a reset. + * [Ranger] + */ +#ifdef __i386__ + int kbd_startup_reset = 0; +#else + int kbd_startup_reset = 1; +#endif + +/* for "kbd-reset" cmdline param */ +void kbd_reset_setup(char *str, int *ints) +{ + kbd_startup_reset = 1; +} + +#define KBD_NO_DATA (-1) /* No data */ +#define KBD_BAD_DATA (-2) /* Parity or other error */ + +static int kbd_read_data(void) +{ + int retval = KBD_NO_DATA; + unsigned char status; + + status = kbd_read_status(); + if (status & KBD_STAT_OBF) { + unsigned char data = kbd_read_input(); + + retval = data; + if (status & (KBD_STAT_GTO | KBD_STAT_PERR)) + retval = KBD_BAD_DATA; + } + return retval; +} + +static void kbd_clear_input(void) +{ + int maxread = 100; /* Random number */ + + do { + if (kbd_read_data() == KBD_NO_DATA) + break; + } while (--maxread); +} + +static int kbd_wait_for_input(void) +{ + long timeout = KBD_INIT_TIMEOUT; + + do { + int retval = kbd_read_data(); + if (retval >= 0) + return retval; + mdelay(1); + } while (--timeout); + return -1; +} + +static void kbd_write_command_w(int data) +{ + kb_wait(); + kbd_write_command(data); +} + +static void kbd_write_output_w(int data) +{ + kb_wait(); + kbd_write_output(data); +} + +static char * initialize_kbd(void) +{ + int status; + + /* + * Test the keyboard interface. + * This seems to be the only way to get it going. + * If the test is successful a x55 is placed in the input buffer. + */ + kbd_write_command_w(KBD_CCMD_SELF_TEST); + if (kbd_wait_for_input() != 0x55) + return "Keyboard failed self test"; + + /* + * Perform a keyboard interface test. This causes the controller + * to test the keyboard clock and data lines. The results of the + * test are placed in the input buffer. + */ + kbd_write_command_w(KBD_CCMD_KBD_TEST); + if (kbd_wait_for_input() != 0x00) + return "Keyboard interface failed self test"; + + /* + * Enable the keyboard by allowing the keyboard clock to run. + */ + kbd_write_command_w(KBD_CCMD_KBD_ENABLE); + + /* + * Reset keyboard. If the read times out + * then the assumption is that no keyboard is + * plugged into the machine. + * This defaults the keyboard to scan-code set 2. + * + * Set up to try again if the keyboard asks for RESEND. + */ + do { + kbd_write_output_w(KBD_CMD_RESET); + status = kbd_wait_for_input(); + if (status == KBD_REPLY_ACK) + break; + if (status != KBD_REPLY_RESEND) + return "Keyboard reset failed, no ACK"; + } while (1); + + if (kbd_wait_for_input() != KBD_REPLY_POR) + return "Keyboard reset failed, no POR"; + + /* + * Set keyboard controller mode. During this, the keyboard should be + * in the disabled state. + * + * Set up to try again if the keyboard asks for RESEND. + */ + do { + kbd_write_output_w(KBD_CMD_DISABLE); + status = kbd_wait_for_input(); + if (status == KBD_REPLY_ACK) + break; + if (status != KBD_REPLY_RESEND) + return "Disable keyboard: no ACK"; + } while (1); + + kbd_write_command_w(KBD_CCMD_WRITE_MODE); + kbd_write_output_w(KBD_MODE_KBD_INT + | KBD_MODE_SYS + | KBD_MODE_DISABLE_MOUSE + | KBD_MODE_KCC); + + /* ibm powerpc portables need this to use scan-code set 1 -- Cort */ + kbd_write_command_w(KBD_CCMD_READ_MODE); + if (!(kbd_wait_for_input() & KBD_MODE_KCC)) { + /* + * If the controller does not support conversion, + * Set the keyboard to scan-code set 1. + */ + kbd_write_output_w(0xF0); + kbd_wait_for_input(); + kbd_write_output_w(0x01); + kbd_wait_for_input(); + } + + kbd_write_output_w(KBD_CMD_ENABLE); + if (kbd_wait_for_input() != KBD_REPLY_ACK) + return "Enable keyboard: no ACK"; + /* + * Finally, set the typematic rate to maximum. + */ + kbd_write_output_w(KBD_CMD_SET_RATE); + if (kbd_wait_for_input() != KBD_REPLY_ACK) + return "Set rate: no ACK"; + kbd_write_output_w(0x00); + if (kbd_wait_for_input() != KBD_REPLY_ACK) + return "Set rate: no ACK"; + return NULL; +} + +void pckbd_init_hw(void) +{ + /* kbd_request_region(); */ + + /* Flush any pending input. */ + kbd_clear_input(); + + if (kbd_startup_reset) { + char *msg = initialize_kbd(); + if (msg) + printk( "initialize_kbd: %s\n", msg); + } + +#if defined CONFIG_PSMOUSE + psaux_init(); +#endif + + /* Ok, finally allocate the IRQ, and off we go.. */ +#if 0 + kbd_request_irq( keyboard_interrupt ); +#endif + +} diff --git a/bsps/i386/pc386/console/printk_support.c b/bsps/i386/pc386/console/printk_support.c new file mode 100644 index 0000000000..d7bc329868 --- /dev/null +++ b/bsps/i386/pc386/console/printk_support.c @@ -0,0 +1,84 @@ +/* + * @file + * + * @ingroup Console + * + * @brief printk support routines + * + * This file contains the required printk support. + */ + +/* + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#if BSP_ENABLE_VGA + #include +#endif +#include +#include +#include +#include "../../shared/dev/serial/legacy-console.h" + +rtems_device_minor_number BSPPrintkPort = 0; + +void BSP_outch(char ch); +int BSP_inch(void); + +void BSP_outch(char ch) +{ + #if BSP_ENABLE_VGA + bool isVga = BSPPrintkPort == BSP_CONSOLE_VGA; + #else + bool isVga = false; + #endif + + if ( !isVga ) { + console_tbl *port = Console_Port_Tbl[BSPPrintkPort]; + if (port->pDeviceFns && port->pDeviceFns->deviceWritePolled) { + port->pDeviceFns->deviceWritePolled( BSPPrintkPort, ch ); + } + return; + } + + #if BSP_ENABLE_VGA + _IBMPC_outch( ch ); + #endif +} + +int BSP_inch(void) +{ + #if BSP_ENABLE_VGA + bool isVga = BSPPrintkPort == BSP_CONSOLE_VGA; + #else + bool isVga = false; + #endif + + int result = -1; + + if ( !isVga ) { + console_tbl *port = Console_Port_Tbl[BSPPrintkPort]; + if (port->pDeviceFns && port->pDeviceFns->deviceRead) { + do { + result = port->pDeviceFns->deviceRead( BSPPrintkPort ); + } while (result == -1); + return result; + } + } + + #if BSP_ENABLE_VGA + result = BSP_wait_polled_input(); + #endif + + return result; +} + +BSP_output_char_function_type BSP_output_char = BSP_outch; +BSP_polling_getchar_function_type BSP_poll_char = BSP_inch; diff --git a/bsps/i386/pc386/console/ps2_mouse.c b/bsps/i386/pc386/console/ps2_mouse.c new file mode 100644 index 0000000000..6a3f8551b4 --- /dev/null +++ b/bsps/i386/pc386/console/ps2_mouse.c @@ -0,0 +1,562 @@ +/* + * linux/drivers/char/pc_keyb.c + * Separation of the PC low-level part by Geert Uytterhoeven, May 1997 + * See keyboard.c for the whole history. + * Major cleanup by Martin Mares, May 1997 + * Combined the keyboard and PS/2 mouse handling into one file, + * because they share the same hardware. + * Johan Myreen 1998-10-08. + * Code fixes to handle mouse ACKs properly. + * C. Scott Ananian 1999-01-29. + * + * RTEMS port: by Rosimildo da Silva. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define INITIALIZE_MOUSE +/* Some configuration switches are present in the include file... */ +#include +#include "ps2_mouse.h" + +static void kbd_write_command_w(int data); +#if 0 +static void kbd_write_output_w(int data); +#endif + +static unsigned char handle_kbd_event(void); +static void ps2_set_driver_handler(int port, mouse_parser_enqueue_handler handler); + +/* used only by send_data - set by keyboard_interrupt */ +static volatile unsigned char reply_expected = 0; +static volatile unsigned char acknowledge = 0; +static volatile unsigned char resend = 0; + +/* + * PS/2 Auxiliary Device + */ +static int psaux_init(void); + +static struct aux_queue *queue; /* Mouse data buffer. */ +static int aux_count = 0; +/* used when we send commands to the mouse that expect an ACK. */ +static unsigned char mouse_reply_expected = 0; + +#define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT) +#define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT) +#define MAX_RETRIES 60 /* some aux operations take long time*/ + +static void ps2_mouse_interrupt(void *); +static mouse_parser_enqueue_handler driver_input_handler_ps2 = NULL; + +/* + * This routine sets the handler to handle the characters received + * from the serial port. + */ +static void ps2_set_driver_handler( + int port, + mouse_parser_enqueue_handler handler +) +{ + driver_input_handler_ps2 = handler; +} + +static void mdelay( unsigned long t ) +{ + Wait_X_ms( t ); +} + +static void* termios_ttyp_paux = NULL; + +/* + * Wait for keyboard controller input buffer to drain. + * + * Don't use 'jiffies' so that we don't depend on + * interrupts.. + * + * Quote from PS/2 System Reference Manual: + * + * "Address hex 0060 and address hex 0064 should be written only when + * the input-buffer-full bit and output-buffer-full bit in the + * Controller Status register are set 0." + */ + +static void kb_wait(void) +{ + unsigned long timeout = KBC_TIMEOUT; + + do { + /* + * "handle_kbd_event()" will handle any incoming events + * while we wait - keypresses or mouse movement. + */ + unsigned char status = handle_kbd_event(); + + if (! (status & KBD_STAT_IBF)) + return; + + mdelay(1); + timeout--; + } while (timeout); + + #ifdef KBD_REPORT_TIMEOUTS + printk( "Keyboard timed out[1]\n"); + #endif +} + +static int do_acknowledge(unsigned char scancode) +{ + if (reply_expected) { + + /* Unfortunately, we must recognise these codes only if we know they + * are known to be valid (i.e., after sending a command), because there + * are some brain-damaged keyboards (yes, FOCUS 9000 again) which have + * keys with such codes :( + */ + if (scancode == KBD_REPLY_ACK) { + acknowledge = 1; + reply_expected = 0; + return 0; + } else if (scancode == KBD_REPLY_RESEND) { + resend = 1; + reply_expected = 0; + return 0; + } + + /* Should not happen... */ + #if 0 + printk( "keyboard reply expected - got %02x\n", scancode); + #endif + } + return 1; +} + +static inline void handle_mouse_event(unsigned char scancode) +{ + if (mouse_reply_expected) { + if (scancode == AUX_ACK) { + mouse_reply_expected--; + return; + } + mouse_reply_expected = 0; + } + + if (aux_count) { + int head = queue->head; + queue->buf[head] = scancode; + head = (head + 1) & (AUX_BUF_SIZE-1); + if (head != queue->tail) { + queue->head = head; + } + + /* if the input queue is active, add to it */ + if( driver_input_handler_ps2 ) { + driver_input_handler_ps2( &scancode, 1 ); + } else { + /* post this byte to termios */ + rtems_termios_enqueue_raw_characters( termios_ttyp_paux, (char *)&scancode, 1 ); + } + } +} + +/* + * This reads the keyboard status port, and does the + * appropriate action. + * + * It requires that we hold the keyboard controller + * spinlock. + */ +static unsigned char handle_kbd_event(void) +{ + unsigned char status = kbd_read_status(); + unsigned int work = 10000; + + while (status & KBD_STAT_OBF) { + unsigned char scancode; + scancode = kbd_read_input(); + if (status & KBD_STAT_MOUSE_OBF) { + handle_mouse_event(scancode); + } else { + do_acknowledge(scancode); + printk("pc_keyb: %X ", scancode ); + } + status = kbd_read_status(); + if(!work--) { + printk("pc_keyb: controller jammed (0x%02X).\n", status); + break; + } + } + return status; +} + +static void ps2_mouse_interrupt(void * unused) +{ + handle_kbd_event(); +} + +static void kbd_write_command_w(int data) +{ + kb_wait(); + kbd_write_command(data); +} + +static void kbd_write_cmd(int cmd) +{ + kb_wait(); + kbd_write_command(KBD_CCMD_WRITE_MODE); + kb_wait(); + kbd_write_output(cmd); +} + +/* + * Check if this is a dual port controller. + */ +static int detect_auxiliary_port(void) +{ + int loops = 10; + int retval = 0; + + /* Put the value 0x5A in the output buffer using the "Write + * Auxiliary Device Output Buffer" command (0xD3). Poll the + * Status Register for a while to see if the value really + * turns up in the Data Register. If the KBD_STAT_MOUSE_OBF + * bit is also set to 1 in the Status Register, we assume this + * controller has an Auxiliary Port (a.k.a. Mouse Port). + */ + kb_wait(); + kbd_write_command(KBD_CCMD_WRITE_AUX_OBUF); + + kb_wait(); + kbd_write_output(0x5a); /* 0x5a is a random dummy value. */ + + do { + unsigned char status = kbd_read_status(); + if (status & KBD_STAT_OBF) { + kbd_read_input(); + if (status & KBD_STAT_MOUSE_OBF) { + printk( "Detected PS/2 Mouse Port.\n"); + retval = 1; + } + break; + } + mdelay(1); + } while (--loops); + return retval; +} + +/* + * Send a byte to the mouse. + */ +static void aux_write_dev(int val) +{ + kb_wait(); + kbd_write_command(KBD_CCMD_WRITE_MOUSE); + kb_wait(); + kbd_write_output(val); +} + +/* + * Send a byte to the mouse & handle returned ack + */ +static void aux_write_ack(int val) +{ + kb_wait(); + kbd_write_command(KBD_CCMD_WRITE_MOUSE); + kb_wait(); + kbd_write_output(val); + /* we expect an ACK in response. */ + mouse_reply_expected++; + kb_wait(); +} + +static unsigned char get_from_queue(void) +{ + unsigned char result; + result = queue->buf[queue->tail]; + queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1); + return result; +} + +static int queue_empty(void) +{ + return queue->head == queue->tail; +} + +/* + * Random magic cookie for the aux device + */ +#define AUX_DEV ((void *)queue) + +static int release_aux(void) +{ + rtems_status_code status; + if (--aux_count) + return 0; + kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints */ + kbd_write_command_w(KBD_CCMD_MOUSE_DISABLE); + status = rtems_interrupt_handler_remove( + AUX_IRQ, + ps2_mouse_interrupt, + NULL + ); + assert(status == RTEMS_SUCCESSFUL); + return 0; +} + +/* + * Install interrupt handler. + * Enable auxiliary device. + */ + +static int open_aux(void) +{ + rtems_status_code status; + + if (aux_count++) { + return 0; + } + queue->head = queue->tail = 0; /* Flush input queue */ + + status = rtems_interrupt_handler_install( + AUX_IRQ, + "ps2_mouse", + RTEMS_INTERRUPT_UNIQUE, + ps2_mouse_interrupt, + NULL + ); + assert(status == RTEMS_SUCCESSFUL); + + kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable the auxiliary port on + controller. */ + aux_write_ack(AUX_ENABLE_DEV); /* Enable aux device */ + kbd_write_cmd(AUX_INTS_ON); /* Enable controller ints */ + return 0; +} + +/* + * Put bytes from input queue to buffer. + */ +size_t read_aux(char * buffer, size_t count ) +{ + size_t i = count; + unsigned char c; + + if (queue_empty()) { + return 0; + } + while (i > 0 && !queue_empty()) { + c = get_from_queue(); + *buffer++ = c; + i--; + } + return count-i; +} + +/* + * Write to the aux device. + */ +static int write_aux( int minor, const char * buffer, int count ) +{ + int retval = 0; + + if (count) { + int written = 0; + if (count > 32) + count = 32; /* Limit to 32 bytes. */ + do { + char c; + c = *buffer++; + aux_write_dev(c); + written++; + } while (--count); + retval = -EIO; + if (written) { + retval = written; + } + } + return retval; +} + +static int psaux_init( void ) +{ + if( !detect_auxiliary_port() ) { + printk( "PS/2 - mouse not found.\n" ); + return -EIO; + } + queue = (struct aux_queue *)malloc( sizeof(*queue) ); + memset(queue, 0, sizeof(*queue)); + queue->head = queue->tail = 0; + queue->proc_list = NULL; + + #ifdef INITIALIZE_MOUSE + kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable Aux. */ + aux_write_ack(AUX_SET_SAMPLE); + aux_write_ack(100); /* 100 samples/sec */ + aux_write_ack(AUX_SET_RES); + aux_write_ack(3); /* 8 counts per mm */ + aux_write_ack(AUX_SET_SCALE21); /* 2:1 scaling */ + #endif /* INITIALIZE_MOUSE */ + kbd_write_command(KBD_CCMD_MOUSE_DISABLE); /* Disable aux device. */ + kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints. */ + return 0; +} + +/* + * paux device driver INITIALIZE entry point. + */ +rtems_device_driver paux_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + rtems_status_code status; + + /* + * Set up TERMIOS + */ + rtems_termios_initialize(); + + printk( "PS/2 mouse probe.\n" ); + if( psaux_init() < 0 ) { + printk("Error detecting PS/2 mouse --\n"); + /* we might want to finish the application here !!! */ + } + open_aux(); + + /* + * Register the device + */ + status = rtems_io_register_name ("/dev/mouse", major, 0); + if (status != RTEMS_SUCCESSFUL) { + printk("Error registering paux device!\n"); + rtems_fatal_error_occurred (status); + } + return RTEMS_SUCCESSFUL; +} /* tty_initialize */ + +static int paux_last_close(int major, int minor, void *arg) +{ + release_aux(); + return 0; +} + +/* + * Write to the aux device. This routine is invoked by the + * termios framework whenever the "ECHO" feature is on. + * It does nothing write now. + */ +static ssize_t write_aux_echo( int minor, const char * buffer, size_t count ) +{ + return 0; +} + +/* + * paux device driver OPEN entry point + */ +rtems_device_driver paux_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + rtems_status_code status; + static rtems_termios_callbacks cb = + { + NULL, /* firstOpen */ + paux_last_close, /* lastClose */ + NULL, /* poll read */ + write_aux_echo, /* write */ + NULL, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + 0 /* outputUsesInterrupts */ + }; + + status = rtems_termios_open (major, minor, arg, &cb ); + termios_ttyp_paux = ( (rtems_libio_open_close_args_t *)arg)->iop->data1; + return status; +} + +/* + * paux device driver CLOSE entry point + */ +rtems_device_driver paux_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + return (rtems_termios_close (arg)); +} + +/* + * paux device driver READ entry point. + * Read characters from the PS/2 mouse. + */ +rtems_device_driver paux_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + return rtems_termios_read (arg); +} /* tty_read */ + +/* + * paux device driver WRITE entry point. + * Write characters to the PS/2 mouse. + */ +rtems_device_driver paux_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; + char *buffer = rw_args->buffer; + int maximum = rw_args->count; + rw_args->bytes_moved = write_aux( minor, buffer, maximum ); + return RTEMS_SUCCESSFUL; +} /* tty_write */ + +/* + * Handle ioctl request. + */ +rtems_device_driver paux_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_libio_ioctl_args_t *args = arg; + + switch( args->command ) { + default: + return rtems_termios_ioctl (arg); + break; + + case MW_UID_REGISTER_DEVICE: + printk( "PS2 Mouse: registering\n" ); + mouse_parser_initialize( "ps2" ); + ps2_set_driver_handler( minor, mouse_parser_enqueue ); + break; + + case MW_UID_UNREGISTER_DEVICE: +/* + unregister_mou_msg_queue( -1 ); +*/ + ps2_set_driver_handler( minor, NULL ); + break; + } + args->ioctl_return = 0; + return RTEMS_SUCCESSFUL; +} diff --git a/bsps/i386/pc386/console/ps2_mouse.h b/bsps/i386/pc386/console/ps2_mouse.h new file mode 100644 index 0000000000..dd61e8a367 --- /dev/null +++ b/bsps/i386/pc386/console/ps2_mouse.h @@ -0,0 +1,151 @@ +/** + * @file + * + * @ingroup i386_pc386 + * + * @brief Keyboard and mouse definitions. + */ + +/* + * include/linux/pc_keyb.h + * PC Keyboard And Keyboard Controller + * (c) 1997 Martin Mares + * + * RTEMS port: by Rosimildo da Silva. + * + * This module was ported from Linux. + * + */ + +/* + * Configuration Switches + */ + +#undef KBD_REPORT_ERR /* Report keyboard errors */ +#define KBD_REPORT_UNKN /* Report unknown scan codes */ +#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */ +#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */ +#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */ + +#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */ +#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */ +#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */ + +/* + * Internal variables of the driver + */ + +extern unsigned char pckbd_read_mask; +extern unsigned char aux_device_present; + +/* + * Keyboard Controller Registers on normal PCs. + */ + +#define KBD_STATUS_REG 0x64 /* Status register (R) */ +#define KBD_CNTL_REG 0x64 /* Controller command register (W) */ +#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */ + +/* + * Keyboard Controller Commands + */ + +#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */ +#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */ +#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */ +#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */ +#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */ +#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */ +#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */ +#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */ +#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */ +#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */ +#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if + initiated by the auxiliary device */ +#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */ + +/* + * Keyboard Commands + */ + +#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */ +#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */ +#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */ +#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */ +#define KBD_CMD_RESET 0xFF /* Reset */ + +/* + * Keyboard Replies + */ + +#define KBD_REPLY_POR 0xAA /* Power on reset */ +#define KBD_REPLY_ACK 0xFA /* Command ACK */ +#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */ + +/* + * Status Register Bits + */ + +#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */ +#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */ +#define KBD_STAT_SELFTEST 0x04 /* Self test successful */ +#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */ +#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */ +#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */ +#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */ +#define KBD_STAT_PERR 0x80 /* Parity error */ + +#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF) + +/* + * Controller Mode Register Bits + */ + +#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */ +#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */ +#define KBD_MODE_SYS 0x04 /* The system flag (?) */ +#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */ +#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */ +#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */ +#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */ +#define KBD_MODE_RFU 0x80 + +/* + * Mouse Commands + */ + +#define AUX_SET_RES 0xE8 /* Set resolution */ +#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */ +#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */ +#define AUX_GET_SCALE 0xE9 /* Get scaling factor */ +#define AUX_SET_STREAM 0xEA /* Set stream mode */ +#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */ +#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */ +#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */ +#define AUX_RESET 0xFF /* Reset aux device */ +#define AUX_ACK 0xFA /* Command byte ACK. */ + +#define AUX_BUF_SIZE 512 /* This might be better divisible by + three to make overruns stay in sync + but then the read function would need + a lock etc - ick */ + +struct aux_queue { + unsigned long head; + unsigned long tail; + struct wait_queue *proc_list; + struct fasync_struct *fasync; + unsigned char buf[AUX_BUF_SIZE]; +}; + +/* How to access the keyboard macros on this platform. */ +#define kbd_read_input() inb(KBD_DATA_REG) +#define kbd_read_status() inb(KBD_STATUS_REG) +#define kbd_write_output(val) outb(val, KBD_DATA_REG) +#define kbd_write_command(val) outb(val, KBD_CNTL_REG) + +/* + * Machine specific bits for the PS/2 driver + */ + +#define AUX_IRQ 12 diff --git a/bsps/i386/pc386/console/rtd316.c b/bsps/i386/pc386/console/rtd316.c new file mode 100644 index 0000000000..c8f3c3a6ef --- /dev/null +++ b/bsps/i386/pc386/console/rtd316.c @@ -0,0 +1,109 @@ +/** + * @file + * + * @brief Driver for RTD316 ISA SCC Board + * + * The RTD316 has a single Z85C30. + */ + +/* + * COPYRIGHT (c) 1989-2014. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "../../shared/dev/serial/legacy-console.h" + +#define RTD_CLOCK_RATE (460800 * 32) + +uint8_t rtd316_com_get_register(uint32_t addr, uint8_t reg) +{ + register uint8_t val = 0; + + outport_byte( addr, reg ); + /* It appears the no delay is needed between the accesses. */ + inport_byte( addr, val ); + + return val; +} + +void rtd316_com_set_register(uint32_t addr,uint8_t reg, uint8_t val) +{ + outport_byte( addr, reg ); + /* It appears the no delay is needed between the accesses. */ + outport_byte( addr, val ); +} + +rtems_device_driver rtd316_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor_arg, + void *arg +) +{ + int p; + console_tbl *ports; + console_tbl *port_p; + + /* + * Now allocate array of device structures and fill them in + */ + ports = calloc( 2, sizeof( console_tbl ) ); + port_p = ports; + + for ( p=0 ; p<2 ; p++ ) { + char name[32]; + sprintf( name, "/dev/rtd316_1_%d", p ); + printk("Found %s\n", name ); + port_p->sDeviceName = strdup( name ); + port_p->deviceType = SERIAL_Z85C30; + #if 0 + port_p->pDeviceFns = &z85c30_fns_polled; + #else + port_p->pDeviceFns = &z85c30_fns; + #endif + + port_p->deviceProbe = NULL; + port_p->pDeviceFlow = NULL; + port_p->ulMargin = 16; + port_p->ulHysteresis = 8; + port_p->pDeviceParams = (void *) 9600; + port_p->getRegister = rtd316_com_get_register; + port_p->setRegister = rtd316_com_set_register; + port_p->getData = NULL; + port_p->setData = NULL; + port_p->ulClock = RTD_CLOCK_RATE; + port_p->ulIntVector = 9; + + if ( p==0 ) { + port_p->ulDataPort = 0; + port_p->ulCtrlPort1 = 0x340; + port_p->ulCtrlPort2 = 0x341; + } else { + port_p->ulDataPort = 1; + port_p->ulCtrlPort1 = 0x342; + port_p->ulCtrlPort2 = 0x343; + } + port_p++; + } /* end ports */ + + /* + * Register the devices + */ + console_register_devices( ports, 2 ); + + return RTEMS_SUCCESSFUL; +} diff --git a/bsps/i386/pc386/console/serial_mouse_config.c b/bsps/i386/pc386/console/serial_mouse_config.c new file mode 100644 index 0000000000..a8a0313954 --- /dev/null +++ b/bsps/i386/pc386/console/serial_mouse_config.c @@ -0,0 +1,48 @@ +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include "../../shared/dev/serial/legacy-console.h" + +/* select which serial port the mouse is connected to */ +#if defined(SERIAL_MOUSE_COM2) + #define MOUSE_DEVICE "/dev/com2" +#else + #define MOUSE_DEVICE "/dev/com1" +#endif + +static const char *SerialMouseDevice = MOUSE_DEVICE; + +bool bsp_get_serial_mouse_device( + const char **name, + const char **type +) +{ + const char *consname; + + *name = SerialMouseDevice; + *type = "ms"; + + /* Check if this port is not been used as console */ + consname = Console_Port_Tbl[ Console_Port_Minor ]->sDeviceName; + if ( !strcmp(MOUSE_DEVICE, consname) ) { + printk( "SERIAL MOUSE: port selected as console.(%s)\n", *name ); + rtems_fatal_error_occurred( -1 ); + } + + printk("Mouse Device: %s\n", *name ); + return name; +} diff --git a/bsps/i386/pc386/console/uart_bus_pci.c b/bsps/i386/pc386/console/uart_bus_pci.c new file mode 100644 index 0000000000..2ad8323f05 --- /dev/null +++ b/bsps/i386/pc386/console/uart_bus_pci.c @@ -0,0 +1,477 @@ +/* + * This file was brought over from FreeBSD for the PCI device table. + * The code for using the table is RTEMS specific is also under the + * FreeBSD license. + * + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + */ + +/*- + * Copyright (c) 2006 Marcel Moolenaar + * Copyright (c) 2001 M. Warner Losh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef __rtems__ +#include +#include +#include +#else +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#endif + +#define DEFAULT_RCLK 1843200 + +#ifndef __rtems__ +static int uart_pci_probe(device_t dev); + +static device_method_t uart_pci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, uart_pci_probe), + DEVMETHOD(device_attach, uart_bus_attach), + DEVMETHOD(device_detach, uart_bus_detach), + DEVMETHOD(device_resume, uart_bus_resume), + DEVMETHOD_END +}; + +static driver_t uart_pci_driver = { + uart_driver_name, + uart_pci_methods, + sizeof(struct uart_softc), +}; +#endif + +struct pci_id { + uint16_t vendor; + uint16_t device; + uint16_t subven; + uint16_t subdev; + const char *desc; + int rid; + int rclk; + int regshft; +}; + +static const struct pci_id pci_ns8250_ids[] = { +{ 0x1028, 0x0008, 0xffff, 0, "Dell Remote Access Card III", 0x14, + 128 * DEFAULT_RCLK }, +{ 0x1028, 0x0012, 0xffff, 0, "Dell RAC 4 Daughter Card Virtual UART", 0x14, + 128 * DEFAULT_RCLK }, +{ 0x1033, 0x0074, 0x1033, 0x8014, "NEC RCV56ACF 56k Voice Modem", 0x10 }, +{ 0x1033, 0x007d, 0x1033, 0x8012, "NEC RS232C", 0x10 }, +{ 0x103c, 0x1048, 0x103c, 0x1227, "HP Diva Serial [GSP] UART - Powerbar SP2", + 0x10 }, +{ 0x103c, 0x1048, 0x103c, 0x1301, "HP Diva RMP3", 0x14 }, +{ 0x103c, 0x1290, 0xffff, 0, "HP Auxiliary Diva Serial Port", 0x18 }, +{ 0x103c, 0x3301, 0xffff, 0, "HP iLO serial port", 0x10 }, +{ 0x11c1, 0x0480, 0xffff, 0, "Agere Systems Venus Modem (V90, 56KFlex)", 0x14 }, +{ 0x115d, 0x0103, 0xffff, 0, "Xircom Cardbus Ethernet + 56k Modem", 0x10 }, +{ 0x1282, 0x6585, 0xffff, 0, "Davicom 56PDV PCI Modem", 0x10 }, +{ 0x12b9, 0x1008, 0xffff, 0, "3Com 56K FaxModem Model 5610", 0x10 }, +{ 0x131f, 0x1000, 0xffff, 0, "Siig CyberSerial (1-port) 16550", 0x18 }, +{ 0x131f, 0x1001, 0xffff, 0, "Siig CyberSerial (1-port) 16650", 0x18 }, +{ 0x131f, 0x1002, 0xffff, 0, "Siig CyberSerial (1-port) 16850", 0x18 }, +{ 0x131f, 0x2000, 0xffff, 0, "Siig CyberSerial (1-port) 16550", 0x10 }, +{ 0x131f, 0x2001, 0xffff, 0, "Siig CyberSerial (1-port) 16650", 0x10 }, +{ 0x131f, 0x2002, 0xffff, 0, "Siig CyberSerial (1-port) 16850", 0x10 }, +{ 0x135c, 0x0190, 0xffff, 0, "Quatech SSCLP-100", 0x18 }, +{ 0x135c, 0x01c0, 0xffff, 0, "Quatech SSCLP-200/300", 0x18 }, +{ 0x135e, 0x7101, 0xffff, 0, "Sealevel Systems Single Port RS-232/422/485/530", + 0x18 }, +{ 0x1407, 0x0110, 0xffff, 0, "Lava Computer mfg DSerial-PCI Port A", 0x10 }, +{ 0x1407, 0x0111, 0xffff, 0, "Lava Computer mfg DSerial-PCI Port B", 0x10 }, +{ 0x1407, 0x0510, 0xffff, 0, "Lava SP Serial 550 PCI", 0x10 }, +{ 0x1409, 0x7168, 0x1409, 0x4025, "Timedia Technology Serial Port", 0x10, + 8 * DEFAULT_RCLK }, +{ 0x1409, 0x7168, 0x1409, 0x4027, "Timedia Technology Serial Port", 0x10, + 8 * DEFAULT_RCLK }, +{ 0x1409, 0x7168, 0x1409, 0x4028, "Timedia Technology Serial Port", 0x10, + 8 * DEFAULT_RCLK }, +{ 0x1409, 0x7168, 0x1409, 0x5025, "Timedia Technology Serial Port", 0x10, + 8 * DEFAULT_RCLK }, +{ 0x1409, 0x7168, 0x1409, 0x5027, "Timedia Technology Serial Port", 0x10, + 8 * DEFAULT_RCLK }, +{ 0x1415, 0x950b, 0xffff, 0, "Oxford Semiconductor OXCB950 Cardbus 16950 UART", + 0x10, 16384000 }, +{ 0x1415, 0xc120, 0xffff, 0, "Oxford Semiconductor OXPCIe952 PCIe 16950 UART", + 0x10 }, +{ 0x14e4, 0x4344, 0xffff, 0, "Sony Ericsson GC89 PC Card", 0x10}, +{ 0x151f, 0x0000, 0xffff, 0, "TOPIC Semiconductor TP560 56k modem", 0x10 }, +{ 0x1fd4, 0x1999, 0x1fd4, 0x0001, "Sunix SER5xxxx Serial Port", 0x10, + 8 * DEFAULT_RCLK }, +{ 0x8086, 0x0f0a, 0xffff, 0, "Intel ValleyView LPIO1 HSUART#1", 0x10, + 24 * DEFAULT_RCLK, 2 }, +{ 0x8086, 0x0f0c, 0xffff, 0, "Intel ValleyView LPIO1 HSUART#2", 0x10, + 24 * DEFAULT_RCLK, 2 }, +{ 0x8086, 0x1c3d, 0xffff, 0, "Intel AMT - KT Controller", 0x10 }, +{ 0x8086, 0x1d3d, 0xffff, 0, "Intel C600/X79 Series Chipset KT Controller", 0x10 }, +{ 0x8086, 0x2a07, 0xffff, 0, "Intel AMT - PM965/GM965 KT Controller", 0x10 }, +{ 0x8086, 0x2a47, 0xffff, 0, "Mobile 4 Series Chipset KT Controller", 0x10 }, +{ 0x8086, 0x2e17, 0xffff, 0, "4 Series Chipset Serial KT Controller", 0x10 }, +{ 0x8086, 0x3b67, 0xffff, 0, "5 Series/3400 Series Chipset KT Controller", + 0x10 }, +{ 0x8086, 0x8811, 0xffff, 0, "Intel EG20T Serial Port 0", 0x10 }, +{ 0x8086, 0x8812, 0xffff, 0, "Intel EG20T Serial Port 1", 0x10 }, +{ 0x8086, 0x8813, 0xffff, 0, "Intel EG20T Serial Port 2", 0x10 }, +{ 0x8086, 0x8814, 0xffff, 0, "Intel EG20T Serial Port 3", 0x10 }, +{ 0x8086, 0x8c3d, 0xffff, 0, "Intel Lynx Point KT Controller", 0x10 }, +{ 0x8086, 0x8cbd, 0xffff, 0, "Intel Wildcat Point KT Controller", 0x10 }, +{ 0x8086, 0x9c3d, 0xffff, 0, "Intel Lynx Point-LP HECI KT", 0x10 }, +{ 0x9710, 0x9820, 0x1000, 1, "NetMos NM9820 Serial Port", 0x10 }, +{ 0x9710, 0x9835, 0x1000, 1, "NetMos NM9835 Serial Port", 0x10 }, +{ 0x9710, 0x9865, 0xa000, 0x1000, "NetMos NM9865 Serial Port", 0x10 }, +{ 0x9710, 0x9900, 0xa000, 0x1000, + "MosChip MCS9900 PCIe to Peripheral Controller", 0x10 }, +{ 0x9710, 0x9901, 0xa000, 0x1000, + "MosChip MCS9901 PCIe to Peripheral Controller", 0x10 }, +{ 0x9710, 0x9904, 0xa000, 0x1000, + "MosChip MCS9904 PCIe to Peripheral Controller", 0x10 }, +{ 0x9710, 0x9922, 0xa000, 0x1000, + "MosChip MCS9922 PCIe to Peripheral Controller", 0x10 }, +{ 0xdeaf, 0x9051, 0xffff, 0, "Middle Digital PC Weasel Serial Port", 0x10 }, +{ 0xffff, 0, 0xffff, 0, NULL, 0, 0} +}; + +#ifndef __rtems__ +const static struct pci_id * +uart_pci_match(device_t dev, const struct pci_id *id) +{ + uint16_t device, subdev, subven, vendor; + + vendor = pci_get_vendor(dev); + device = pci_get_device(dev); + while (id->vendor != 0xffff && + (id->vendor != vendor || id->device != device)) + id++; + if (id->vendor == 0xffff) + return (NULL); + if (id->subven == 0xffff) + return (id); + subven = pci_get_subvendor(dev); + subdev = pci_get_subdevice(dev); + while (id->vendor == vendor && id->device == device && + (id->subven != subven || id->subdev != subdev)) + id++; + return ((id->vendor == vendor && id->device == device) ? id : NULL); +} + +static int +uart_pci_probe(device_t dev) +{ + struct uart_softc *sc; + const struct pci_id *id; + int result; + + sc = device_get_softc(dev); + + id = uart_pci_match(dev, pci_ns8250_ids); + if (id != NULL) { + sc->sc_class = &uart_ns8250_class; + goto match; + } + /* Add checks for non-ns8250 IDs here. */ + return (ENXIO); + + match: + result = uart_bus_probe(dev, id->regshft, id->rclk, id->rid, 0); + /* Bail out on error. */ + if (result > 0) + return (result); + /* Set/override the device description. */ + if (id->desc) + device_set_desc(dev, id->desc); + return (result); +} + +DRIVER_MODULE(uart, pci, uart_pci_driver, uart_devclass, NULL, NULL); +#endif + +#ifdef __rtems__ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include "../../shared/dev/serial/legacy-console.h" + +#define MAX_BOARDS 4 + +/* + * Information saved from PCI scan + */ +typedef struct { + bool found; + const char* desc; + uint32_t base; + uint8_t irq; + uint8_t bus; + uint8_t slot; + int ports; + uint32_t clock; +} port_instance_conf_t; + +/* + * Memory Mapped Register Access Routines + */ + +#define UART_PCI_IO (0) + +static uint8_t pci_ns16550_mem_get_register(uint32_t addr, uint8_t i) +{ + uint8_t val = 0; + volatile uint32_t *reg = (volatile uint32_t *)(addr + (i*4)); + val = *reg; + if (UART_PCI_IO) + printk( "RD(%p -> 0x%02x) ", reg, val ); + return val; +} + +static void pci_ns16550_mem_set_register(uint32_t addr, uint8_t i, uint8_t val) +{ + volatile uint32_t *reg = (volatile uint32_t *)(addr + (i*4)); + if (UART_PCI_IO) + printk( "WR(%p <- 0x%02x) ", reg, val ); + *reg = val; +} + +/* + * IO Register Access Routines + */ +static uint8_t pci_ns16550_io_get_register(uint32_t addr, uint8_t i) +{ + uint8_t val = rtems_inb(addr + i); + if (UART_PCI_IO) + printk( "RD(%p -> 0x%02x) ", (void*) addr + i, val ); + return val; +} + +static void pci_ns16550_io_set_register(uint32_t addr, uint8_t i, uint8_t val) +{ + if (UART_PCI_IO) + printk( "WR(%p <- 0x%02x) ", (void*) addr + i, val ); + rtems_outb(addr + i, val); +} + +void pci_uart_probe(void) +{ + port_instance_conf_t conf[MAX_BOARDS]; + int boards = 0; + int b = 0; + console_tbl *ports; + console_tbl *port_p; + int bus; + int dev; + int fun; + int status; + int instance; + int i; + int total_ports = 0; + + for ( b=0 ; b> 1) & 3) != 2))) { + boards++; + conf[instance].found = true; + conf[instance].desc = pci_ns8250_ids[i].desc; + conf[instance].clock = pci_ns8250_ids[i].rclk; + conf[instance].ports = 1; + total_ports += conf[instance].ports; + + pci_read_config_byte( bus, dev, fun, PCI_INTERRUPT_LINE, &irq ); + + conf[instance].irq = irq; + conf[instance].base = base; + } + } + } + } + + /* + * Now allocate array of device structures and fill them in + */ + if (boards) { + int device_instance; + + ports = calloc( total_ports, sizeof( console_tbl ) ); + if (ports != NULL) { + port_p = ports; + device_instance = 1; + for (b = 0; b < MAX_BOARDS; b++) { + uint32_t base = 0; + bool io; + const char* locatable = ""; + const char* prefectable = locatable; + char name[32]; + if ( conf[b].found == false ) + continue; + sprintf( name, "/dev/pcicom%d", device_instance++ ); + port_p->sDeviceName = strdup( name ); + port_p->deviceType = SERIAL_NS16550; + if ( conf[b].irq <= 15 ) { + port_p->pDeviceFns = &ns16550_fns; + } else { + printk( + "%s IRQ=%d >= 16 requires APIC support, using polling\n", + name, + conf[b].irq + ); + port_p->pDeviceFns = &ns16550_fns_polled; + } + + /* + * PCI BAR (http://wiki.osdev.org/PCI#Base_Address_Registers): + * + * Bit 0: 0 = memory, 1 = IO + * + * Memory: + * Bit 2-1 : 0 = any 32bit address, + * 1 = < 1M + * 2 = any 64bit address + * Bit 3 : 0 = no, 1 = yes + * Bit 31-4 : base address (16-byte aligned) + * + * IO: + * Bit 1 : reserved + * Bit 31-2 : base address (4-byte aligned) + */ + + io = (conf[b].base & 1) == 1; + + if (io) { + base = conf[b].base & 0xfffffffc; + } else { + int loc = (conf[b].base >> 1) & 3; + if (loc == 0) { + base = conf[b].base & 0xfffffff0; + locatable = ",A32"; + } else if (loc == 1) { + base = conf[b].base & 0x0000fff0; + locatable = ",A16"; + } + prefectable = (conf[b].base & (1 << 3)) == 0 ? ",no-prefech" : ",prefetch"; + } + + port_p->deviceProbe = NULL; + port_p->pDeviceFlow = NULL; + port_p->ulMargin = 16; + port_p->ulHysteresis = 8; + port_p->pDeviceParams = (void *) 9600; + port_p->ulCtrlPort1 = base; + port_p->ulCtrlPort2 = 0; /* NA */ + port_p->ulDataPort = 0; /* NA */ + if (io) { + port_p->getRegister = pci_ns16550_io_get_register; + port_p->setRegister = pci_ns16550_io_set_register; + } else { + port_p->getRegister = pci_ns16550_mem_get_register; + port_p->setRegister = pci_ns16550_mem_set_register; + } + port_p->getData = NULL; /* NA */ + port_p->setData = NULL; /* NA */ + port_p->ulClock = conf[b].clock; + port_p->ulIntVector = conf[b].irq; + + + printk( + "%s:%d:%s,%s:0x%lx%s%s,irq:%d,clk:%lu\n", /* */ + name, b, conf[b].desc, + io ? "io" : "mem", base, locatable, prefectable, + conf[b].irq, conf[b].clock + ); + + + port_p++; + } /* end boards */ + + /* + * Register the devices + */ + console_register_devices( ports, total_ports ); + + /* + * Do not free the ports memory, the console hold this memory for-ever. + */ + } + } +} +#endif diff --git a/bsps/i386/pc386/console/vgacons.c b/bsps/i386/pc386/console/vgacons.c new file mode 100644 index 0000000000..2886496e51 --- /dev/null +++ b/bsps/i386/pc386/console/vgacons.c @@ -0,0 +1,191 @@ +/* + * This file contains the termios TTY driver for the i386 + * vga. + * + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VGACONS_STATIC static + +/* + * vgacons_init + * + * This function initializes the VGA console to a quiecsent state. + */ +VGACONS_STATIC void vgacons_init(int minor) +{ + /* + * Note: We do not initialize the KBD interface here since + * it was initialized regardless of whether the + * vga is available or not. Therefore it is initialized + * in bsp_start. + */ +} + +/* + * vgacons_open + * + * This function opens a port for communication. + * + * Default state is 9600 baud, 8 bits, No parity, and 1 stop bit. + */ +VGACONS_STATIC int vgacons_open( + int major, + int minor, + void *arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * vgacons_close + * + * This function shuts down the requested port. + */ +VGACONS_STATIC int vgacons_close( + int major, + int minor, + void *arg +) +{ + return(RTEMS_SUCCESSFUL); +} + +/* + * vgacons_write_polled + * + * This routine polls out the requested character. + */ +VGACONS_STATIC void vgacons_write_polled( + int minor, + char c +) +{ + _IBMPC_outch( c ); + if( c == '\n') + _IBMPC_outch( '\r' ); /* LF = LF + CR */ +} + +/* + * vgacons_write_support_polled + * + * Console Termios output entry point when using polled output. + * + */ +VGACONS_STATIC ssize_t vgacons_write_support_polled( + int minor, + const char *buf, + size_t len +) +{ + int nwrite = 0; + + /* + * poll each byte in the string out of the port. + */ + while (nwrite < len) { + vgacons_write_polled(minor, *buf++); + nwrite++; + } + + /* + * return the number of bytes written. + */ + return nwrite; +} + +/* + * vgacons_inbyte_nonblocking_polled + * + * Console Termios polling input entry point. + */ +VGACONS_STATIC int vgacons_inbyte_nonblocking_polled( + int minor +) +{ + if( rtems_kbpoll() ) { + int c = getch(); + return c; + } + + return -1; +} + +/* + * vgacons_set_attributes + * + * This function sets the UART channel to reflect the requested termios + * port settings. + */ +VGACONS_STATIC int vgacons_set_attributes( + int minor, + const struct termios *t +) +{ + return 0; +} + +bool vgacons_probe( + int minor +) +{ + rtems_status_code status; + static bool firstTime = true; + + if ((*(unsigned char*) NB_MAX_ROW_ADDR == 0) && + (*(unsigned short*)NB_MAX_COL_ADDR == 0)) { + return false; + } + + /* + * If there is a video card, let's assume there is also a keyboard. + * The means that we need the ISR installed in case someone wants to + * use the Keyboard or PS2 Mouse. With Microwindows, the console + * can be COM1 and you can still use the mouse/VGA for graphics. + */ + if ( firstTime ) { + status = rtems_interrupt_handler_install( + BSP_KEYBOARD, + "vgacons", + RTEMS_INTERRUPT_UNIQUE, + keyboard_interrupt, + NULL + ); + assert(status == RTEMS_SUCCESSFUL); + } + firstTime = false; + + return true; +} + +const console_fns vgacons_fns = +{ + libchip_serial_default_probe, /* deviceProbe */ + vgacons_open, /* deviceFirstOpen */ + vgacons_close, /* deviceLastClose */ + vgacons_inbyte_nonblocking_polled, /* deviceRead */ + vgacons_write_support_polled, /* deviceWrite */ + vgacons_init, /* deviceInitialize */ + vgacons_write_polled, /* deviceWritePolled */ + vgacons_set_attributes, /* deviceSetAttributes */ + FALSE, /* deviceOutputUsesInterrupts */ +}; diff --git a/bsps/i386/pc386/console/vgainit.c b/bsps/i386/pc386/console/vgainit.c new file mode 100644 index 0000000000..ce83ae59b1 --- /dev/null +++ b/bsps/i386/pc386/console/vgainit.c @@ -0,0 +1,757 @@ +/* + * Copyright (c) 1999 Greg Haerr + * Copyright (c) 1991 David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * Alternate EGA/VGA Screen Driver Init, direct hw programming + */ +#include + +#ifdef __rtems__ +#define ROMFONT 0 /* =0 no bios rom fonts available*/ +#else +#define ROMFONT 1 /* =1 uses PC rom fonts */ +#endif + +/* defines are defined in device.h of the MicroWindows package */ +#define MODE_SET 0 /* draw pixels as given (default) */ +#define MODE_XOR 1 /* draw pixels using XOR */ +#define MODE_OR 2 /* draw pixels using OR (notimp)*/ +#define MODE_AND 3 /* draw pixels using AND (notimp)*/ +#define MODE_MAX 3 +typedef int MODE; /* drawing mode*/ + +/* Define one and only one of the following to be nonzero*/ +#define VGA_ET4000 0 /* TSENG LABS ET4000 chip 800x600*/ +#define VGA_STANDARD 1 /* standard VGA 640x480*/ +#define EGA_STANDARD 0 /* standard EGA 640x350*/ + +#define DONE 0 +#define IN 1 +#define OUT 2 + +#define RAM_SCAN_LINES 32 /* number of scan lines in fonts in RAM */ +#define FONT_CHARS 256 /* number of characters in font tables */ +#define CHAR_WIDTH 8 /* number of pixels for character width */ + +#define PALREG 0x3c0 +#define SEQREG 0x3c4 +#define SEQVAL 0x3c5 +#define GRREG 0x3ce +#define GRVAL 0x3cf +#define ATTRREG 0x3da +#define CRTCREG 0x3d4 +#define CRTCVAL 0x3d5 + +#define GENREG1 0x3c2 +#define GENREG2 0x3cc +#define GENREG3 0x3ca + +#define DATA_ROTATE 3 /* register number for data rotate */ + +typedef struct { + int action; + int port1; + int data1; + int port2; + int data2; +} REGIO; + +#if ROMFONT +extern FARADDR rom_char_addr; /* address of ROM font*/ +extern int ROM_CHAR_HEIGHT; /* ROM character height*/ +#endif + +/* local data*/ +static REGIO graphics_on[]; +static REGIO graph_off[]; + +/* entry points*/ +void ega_hwinit(void); +void ega_hwterm(void); + +/* local routines*/ +static void writeregs(REGIO *rp); +static void out_word(unsigned int p,unsigned int d); +static void setmode(MODE mode); + +void +ega_hwinit(void) +{ + writeregs(graphics_on); +} + +void +ega_hwterm(void) +{ + setmode(MODE_SET); + + /* Copy character table from ROM back into bit plane 2 before turning + * off graphics. + */ + out_word(SEQREG, 0x0100); /* syn reset */ + out_word(SEQREG, 0x0402); /* cpu writes only to map 2 */ + out_word(SEQREG, 0x0704); /* sequential addressing */ + out_word(SEQREG, 0x0300); /* clear synchronous reset */ + + out_word(GRREG, 0x0204); /* select map 2 for CPU reads */ + out_word(GRREG, 0x0005); /* disable odd-even addressing */ + +#if ROMFONT + { + FARADDR srcoffset; + FARADDR destoffset; + int data; + int ch; + int row; + + srcoffset = rom_char_addr; + destoffset = EGA_BASE; + for (ch = 0; ch < FONT_CHARS; ch++) { + for(row = 0; row < ROM_CHAR_HEIGHT; row++) { + data = GETBYTE_FP(srcoffset++); + PUTBYTE_FP(destoffset++, data); + } + destoffset += (RAM_SCAN_LINES - ROM_CHAR_HEIGHT); + } + } +#endif + + /* Finally set the registers back for text mode. */ + writeregs(graph_off); +} + +/* Set the graphics registers as indicated by the given table */ +static void +writeregs(REGIO *rp) +{ + for (; rp->action != DONE; rp++) { + switch (rp->action) { + case IN: + inp(rp->port1); + break; + case OUT: + outp(rp->port1, rp->data1); + if (rp->port2) + outp(rp->port2, rp->data2); + break; + } + } +} + +/* Output a word to an I/O port. */ +static void +out_word(unsigned int p,unsigned int d) +{ + outp(p, d & 0xff); + outp(p + 1, (d >> 8) & 0xff); +} + +/* Values for the data rotate register to implement drawing modes. */ +static unsigned char mode_table[MODE_MAX + 1] = { + 0x00, 0x18, 0x10, 0x08 +}; + +/* Set the drawing mode. + * This is either SET, OR, AND, or XOR. + */ +static void +setmode(MODE mode) +{ + if (mode > MODE_MAX) + return; + outp(GRREG, DATA_ROTATE); + outp(GRVAL, mode_table[mode]); +} + +#if VGA_ET4000 + +/* VGA 800x600 16-color graphics (BIOS mode 0x29). + */ +REGIO graphics_on[] = { + /* Reset attr F/F */ + IN, ATTRREG, 0, 0, 0, + + /* Disable palette */ + OUT, PALREG, 0, 0, 0, + + /* Reset sequencer regs */ + OUT, SEQREG, 0, SEQVAL, 0, + OUT, SEQREG, 1, SEQVAL, 1, + OUT, SEQREG, 2, SEQVAL, 0x0f, + OUT, SEQREG, 3, SEQVAL, 0, + OUT, SEQREG, 4, SEQVAL, 6, + + /* Misc out reg */ + OUT, GENREG1, 0xe3, 0, 0, + + /* Sequencer enable */ + OUT, SEQREG, 0, SEQVAL, 0x03, + + /* Unprotect crtc regs 0-7 */ + OUT, CRTCREG, 0x11, CRTCVAL, 0, + + /* Crtc */ + OUT, CRTCREG, 0, CRTCVAL, 0x7a, + OUT, CRTCREG, 1, CRTCVAL, 0x63, + OUT, CRTCREG, 2, CRTCVAL, 0x64, + OUT, CRTCREG, 3, CRTCVAL, 0x1d, + OUT, CRTCREG, 4, CRTCVAL, 0x68, + OUT, CRTCREG, 5, CRTCVAL, 0x9a, + OUT, CRTCREG, 6, CRTCVAL, 0x78, + OUT, CRTCREG, 7, CRTCVAL, 0xf0, + OUT, CRTCREG, 8, CRTCVAL, 0x00, + OUT, CRTCREG, 9, CRTCVAL, 0x60, + OUT, CRTCREG, 10, CRTCVAL, 0x00, + OUT, CRTCREG, 11, CRTCVAL, 0x00, + OUT, CRTCREG, 12, CRTCVAL, 0x00, + OUT, CRTCREG, 13, CRTCVAL, 0x00, + OUT, CRTCREG, 14, CRTCVAL, 0x00, + OUT, CRTCREG, 15, CRTCVAL, 0x00, + OUT, CRTCREG, 16, CRTCVAL, 0x5c, + OUT, CRTCREG, 17, CRTCVAL, 0x8e, + OUT, CRTCREG, 18, CRTCVAL, 0x57, + OUT, CRTCREG, 19, CRTCVAL, 0x32, + OUT, CRTCREG, 20, CRTCVAL, 0x00, + OUT, CRTCREG, 21, CRTCVAL, 0x5b, + OUT, CRTCREG, 22, CRTCVAL, 0x75, + OUT, CRTCREG, 23, CRTCVAL, 0xc3, + OUT, CRTCREG, 24, CRTCVAL, 0xff, + + /* Graphics controller */ + OUT, GENREG2, 0x00, 0, 0, + OUT, GENREG3, 0x01, 0, 0, + OUT, GRREG, 0, GRVAL, 0x00, + OUT, GRREG, 1, GRVAL, 0x00, + OUT, GRREG, 2, GRVAL, 0x00, + OUT, GRREG, 3, GRVAL, 0x00, + OUT, GRREG, 4, GRVAL, 0x00, + OUT, GRREG, 5, GRVAL, 0x00, + OUT, GRREG, 6, GRVAL, 0x05, + OUT, GRREG, 7, GRVAL, 0x0f, + OUT, GRREG, 8, GRVAL, 0xff, + + /* Reset attribute flip/flop */ + IN, ATTRREG, 0, 0, 0, + + /* Palette */ + OUT, PALREG, 0, PALREG, 0x00, + OUT, PALREG, 1, PALREG, 0x01, + OUT, PALREG, 2, PALREG, 0x02, + OUT, PALREG, 3, PALREG, 0x03, + OUT, PALREG, 4, PALREG, 0x04, + OUT, PALREG, 5, PALREG, 0x05, + OUT, PALREG, 6, PALREG, 0x06, + OUT, PALREG, 7, PALREG, 0x07, + OUT, PALREG, 8, PALREG, 0x38, + OUT, PALREG, 9, PALREG, 0x39, + OUT, PALREG, 10, PALREG, 0x3a, + OUT, PALREG, 11, PALREG, 0x3b, + OUT, PALREG, 12, PALREG, 0x3c, + OUT, PALREG, 13, PALREG, 0x3d, + OUT, PALREG, 14, PALREG, 0x3e, + OUT, PALREG, 15, PALREG, 0x3f, + OUT, PALREG, 16, PALREG, 0x01, + OUT, PALREG, 17, PALREG, 0x00, + OUT, PALREG, 18, PALREG, 0x0f, + OUT, PALREG, 19, PALREG, 0x00, + + /* Enable palette */ + OUT, PALREG, 0x20, 0, 0, + + /* End of table */ + DONE, 0, 0, 0, 0 +}; + +/* VGA 80x25 text (BIOS mode 3). + */ +static REGIO graph_off[] = { + /* Reset attr F/F */ + IN, ATTRREG, 0, 0, 0, + + /* Disable palette */ + OUT, PALREG, 0, 0, 0, + + /* Reset sequencer regs */ + OUT, SEQREG, 0, SEQVAL, 1, + OUT, SEQREG, 1, SEQVAL, 1, + OUT, SEQREG, 2, SEQVAL, 3, + OUT, SEQREG, 3, SEQVAL, 0, + OUT, SEQREG, 4, SEQVAL, 2, + + /* Misc out reg */ + OUT, GENREG1, 0x63, 0, 0, + + /* Sequencer enable */ + OUT, SEQREG, 0, SEQVAL, 3, + + /* Unprotect crtc regs 0-7 */ + OUT, CRTCREG, 0x11, CRTCVAL, 0, + + /* Crtc */ + OUT, CRTCREG, 0, CRTCVAL, 0x5f, /* horiz total */ + OUT, CRTCREG, 1, CRTCVAL, 0x4f, /* horiz end */ + OUT, CRTCREG, 2, CRTCVAL, 0x50, /* horiz blank */ + OUT, CRTCREG, 3, CRTCVAL, 0x82, /* end blank */ + OUT, CRTCREG, 4, CRTCVAL, 0x55, /* horiz retrace */ + OUT, CRTCREG, 5, CRTCVAL, 0x81, /* end retrace */ + OUT, CRTCREG, 6, CRTCVAL, 0xbf, /* vert total */ + OUT, CRTCREG, 7, CRTCVAL, 0x1f, /* overflows */ + OUT, CRTCREG, 8, CRTCVAL, 0x00, /* row scan */ + OUT, CRTCREG, 9, CRTCVAL, 0x4f, /* max scan line */ + OUT, CRTCREG, 10, CRTCVAL, 0x00, /* cursor start */ + OUT, CRTCREG, 11, CRTCVAL, 0x0f, /* cursor end */ + OUT, CRTCREG, 12, CRTCVAL, 0x0e, /* start high addr */ + OUT, CRTCREG, 13, CRTCVAL, 0xb0, /* low addr */ + OUT, CRTCREG, 14, CRTCVAL, 0x16, /* cursor high */ + OUT, CRTCREG, 15, CRTCVAL, 0x30, /* cursor low */ + OUT, CRTCREG, 16, CRTCVAL, 0x9c, /* vert retrace */ + OUT, CRTCREG, 17, CRTCVAL, 0x8e, /* retrace end */ + OUT, CRTCREG, 18, CRTCVAL, 0x8f, /* vert end */ + OUT, CRTCREG, 19, CRTCVAL, 0x28, /* offset */ + OUT, CRTCREG, 20, CRTCVAL, 0x1f, /* underline */ + OUT, CRTCREG, 21, CRTCVAL, 0x96, /* vert blank */ + OUT, CRTCREG, 22, CRTCVAL, 0xb9, /* end blank */ + OUT, CRTCREG, 23, CRTCVAL, 0xa3, /* crt mode */ + OUT, CRTCREG, 24, CRTCVAL, 0xff, /* line compare */ + + /* Graphics controller */ + OUT, GENREG2, 0x00, 0, 0, + OUT, GENREG3, 0x01, 0, 0, + OUT, GRREG, 0, GRVAL, 0x00, + OUT, GRREG, 1, GRVAL, 0x00, + OUT, GRREG, 2, GRVAL, 0x00, + OUT, GRREG, 3, GRVAL, 0x00, + OUT, GRREG, 4, GRVAL, 0x00, + OUT, GRREG, 5, GRVAL, 0x10, + OUT, GRREG, 6, GRVAL, 0x0e, + OUT, GRREG, 7, GRVAL, 0x00, + OUT, GRREG, 8, GRVAL, 0xff, + + /* Reset attribute flip/flop */ + IN, ATTRREG, 0, 0, 0, + + /* Palette */ + OUT, PALREG, 0, PALREG, 0x00, + OUT, PALREG, 1, PALREG, 0x01, + OUT, PALREG, 2, PALREG, 0x02, + OUT, PALREG, 3, PALREG, 0x03, + OUT, PALREG, 4, PALREG, 0x04, + OUT, PALREG, 5, PALREG, 0x05, + OUT, PALREG, 6, PALREG, 0x06, + OUT, PALREG, 7, PALREG, 0x07, + OUT, PALREG, 8, PALREG, 0x10, + OUT, PALREG, 9, PALREG, 0x11, + OUT, PALREG, 10, PALREG, 0x12, + OUT, PALREG, 11, PALREG, 0x13, + OUT, PALREG, 12, PALREG, 0x14, + OUT, PALREG, 13, PALREG, 0x15, + OUT, PALREG, 14, PALREG, 0x16, + OUT, PALREG, 15, PALREG, 0x17, + OUT, PALREG, 16, PALREG, 0x08, + OUT, PALREG, 17, PALREG, 0x00, + OUT, PALREG, 18, PALREG, 0x0f, + OUT, PALREG, 19, PALREG, 0x00, + + /* Enable palette */ + OUT, PALREG, 0x20, 0, 0, + + /* End of table */ + DONE, 0, 0, 0, 0 +}; + +#endif + +#if VGA_STANDARD + +/* VGA 640x480 16-color graphics (BIOS mode 0x12). + */ +static REGIO graphics_on[] = { + /* Reset attr F/F */ + { IN, ATTRREG, 0, 0, 0 }, + + /* Disable palette */ + { OUT, PALREG, 0, 0, 0 }, + + /* Reset sequencer regs */ + { OUT, SEQREG, 0, SEQVAL, 0 }, + { OUT, SEQREG, 1, SEQVAL, 1 }, + { OUT, SEQREG, 2, SEQVAL, 0x0f }, + { OUT, SEQREG, 3, SEQVAL, 0 }, + { OUT, SEQREG, 4, SEQVAL, 6 }, + + /* Misc out reg */ + { OUT, GENREG1, 0xe3, 0, 0 }, + + /* Sequencer enable */ + { OUT, SEQREG, 0, SEQVAL, 0x03 }, + + /* Unprotect crtc regs 0-7 */ + { OUT, CRTCREG, 0x11, CRTCVAL, 0 }, + + /* Crtc */ + { OUT, CRTCREG, 0, CRTCVAL, 0x5f }, + { OUT, CRTCREG, 1, CRTCVAL, 0x4f }, + { OUT, CRTCREG, 2, CRTCVAL, 0x50 }, + { OUT, CRTCREG, 3, CRTCVAL, 0x82 }, + { OUT, CRTCREG, 4, CRTCVAL, 0x54 }, + { OUT, CRTCREG, 5, CRTCVAL, 0x80 }, + { OUT, CRTCREG, 6, CRTCVAL, 0x0b }, + { OUT, CRTCREG, 7, CRTCVAL, 0x3e }, + { OUT, CRTCREG, 8, CRTCVAL, 0x00 }, + { OUT, CRTCREG, 9, CRTCVAL, 0x40 }, + { OUT, CRTCREG, 10, CRTCVAL, 0x00 }, + { OUT, CRTCREG, 11, CRTCVAL, 0x00 }, + { OUT, CRTCREG, 12, CRTCVAL, 0x00 }, + { OUT, CRTCREG, 13, CRTCVAL, 0x00 }, + { OUT, CRTCREG, 14, CRTCVAL, 0x00 }, + { OUT, CRTCREG, 15, CRTCVAL, 0x59 }, + { OUT, CRTCREG, 16, CRTCVAL, 0xea }, + { OUT, CRTCREG, 17, CRTCVAL, 0x8c }, + { OUT, CRTCREG, 18, CRTCVAL, 0xdf }, + { OUT, CRTCREG, 19, CRTCVAL, 0x28 }, + { OUT, CRTCREG, 20, CRTCVAL, 0x00 }, + { OUT, CRTCREG, 21, CRTCVAL, 0xe7 }, + { OUT, CRTCREG, 22, CRTCVAL, 0x04 }, + { OUT, CRTCREG, 23, CRTCVAL, 0xe3 }, + { OUT, CRTCREG, 24, CRTCVAL, 0xff }, + + /* Graphics controller */ + { OUT, GENREG2, 0x00, 0, 0 }, + { OUT, GENREG3, 0x01, 0, 0 }, + { OUT, GRREG, 0, GRVAL, 0x00 }, + { OUT, GRREG, 1, GRVAL, 0x00 }, + { OUT, GRREG, 2, GRVAL, 0x00 }, + { OUT, GRREG, 3, GRVAL, 0x00 }, + { OUT, GRREG, 4, GRVAL, 0x00 }, + { OUT, GRREG, 5, GRVAL, 0x00 }, + { OUT, GRREG, 6, GRVAL, 0x05 }, + { OUT, GRREG, 7, GRVAL, 0x0f }, + { OUT, GRREG, 8, GRVAL, 0xff }, + + /* Reset attribute flip/flop */ + { IN, ATTRREG, 0, 0, 0 }, + + /* Palette */ + { OUT, PALREG, 0, PALREG, 0x00 }, + { OUT, PALREG, 1, PALREG, 0x01 }, + { OUT, PALREG, 2, PALREG, 0x02 }, + { OUT, PALREG, 3, PALREG, 0x03 }, + { OUT, PALREG, 4, PALREG, 0x04 }, + { OUT, PALREG, 5, PALREG, 0x05 }, + { OUT, PALREG, 6, PALREG, 0x06 }, + { OUT, PALREG, 7, PALREG, 0x07 }, + { OUT, PALREG, 8, PALREG, 0x38 }, + { OUT, PALREG, 9, PALREG, 0x39 }, + { OUT, PALREG, 10, PALREG, 0x3a }, + { OUT, PALREG, 11, PALREG, 0x3b }, + { OUT, PALREG, 12, PALREG, 0x3c }, + { OUT, PALREG, 13, PALREG, 0x3d }, + { OUT, PALREG, 14, PALREG, 0x3e }, + { OUT, PALREG, 15, PALREG, 0x3f }, + { OUT, PALREG, 16, PALREG, 0x01 }, + { OUT, PALREG, 17, PALREG, 0x00 }, + { OUT, PALREG, 18, PALREG, 0x0f }, + { OUT, PALREG, 19, PALREG, 0x00 }, + + /* Enable palette */ + { OUT, PALREG, 0x20, 0, 0 }, + + /* End of table */ + { DONE, 0, 0, 0, 0 } +}; + +/* VGA 80x25 text (BIOS mode 3). + */ +static REGIO graph_off[] = { + /* Reset attr F/F */ + { IN, ATTRREG, 0, 0, 0 }, + + /* Disable palette */ + { OUT, PALREG, 0, 0, 0 }, + + /* Reset sequencer regs */ + { OUT, SEQREG, 0, SEQVAL, 1 }, + { OUT, SEQREG, 1, SEQVAL, 1 }, + { OUT, SEQREG, 2, SEQVAL, 3 }, + { OUT, SEQREG, 3, SEQVAL, 0 }, + { OUT, SEQREG, 4, SEQVAL, 2 }, + + /* Misc out reg */ + { OUT, GENREG1, 0x63, 0, 0 }, + + /* Sequencer enable */ + { OUT, SEQREG, 0, SEQVAL, 3 }, + + /* Unprotect crtc regs 0-7 */ + { OUT, CRTCREG, 0x11, CRTCVAL, 0 }, + + /* Crtc */ + { OUT, CRTCREG, 0, CRTCVAL, 0x5f }, /* horiz total */ + { OUT, CRTCREG, 1, CRTCVAL, 0x4f }, /* horiz end */ + { OUT, CRTCREG, 2, CRTCVAL, 0x50 }, /* horiz blank */ + { OUT, CRTCREG, 3, CRTCVAL, 0x82 }, /* end blank */ + { OUT, CRTCREG, 4, CRTCVAL, 0x55 }, /* horiz retrace */ + { OUT, CRTCREG, 5, CRTCVAL, 0x81 }, /* end retrace */ + { OUT, CRTCREG, 6, CRTCVAL, 0xbf }, /* vert total */ + { OUT, CRTCREG, 7, CRTCVAL, 0x1f }, /* overflows */ + { OUT, CRTCREG, 8, CRTCVAL, 0x00 }, /* row scan */ + { OUT, CRTCREG, 9, CRTCVAL, 0x4f }, /* max scan line */ + { OUT, CRTCREG, 10, CRTCVAL, 0x00 }, /* cursor start */ + { OUT, CRTCREG, 11, CRTCVAL, 0x0f }, /* cursor end */ + { OUT, CRTCREG, 12, CRTCVAL, 0x0e }, /* start high addr */ + { OUT, CRTCREG, 13, CRTCVAL, 0xb0 }, /* low addr */ + { OUT, CRTCREG, 14, CRTCVAL, 0x16 }, /* cursor high */ + { OUT, CRTCREG, 15, CRTCVAL, 0x30 }, /* cursor low */ + { OUT, CRTCREG, 16, CRTCVAL, 0x9c }, /* vert retrace */ + { OUT, CRTCREG, 17, CRTCVAL, 0x8e }, /* retrace end */ + { OUT, CRTCREG, 18, CRTCVAL, 0x8f }, /* vert end */ + { OUT, CRTCREG, 19, CRTCVAL, 0x28 }, /* offset */ + { OUT, CRTCREG, 20, CRTCVAL, 0x1f }, /* underline */ + { OUT, CRTCREG, 21, CRTCVAL, 0x96 }, /* vert blank */ + { OUT, CRTCREG, 22, CRTCVAL, 0xb9 }, /* end blank */ + { OUT, CRTCREG, 23, CRTCVAL, 0xa3 }, /* crt mode */ + { OUT, CRTCREG, 24, CRTCVAL, 0xff }, /* line compare */ + + /* Graphics controller */ + { OUT, GENREG2, 0x00, 0, 0 }, + { OUT, GENREG3, 0x01, 0, 0 }, + { OUT, GRREG, 0, GRVAL, 0x00 }, + { OUT, GRREG, 1, GRVAL, 0x00 }, + { OUT, GRREG, 2, GRVAL, 0x00 }, + { OUT, GRREG, 3, GRVAL, 0x00 }, + { OUT, GRREG, 4, GRVAL, 0x00 }, + { OUT, GRREG, 5, GRVAL, 0x10 }, + { OUT, GRREG, 6, GRVAL, 0x0e }, + { OUT, GRREG, 7, GRVAL, 0x00 }, + { OUT, GRREG, 8, GRVAL, 0xff }, + + /* Reset attribute flip/flop */ + { IN, ATTRREG, 0, 0, 0 }, + + /* Palette */ + { OUT, PALREG, 0, PALREG, 0x00 }, + { OUT, PALREG, 1, PALREG, 0x01 }, + { OUT, PALREG, 2, PALREG, 0x02 }, + { OUT, PALREG, 3, PALREG, 0x03 }, + { OUT, PALREG, 4, PALREG, 0x04 }, + { OUT, PALREG, 5, PALREG, 0x05 }, + { OUT, PALREG, 6, PALREG, 0x06 }, + { OUT, PALREG, 7, PALREG, 0x07 }, + { OUT, PALREG, 8, PALREG, 0x10 }, + { OUT, PALREG, 9, PALREG, 0x11 }, + { OUT, PALREG, 10, PALREG, 0x12 }, + { OUT, PALREG, 11, PALREG, 0x13 }, + { OUT, PALREG, 12, PALREG, 0x14 }, + { OUT, PALREG, 13, PALREG, 0x15 }, + { OUT, PALREG, 14, PALREG, 0x16 }, + { OUT, PALREG, 15, PALREG, 0x17 }, + { OUT, PALREG, 16, PALREG, 0x08 }, + { OUT, PALREG, 17, PALREG, 0x00 }, + { OUT, PALREG, 18, PALREG, 0x0f }, + { OUT, PALREG, 19, PALREG, 0x00 }, + + /* Enable palette */ + { OUT, PALREG, 0x20, 0, 0 }, + + /* End of table */ + { DONE, 0, 0, 0, 0 } +}; + +#endif + +#if EGA_STANDARD + +/* EGA 640x350 16-color graphics (BIOS mode 0x10). + */ +static REGIO graphics_on[] = { + /* Reset attr F/F */ + IN, ATTRREG, 0, 0, 0, + + /* Disable palette */ + OUT, PALREG, 0, 0, 0, + + /* Reset sequencer regs */ + OUT, SEQREG, 0, SEQVAL, 0, + OUT, SEQREG, 1, SEQVAL, 1, + OUT, SEQREG, 2, SEQVAL, 0x0f, + OUT, SEQREG, 3, SEQVAL, 0, + OUT, SEQREG, 4, SEQVAL, 6, + + /* Misc out reg */ + OUT, GENREG1, 0xa7, 0, 0, + + /* Sequencer enable */ + OUT, SEQREG, 0, SEQVAL, 0x03, + + /* Unprotect crtc regs 0-7 */ + OUT, CRTCREG, 0x11, CRTCVAL, 0, + + /* Crtc */ + OUT, CRTCREG, 0, CRTCVAL, 0x5b, + OUT, CRTCREG, 1, CRTCVAL, 0x4f, + OUT, CRTCREG, 2, CRTCVAL, 0x53, + OUT, CRTCREG, 3, CRTCVAL, 0x37, + OUT, CRTCREG, 4, CRTCVAL, 0x52, + OUT, CRTCREG, 5, CRTCVAL, 0x00, + OUT, CRTCREG, 6, CRTCVAL, 0x6c, + OUT, CRTCREG, 7, CRTCVAL, 0x1f, + OUT, CRTCREG, 8, CRTCVAL, 0x00, + OUT, CRTCREG, 9, CRTCVAL, 0x00, + OUT, CRTCREG, 10, CRTCVAL, 0x00, + OUT, CRTCREG, 11, CRTCVAL, 0x00, + OUT, CRTCREG, 12, CRTCVAL, 0x00, + OUT, CRTCREG, 13, CRTCVAL, 0x00, + OUT, CRTCREG, 14, CRTCVAL, 0x00, + OUT, CRTCREG, 15, CRTCVAL, 0x00, + OUT, CRTCREG, 16, CRTCVAL, 0x5e, + OUT, CRTCREG, 17, CRTCVAL, 0x2b, + OUT, CRTCREG, 18, CRTCVAL, 0x5d, + OUT, CRTCREG, 19, CRTCVAL, 0x28, + OUT, CRTCREG, 20, CRTCVAL, 0x0f, + OUT, CRTCREG, 21, CRTCVAL, 0x5f, + OUT, CRTCREG, 22, CRTCVAL, 0x0a, + OUT, CRTCREG, 23, CRTCVAL, 0xe3, + OUT, CRTCREG, 24, CRTCVAL, 0xff, + + /* Graphics controller */ + OUT, GENREG2, 0x00, 0, 0, + OUT, GENREG3, 0x01, 0, 0, + OUT, GRREG, 0, GRVAL, 0x00, + OUT, GRREG, 1, GRVAL, 0x00, + OUT, GRREG, 2, GRVAL, 0x00, + OUT, GRREG, 3, GRVAL, 0x00, + OUT, GRREG, 4, GRVAL, 0x00, + OUT, GRREG, 5, GRVAL, 0x00, + OUT, GRREG, 6, GRVAL, 0x05, + OUT, GRREG, 7, GRVAL, 0x0f, + OUT, GRREG, 8, GRVAL, 0xff, + + /* Reset attribute flip/flop */ + IN, ATTRREG, 0, 0, 0, + + /* Palette */ + OUT, PALREG, 0, PALREG, 0x00, + OUT, PALREG, 1, PALREG, 0x01, + OUT, PALREG, 2, PALREG, 0x02, + OUT, PALREG, 3, PALREG, 0x03, + OUT, PALREG, 4, PALREG, 0x04, + OUT, PALREG, 5, PALREG, 0x05, + OUT, PALREG, 6, PALREG, 0x06, + OUT, PALREG, 7, PALREG, 0x07, + OUT, PALREG, 8, PALREG, 0x38, + OUT, PALREG, 9, PALREG, 0x39, + OUT, PALREG, 10, PALREG, 0x3a, + OUT, PALREG, 11, PALREG, 0x3b, + OUT, PALREG, 12, PALREG, 0x3c, + OUT, PALREG, 13, PALREG, 0x3d, + OUT, PALREG, 14, PALREG, 0x3e, + OUT, PALREG, 15, PALREG, 0x3f, + OUT, PALREG, 16, PALREG, 0x01, + OUT, PALREG, 17, PALREG, 0x00, + OUT, PALREG, 18, PALREG, 0x0f, + OUT, PALREG, 19, PALREG, 0x00, + + /* Enable palette */ + OUT, PALREG, 0x20, 0, 0, + + /* End of table */ + DONE, 0, 0, 0, 0 +}; + +/* EGA 80x25 text (BIOS mode 3). + */ +static REGIO graph_off[] = { + /* Reset attr F/F */ + IN, ATTRREG, 0, 0, 0, + + /* Disable palette */ + OUT, PALREG, 0, 0, 0, + + /* Reset sequencer regs */ + OUT, SEQREG, 0, SEQVAL, 1, + OUT, SEQREG, 1, SEQVAL, 1, + OUT, SEQREG, 2, SEQVAL, 3, + OUT, SEQREG, 3, SEQVAL, 0, + OUT, SEQREG, 4, SEQVAL, 3, + + /* Misc out reg */ + OUT, GENREG1, 0xa7, 0, 0, + + /* Sequencer enable */ + OUT, SEQREG, 0, SEQVAL, 3, + + /* Crtc */ + OUT, CRTCREG, 0, CRTCVAL, 0x5b, /* horiz total */ + OUT, CRTCREG, 1, CRTCVAL, 0x4f, /* horiz end */ + OUT, CRTCREG, 2, CRTCVAL, 0x53, /* horiz blank */ + OUT, CRTCREG, 3, CRTCVAL, 0x37, /* end blank */ + OUT, CRTCREG, 4, CRTCVAL, 0x51, /* horiz retrace */ + OUT, CRTCREG, 5, CRTCVAL, 0x5b, /* end retrace */ + OUT, CRTCREG, 6, CRTCVAL, 0x6c, /* vert total */ + OUT, CRTCREG, 7, CRTCVAL, 0x1f, /* overflows */ + OUT, CRTCREG, 8, CRTCVAL, 0x00, /* row scan */ + OUT, CRTCREG, 9, CRTCVAL, 0x0d, /* max scan line */ + OUT, CRTCREG, 10, CRTCVAL, 0x00, /* cursor start */ + OUT, CRTCREG, 11, CRTCVAL, 0x0f, /* cursor end */ + OUT, CRTCREG, 12, CRTCVAL, 0x00, /* start high addr */ + OUT, CRTCREG, 13, CRTCVAL, 0x00, /* low addr */ + OUT, CRTCREG, 14, CRTCVAL, 0x00, /* cursor high */ + OUT, CRTCREG, 15, CRTCVAL, 0x00, /* cursor low */ + OUT, CRTCREG, 16, CRTCVAL, 0x5e, /* vert retrace */ + OUT, CRTCREG, 17, CRTCVAL, 0x2b, /* retrace end */ + OUT, CRTCREG, 18, CRTCVAL, 0x5d, /* vert end */ + OUT, CRTCREG, 19, CRTCVAL, 0x28, /* offset */ + OUT, CRTCREG, 20, CRTCVAL, 0x0f, /* underline */ + OUT, CRTCREG, 21, CRTCVAL, 0x5e, /* vert blank */ + OUT, CRTCREG, 22, CRTCVAL, 0x0a, /* end blank */ + OUT, CRTCREG, 23, CRTCVAL, 0xa3, /* crt mode */ + OUT, CRTCREG, 24, CRTCVAL, 0xff, /* line compare */ + + /* Graphics controller */ + OUT, GENREG2, 0x00, 0, 0, + OUT, GENREG3, 0x01, 0, 0, + OUT, GRREG, 0, GRVAL, 0x00, + OUT, GRREG, 1, GRVAL, 0x00, + OUT, GRREG, 2, GRVAL, 0x00, + OUT, GRREG, 3, GRVAL, 0x00, + OUT, GRREG, 4, GRVAL, 0x00, + OUT, GRREG, 5, GRVAL, 0x10, + OUT, GRREG, 6, GRVAL, 0x0e, + OUT, GRREG, 7, GRVAL, 0x00, + OUT, GRREG, 8, GRVAL, 0xff, + + /* Reset attribute flip/flop */ + IN, ATTRREG, 0, 0, 0, + + /* Palette */ + OUT, PALREG, 0, PALREG, 0x00, + OUT, PALREG, 1, PALREG, 0x01, + OUT, PALREG, 2, PALREG, 0x02, + OUT, PALREG, 3, PALREG, 0x03, + OUT, PALREG, 4, PALREG, 0x04, + OUT, PALREG, 5, PALREG, 0x05, + OUT, PALREG, 6, PALREG, 0x14, + OUT, PALREG, 7, PALREG, 0x07, + OUT, PALREG, 8, PALREG, 0x38, + OUT, PALREG, 9, PALREG, 0x39, + OUT, PALREG, 10, PALREG, 0x3a, + OUT, PALREG, 11, PALREG, 0x3b, + OUT, PALREG, 12, PALREG, 0x3c, + OUT, PALREG, 13, PALREG, 0x3d, + OUT, PALREG, 14, PALREG, 0x3e, + OUT, PALREG, 15, PALREG, 0x3f, + OUT, PALREG, 16, PALREG, 0x08, + OUT, PALREG, 17, PALREG, 0x00, + OUT, PALREG, 18, PALREG, 0x0f, + OUT, PALREG, 19, PALREG, 0x00, + + /* Enable palette */ + OUT, PALREG, 0x20, 0, 0, + + /* End of table */ + DONE, 0, 0, 0, 0 +}; + +#endif diff --git a/bsps/i386/pc386/console/videoAsm.S b/bsps/i386/pc386/console/videoAsm.S new file mode 100644 index 0000000000..03f31f879b --- /dev/null +++ b/bsps/i386/pc386/console/videoAsm.S @@ -0,0 +1,48 @@ +/* + * videoAsm.S - This file contains code for displaying cursor on the console + * + * Copyright (C) 1998 valette@crf.canon.fr + * + * This code is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + .file "videoAsm.s" + +#include + + .text + .align 4 + .globl wr_cursor /* Move cursor position */ + +/* + * void wr_cursor(newPosition, ioBaseAddr) + */ + +wr_cursor: pushl %ecx + movl 8(%esp), %ecx /* Get new cursor position */ + movb $CC_CURSHIGH, %al /* Cursor high location */ + movl 12(%esp), %edx /* Get IO base address */ + outb (%dx) + incw %dx /* Program Data register */ + movb %ch, %al + outb (%dx) /* Update high location cursor */ + decw %dx /* Program Index Register */ + movb $CC_CURSLOW, %al /* Cursor low location */ + outb (%dx) + incw %dx /* Program Data Register */ + movb %cl, %al + outb (%dx) /* Update low location cursor */ + popl %ecx + ret diff --git a/bsps/i386/pc386/console/vt.c b/bsps/i386/pc386/console/vt.c new file mode 100644 index 0000000000..022cb5d461 --- /dev/null +++ b/bsps/i386/pc386/console/vt.c @@ -0,0 +1,348 @@ +/* + * linux/drivers/char/vt.c + * + * Copyright (C) 1992 obz under the linux copyright + * + * Dynamic diacritical handling - aeb@cwi.nl - Dec 1993 + * Dynamic keymap and string allocation - aeb@cwi.nl - May 1994 + * Restrict VT switching via ioctl() - grif@cs.ucr.edu - Dec 1995 + * Some code moved for less code duplication - Andi Kleen - Mar 1997 + * + * + * by: Rosimildo da Silva -- + * Ported to RTEMS to provide the basic interface to the console + * driver. Removed all stuff not required, such as VT_, Fonts, etc. + */ + +#include /* memcpy */ +#include +#include + +#include +#include +#include +#include +#include + +/* + * Console (vt and kd) routines, as defined by USL SVR4 manual, and by + * experimentation and study of X386 SYSV handling. + * + * One point of difference: SYSV vt's are /dev/vtX, which X >= 0, and + * /dev/console is a separate ttyp. Under Linux, /dev/tty0 is /dev/console, + * and the vc start at /dev/ttyX, X >= 1. We maintain that here, so we will + * always treat our set of vt as numbered 1..MAX_NR_CONSOLES (corresponding to + * ttys 0..MAX_NR_CONSOLES-1). Explicitly naming VT 0 is illegal, but using + * /dev/tty0 (fg_console) as a target is legal, since an implicit aliasing + * to the current console is done by the main ioctl code. + */ + +struct vt_struct *vt_cons[MAX_NR_CONSOLES]; + +/* Keyboard type: Default is KB_101, but can be set by machine + * specific code. + */ +unsigned char keyboard_type = KB_101; + +/* + * Generates sound of some frequency for some number of clock ticks + * + * If freq is 0, will turn off sound, else will turn it on for that time. + * If msec is 0, will return immediately, else will sleep for msec time, then + * turn sound off. + * + * We also return immediately, which is what was implied within the X + * comments - KDMKTONE doesn't put the process to sleep. + */ + +#if defined(__i386__) || defined(__alpha__) || defined(__powerpc__) \ + || (defined(__mips__) && !defined(CONFIG_SGI)) + +static void +kd_nosound(unsigned long ignored) +{ + /* disable counter 2 */ + outb(inb_p(0x61)&0xFC, 0x61); + return; +} + +static void +_kd_mksound(unsigned int hz, unsigned int ticks) +{ + unsigned int count = 0; + rtems_interrupt_lock_context lock_context; + + if (hz > 20 && hz < 32767) + count = 1193180 / hz; + + rtems_interrupt_lock_acquire(&rtems_i386_i8254_access_lock, &lock_context); +/* del_timer(&sound_timer); */ + if (count) { + /* enable counter 2 */ + outb_p(inb_p(0x61)|3, 0x61); + /* set command for counter 2, 2 byte write */ + outb_p(0xB6, TIMER_MODE); + /* select desired HZ */ + outb_p(count & 0xff, TIMER_CNTR2); + outb((count >> 8) & 0xff, TIMER_CNTR2); + +/* + if (ticks) { + sound_timer.expires = jiffies+ticks; + add_timer(&sound_timer); + } +*/ + } else + kd_nosound(0); + + rtems_interrupt_lock_release(&rtems_i386_i8254_access_lock, &lock_context); + return; +} + +#else + +void +_kd_mksound(unsigned int hz, unsigned int ticks) +{ +} + +#endif + +void (*kd_mksound)(unsigned int hz, unsigned int ticks) = _kd_mksound; + +#define i (tmp.kb_index) +#define s (tmp.kb_table) +#define v (tmp.kb_value) +static inline int +do_kdsk_ioctl(int cmd, struct kbentry *user_kbe, int perm, struct kbd_struct *kbd) +{ + struct kbentry tmp; + ushort *key_map, val; + + tmp = *user_kbe; + if (i >= NR_KEYS) /* s cannot be >= MAX_NR_KEYMAPS */ + return -EINVAL; + + switch (cmd) { + case KDGKBENT: + key_map = key_maps[s]; + if (key_map) { + val = U(key_map[i]); + if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES) + val = K_HOLE; + } else + val = (i ? K_HOLE : K_NOSUCHMAP); + user_kbe->kb_value = val; + return 0; + + case KDSKBENT: + return -EINVAL; + } + return 0; +} +#undef i +#undef s +#undef v + +#define HZ 100 + +static inline int +do_kbkeycode_ioctl(int cmd, struct kbkeycode *user_kbkc, int perm) +{ + struct kbkeycode tmp; + int kc = 0; + + tmp = *user_kbkc; + switch (cmd) { + case KDGETKEYCODE: + kc = getkeycode(tmp.scancode); + if (kc >= 0) + user_kbkc->keycode = kc; + break; + case KDSETKEYCODE: + if (!perm) + return -EPERM; + kc = setkeycode(tmp.scancode, tmp.keycode); + break; + } + return kc; +} + +static inline int +do_kdgkb_ioctl(int cmd, struct kbsentry *user_kdgkb, int perm) +{ + return -EINVAL; +} + +/* + * We handle the console-specific ioctl's here. We allow the + * capability to modify any console, not just the fg_console. + */ +int vt_ioctl( unsigned int cmd, unsigned long arg) +{ + int perm; + unsigned int console; + unsigned char ucval; + struct kbd_struct * kbd; + + console = 0; + /* + * To have permissions to do most of the vt ioctls, we either have + * to be the owner of the tty, or super-user. + */ + perm = 1; + kbd = kbd_table + console; + switch (cmd) { + case KIOCSOUND: + if (!perm) + return -EPERM; + if (arg) + arg = 1193180 / arg; + kd_mksound(arg, 0); + return 0; + + case KDMKTONE: + if (!perm) + return -EPERM; + { + unsigned int ticks, count; + + /* + * Generate the tone for the appropriate number of ticks. + * If the time is zero, turn off sound ourselves. + */ + ticks = HZ * ((arg >> 16) & 0xffff) / 1000; + count = ticks ? (arg & 0xffff) : 0; + if (count) + count = 1193180 / count; + kd_mksound(count, ticks); + return 0; + } + + case KDGKBTYPE: + /* + * this is naive. + */ + ucval = keyboard_type; + goto setchar; + + case KDSETMODE: + case KDGETMODE: + return -EINVAL; + + case KDSKBMODE: + if (!perm) + return -EPERM; + switch(arg) { + case K_RAW: + kbd->kbdmode = VC_RAW; + break; + case K_MEDIUMRAW: + kbd->kbdmode = VC_MEDIUMRAW; + break; + case K_XLATE: + kbd->kbdmode = VC_XLATE; + compute_shiftstate(); + break; + case K_UNICODE: + kbd->kbdmode = VC_UNICODE; + compute_shiftstate(); + break; + default: + return -EINVAL; + } + return 0; + + case KDGKBMODE: + ucval = ((kbd->kbdmode == VC_RAW) ? K_RAW : + (kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW : + (kbd->kbdmode == VC_UNICODE) ? K_UNICODE : + K_XLATE); + goto setint; + + /* this could be folded into KDSKBMODE, but for compatibility + reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */ + case KDSKBMETA: + switch(arg) { + case K_METABIT: + clr_vc_kbd_mode(kbd, VC_META); + break; + case K_ESCPREFIX: + set_vc_kbd_mode(kbd, VC_META); + break; + default: + return -EINVAL; + } + return 0; + + case KDGKBMETA: + ucval = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT); + setint: + *(int *)arg = ucval; + return 0; + + case KDGETKEYCODE: + case KDSETKEYCODE: + return do_kbkeycode_ioctl(cmd, (struct kbkeycode *)arg, perm); + + case KDGKBENT: + case KDSKBENT: + return do_kdsk_ioctl(cmd, (struct kbentry *)arg, perm, kbd); + + case KDGKBDIACR: + { + struct kbdiacrs *a = (struct kbdiacrs *)arg; + a->kb_cnt = accent_table_size; + memcpy( a->kbdiacr, accent_table, accent_table_size*sizeof(struct kbdiacr) ); + return 0; + } + + case KDSKBDIACR: + { + struct kbdiacrs *a = (struct kbdiacrs *)arg; + unsigned int ct; + + if (!perm) + return -EPERM; + ct = a->kb_cnt; + if (ct >= MAX_DIACR) + return -EINVAL; + accent_table_size = ct; + memcpy(accent_table, a->kbdiacr, ct*sizeof(struct kbdiacr)); + return 0; + } + + /* the ioctls below read/set the flags usually shown in the leds */ + /* don't use them - they will go away without warning */ + case KDGKBLED: + ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4); + goto setchar; + + case KDSKBLED: + if (!perm) + return -EPERM; + if (arg & ~0x77) + return -EINVAL; + kbd->ledflagstate = (arg & 7); + kbd->default_ledflagstate = ((arg >> 4) & 7); + set_leds(); + return 0; + + /* the ioctls below only set the lights, not the functions */ + /* for those, see KDGKBLED and KDSKBLED above */ + case KDGETLED: + ucval = getledstate(); + setchar: + *(char*)arg = ucval; + return 0; + + case KDSETLED: + if (!perm) + return -EPERM; + setledstate(kbd, arg); + return 0; + + default: + return -EINVAL; + } +} diff --git a/bsps/lm32/shared/console/console.c b/bsps/lm32/shared/console/console.c new file mode 100644 index 0000000000..d49ca346b6 --- /dev/null +++ b/bsps/lm32/shared/console/console.c @@ -0,0 +1,178 @@ +/* + * Console driver for Lattice Mico32 (lm32). + */ + +/* + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + * Jukka Pietarinen , 2008, + * Micro-Research Finland Oy + */ + +#define NO_BSP_INIT + +#include +#include +#include +#include + +/* console_initialize + * + * This routine initializes the console IO driver. + */ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + + printk("console_initialize\n"); + + status = rtems_io_register_name( + "/dev/console", + major, + (rtems_device_minor_number) 0 + ); + + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + return RTEMS_SUCCESSFUL; +} + +/* inbyte + * + * This routine reads a character from the SOURCE. + */ +static int inbyte( void ) +{ + /* + * If polling, wait until a character is available. + */ + return BSP_uart_polled_read(); +} + +/* outbyte + * + * This routine transmits a character out the SOURCE. It may support + * XON/XOFF flow control. + */ +static void outbyte( + char ch +) +{ + /* + * If polling, wait for the transmitter to be ready. + * Check for flow control requests and process. + * Then output the character. + */ + + BSP_uart_polled_write(ch); +} + +/* + * Open entry point + */ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * Close entry point + */ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * read bytes from the serial port. We only have stdin. + */ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args; + char *buffer; + int maximum; + int count = 0; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + buffer[ count ] = inbyte(); + if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { + buffer[ count++ ] = '\n'; + break; + } + } + + rw_args->bytes_moved = count; + return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; +} + +/* + * write bytes to the serial port. Stdout and stderr are the same. + */ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + int count; + int maximum; + rtems_libio_rw_args_t *rw_args; + char *buffer; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + if ( buffer[ count ] == '\n') { + outbyte('\r'); + } + outbyte( buffer[ count ] ); + } + + rw_args->bytes_moved = maximum; + return 0; +} + +/* + * IO Control entry point + */ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +BSP_output_char_function_type BSP_output_char = BSP_uart_polled_write; +BSP_polling_getchar_function_type BSP_poll_char = BSP_uart_polled_read; diff --git a/bsps/lm32/shared/console/uart.c b/bsps/lm32/shared/console/uart.c new file mode 100644 index 0000000000..9adbd4063d --- /dev/null +++ b/bsps/lm32/shared/console/uart.c @@ -0,0 +1,73 @@ +/* + * Uart driver for Lattice Mico32 (lm32) UART + */ + +/* + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + * Jukka Pietarinen , 2008, + * Micro-Research Finland Oy + */ + +#include "../include/system_conf.h" +#include "uart.h" +#include +#include + +static inline int uartread(unsigned int reg) +{ + return *((int*)(UART_BASE_ADDRESS + reg)); +} + +static inline void uartwrite(unsigned int reg, int value) +{ + *((int*)(UART_BASE_ADDRESS + reg)) = value; +} + +void BSP_uart_init(int baud) +{ + /* Disable UART interrupts */ + uartwrite(LM32_UART_IER, 0); + + /* Line control 8 bit, 1 stop, no parity */ + uartwrite(LM32_UART_LCR, LM32_UART_LCR_8BIT); + + /* Modem control, DTR = 1, RTS = 1 */ + uartwrite(LM32_UART_MCR, LM32_UART_MCR_DTR | LM32_UART_MCR_RTS); + + /* Set baud rate */ + uartwrite(LM32_UART_DIV, CPU_FREQUENCY/baud); +} + +void BSP_uart_polled_write(char ch) +{ + /* Insert CR before LF */ + if (ch == '\n') + BSP_uart_polled_write('\r'); + /* Wait until THR is empty. */ + while (!(uartread(LM32_UART_LSR) & LM32_UART_LSR_THRE)); + uartwrite(LM32_UART_RBR, ch); +} + +int BSP_uart_polled_read( void ) +{ + /* Wait until there is a byte in RBR */ + while (!(uartread(LM32_UART_LSR) & LM32_UART_LSR_DR)); + return (int) uartread(LM32_UART_RBR); +} + +char BSP_uart_is_character_ready(char *ch) +{ + if (uartread(LM32_UART_LSR) & LM32_UART_LSR_DR) + { + *ch = (char) uartread(LM32_UART_RBR); + return true; + } + *ch = '0'; + return false; +} diff --git a/bsps/lm32/shared/console/uart.h b/bsps/lm32/shared/console/uart.h new file mode 100644 index 0000000000..baafde13e2 --- /dev/null +++ b/bsps/lm32/shared/console/uart.h @@ -0,0 +1,102 @@ +/** + * @file + * @ingroup lm32_shared lm32_uart + * @brief LatticeMico32 UART definitions + */ + +/* + * This file contains definitions for LatticeMico32 UART + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + * Jukka Pietarinen , 2008, + * Micro-Research Finland Oy + */ + +/** + * @defgroup lm32_uart LM32 UART + * @ingroup lm32_shared + * @brief LatticeMico32 UART definitions + * @{ + */ + +#ifndef _BSPUART_H +#define _BSPUART_H + +void BSP_uart_init(int baud); + +/* Receive buffer register / transmit holding register */ + +#define LM32_UART_RBR (0x0000) + +/* Interrupt enable register */ + +#define LM32_UART_IER (0x0004) +#define LM32_UART_IER_RBRI (0x0001) +#define LM32_UART_IER_THRI (0x0002) +#define LM32_UART_IER_RLSI (0x0004) +#define LM32_UART_IER_MSI (0x0008) + +/* Interrupt identification register */ + +#define LM32_UART_IIR (0x0008) +#define LM32_UART_IIR_STAT (0x0001) +#define LM32_UART_IIR_ID0 (0x0002) +#define LM32_UART_IIR_ID1 (0x0004) + +/* Line control register */ + +#define LM32_UART_LCR (0x000C) +#define LM32_UART_LCR_WLS0 (0x0001) +#define LM32_UART_LCR_WLS1 (0x0002) +#define LM32_UART_LCR_STB (0x0004) +#define LM32_UART_LCR_PEN (0x0008) +#define LM32_UART_LCR_EPS (0x0010) +#define LM32_UART_LCR_SP (0x0020) +#define LM32_UART_LCR_SB (0x0040) +#define LM32_UART_LCR_5BIT (0) +#define LM32_UART_LCR_6BIT (LM32_UART_LCR_WLS0) +#define LM32_UART_LCR_7BIT (LM32_UART_LCR_WLS1) +#define LM32_UART_LCR_8BIT (LM32_UART_LCR_WLS1 | LM32_UART_LCR_WLS0) + +/* Modem control register */ + +#define LM32_UART_MCR (0x0010) +#define LM32_UART_MCR_DTR (0x0001) +#define LM32_UART_MCR_RTS (0x0002) + +/* Line status register */ + +#define LM32_UART_LSR (0x0014) +#define LM32_UART_LSR_DR (0x0001) +#define LM32_UART_LSR_OE (0x0002) +#define LM32_UART_LSR_PE (0x0004) +#define LM32_UART_LSR_FE (0x0008) +#define LM32_UART_LSR_BI (0x0010) +#define LM32_UART_LSR_THRE (0x0020) +#define LM32_UART_LSR_TEMT (0x0040) + +/* Modem status register */ + +#define LM32_UART_MSR (0x0018) +#define LM32_UART_MSR_DCTS (0x0001) +#define LM32_UART_MSR_DDSR (0x0002) +#define LM32_UART_MSR_TERI (0x0004) +#define LM32_UART_MSR_DDCD (0x0008) +#define LM32_UART_MSR_CTS (0x0010) +#define LM32_UART_MSR_DSR (0x0020) +#define LM32_UART_MSR_RI (0x0040) +#define LM32_UART_MSR_DCD (0x0000) + +/* Baud-rate divisor register */ + +#define LM32_UART_DIV (0x001C) + +#endif /* _BSPUART_H */ + +/** @} */ diff --git a/bsps/m32c/m32cbsp/console/console-io.c b/bsps/m32c/m32cbsp/console/console-io.c new file mode 100644 index 0000000000..745493c43a --- /dev/null +++ b/bsps/m32c/m32cbsp/console/console-io.c @@ -0,0 +1,65 @@ +/* + * This file contains the hardware specific portions of the TTY driver + * for the serial ports on the m32c simulator in gdb. + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include + +/* + * console_initialize_hardware + * + * This routine initializes the console hardware. + * + */ + +void console_initialize_hardware(void) +{ + return; +} + +/* + * console_outbyte_polled + * + * This routine transmits a character using polling. + */ +ssize_t sys_write(int fd, const void *buf, size_t count); +void console_outbyte_polled( + int port, + char ch +) +{ + sys_write( 2, &ch, 1 ); +} + +/* + * console_inbyte_nonblocking + * + * This routine polls for a character. + */ + +int console_inbyte_nonblocking( + int port +) +{ + return -1; +} + +#include + +static void M32CsimBSP_output_char(char c) { console_outbyte_polled( 0, c ); } + +BSP_output_char_function_type BSP_output_char = M32CsimBSP_output_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/m32c/m32cbsp/console/syscalls.S b/bsps/m32c/m32cbsp/console/syscalls.S new file mode 100644 index 0000000000..f4cabac940 --- /dev/null +++ b/bsps/m32c/m32cbsp/console/syscalls.S @@ -0,0 +1,43 @@ +/* + * System call support for simulator in gdb. + * Adapted from newlib 1.16.0. + */ + +#define SYS_exit 1 +#define SYS_open 2 +#define SYS_close 3 +#define SYS_read 4 +#define SYS_write 5 +#define SYS_lseek 6 +#define SYS_unlink 7 +#define SYS_getpid 8 +#define SYS_kill 9 +#define SYS_fstat 10 +#define SYS_sbrk 11 + +#define POUND # +#define SYSCALL(N) mov.b POUND N,0x400 + +#define S(n) _sys_##n: .global _sys_##n | SYSCALL(SYS_##n) | rts + +S(write) +S(exit) +S(sbrk) + + .global _abort +_abort: + /* This is for debuggers. The simulator stops here too. */ + brk + + /* Else, fall back on the simulator's "kill me" option. */ +#if defined(__r8c_cpu__) || defined(__m16c_cpu__) + mov.w #42,r1 +#else + mov.w #42,r0 +#endif + + SYSCALL(SYS_kill) + + /* Else, exit. */ + jmp.a __exit + diff --git a/bsps/m68k/av5282/console/console.c b/bsps/m68k/av5282/console/console.c new file mode 100644 index 0000000000..dd557660f8 --- /dev/null +++ b/bsps/m68k/av5282/console/console.c @@ -0,0 +1,711 @@ +/* + * Multi UART console serial I/O. + * + * TO DO: Add DMA input/output + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x)) + +#define MCF5282_UART_USR_ERROR ( MCF5282_UART_USR_RB | \ + MCF5282_UART_USR_FE | \ + MCF5282_UART_USR_PE | \ + MCF5282_UART_USR_OE ) + +static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); +static ssize_t IntUartInterruptWrite (int minor, const char *buf, size_t len); + +static void _BSP_null_char( char c ) +{ + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + while ( (MCF5282_UART_USR(CONSOLE_PORT) & MCF5282_UART_USR_TXRDY) == 0 ) + continue; + + MCF5282_UART_UTB(CONSOLE_PORT) = c; + while ( (MCF5282_UART_USR(CONSOLE_PORT) & MCF5282_UART_USR_TXRDY) == 0 ) + continue; + + rtems_interrupt_enable(level); +} +BSP_output_char_function_type BSP_output_char = _BSP_null_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; + +#define MAX_UART_INFO 3 +#define RX_BUFFER_SIZE 512 + +struct IntUartInfoStruct +{ + int iomode; + volatile int uimr; + int baud; + int databits; + int parity; + int stopbits; + int hwflow; + int rx_in; + int rx_out; + char rx_buffer[RX_BUFFER_SIZE]; + void *ttyp; +}; + +struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; + +/* + * Function : IntUartSet + * + * Description : This updates the hardware UART settings. + */ +static void IntUartSet( + int minor, + int baud, + int databits, + int parity, + int stopbits, + int hwflow +) +{ + int divisor; + uint32_t clock_speed; + uint8_t umr1 = 0; + uint8_t umr2 = 0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + + /* disable interrupts, clear RTS line, and disable the UARTS */ + MCF5282_UART_UIMR(minor) = 0; + MCF5282_UART_UOP0(minor) = 1; + MCF5282_UART_UCR(minor) = + (MCF5282_UART_UCR_TX_DISABLED | MCF5282_UART_UCR_RX_DISABLED); + + /* save the current values */ + info->uimr = 0; + info->baud = baud; + info->databits = databits; + info->parity = parity; + info->stopbits = stopbits; + info->hwflow = hwflow; + + clock_speed = get_CPU_clock_speed(); + /* determine the baud divisor value */ + divisor = (clock_speed / ( 32 * baud )); + if ( divisor < 2 ) + divisor = 2; + + /* check to see if doing hardware flow control */ + if ( hwflow ) { + /* set hardware flow options */ + umr1 |= MCF5282_UART_UMR1_RXRTS; + umr2 |= MCF5282_UART_UMR2_TXCTS; + } + + /* determine the new umr values */ + umr1 |= (parity | databits); + umr2 |= (stopbits); + + /* reset the uart */ + MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_ERROR; + MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_RX; + MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_TX; + + /* reset the uart mode register and update values */ + MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_MR; + MCF5282_UART_UMR(minor) = umr1; + MCF5282_UART_UMR(minor) = umr2; + + /* set the baud rate values */ + MCF5282_UART_UCSR(minor) = + (MCF5282_UART_UCSR_RCS_SYS_CLK | MCF5282_UART_UCSR_TCS_SYS_CLK); + MCF5282_UART_UBG1(minor) = (divisor & 0xff00) >> 8; + MCF5282_UART_UBG2(minor) = (divisor & 0x00ff); + + /* enable the uart */ + MCF5282_UART_UCR(minor) = + (MCF5282_UART_UCR_TX_ENABLED | MCF5282_UART_UCR_RX_ENABLED); + + /* check to see if interrupts need to be enabled */ + if ( info->iomode != TERMIOS_POLLED ) { + /* enable rx interrupts */ + info->uimr |= MCF5282_UART_UIMR_FFULL; + MCF5282_UART_UIMR(minor) = info->uimr; + } + + /* check to see if doing hardware flow control */ + if ( hwflow ) { + /* assert the RTS line */ + MCF5282_UART_UOP1(minor) = 1; + } + + rtems_interrupt_enable(level); +} + +/* + * Function : IntUartSetAttributes + * + * Description : This provides the hardware-dependent portion of tcsetattr(). + * value and sets it. At the moment this just sets the baud rate. + * + * Note: The highest baudrate is 115200 as this stays within + * an error of +/- 5% at 25MHz processor clock + */ +static int IntUartSetAttributes( + int minor, + const struct termios *t +) +{ + /* set default index values */ + int baud = (int)19200; + int databits = (int)MCF5282_UART_UMR1_BC_8; + int parity = (int)MCF5282_UART_UMR1_PM_NONE; + int stopbits = (int)MCF5282_UART_UMR2_STOP_BITS_1; + int hwflow = (int)0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* check to see if input is valid */ + if ( t != (const struct termios *)0 ) { + /* determine baud rate index */ + baud = rtems_termios_baud_to_number(t->c_ospeed); + + /* determine data bits */ + switch ( t->c_cflag & CSIZE ) { + case CS5: + databits = (int)MCF5282_UART_UMR1_BC_5; + break; + case CS6: + databits = (int)MCF5282_UART_UMR1_BC_6; + break; + case CS7: + databits = (int)MCF5282_UART_UMR1_BC_7; + break; + case CS8: + databits = (int)MCF5282_UART_UMR1_BC_8; + break; + } + + /* determine if parity is enabled */ + if ( t->c_cflag & PARENB ) { + if ( t->c_cflag & PARODD ) { + /* odd parity */ + parity = (int)MCF5282_UART_UMR1_PM_ODD; + } else { + /* even parity */ + parity = (int)MCF5282_UART_UMR1_PM_EVEN; + } + } + + /* determine stop bits */ + if ( t->c_cflag & CSTOPB ) { + /* two stop bits */ + stopbits = (int)MCF5282_UART_UMR2_STOP_BITS_2; + } + + /* check to see if hardware flow control */ + if ( t->c_cflag & CRTSCTS ) { + hwflow = 1; + } + } + + /* check to see if values have changed */ + if ( ( baud != info->baud ) || + ( databits != info->databits ) || + ( parity != info->parity ) || + ( stopbits != info->stopbits ) || + ( hwflow != info->hwflow ) ) { + + /* call function to set values */ + IntUartSet(minor, baud, databits, parity, stopbits, hwflow); + } + + return RTEMS_SUCCESSFUL; +} + +/* + * Function : IntUartInterruptHandler + * + * Description : This is the interrupt handler for the internal uart. It + * determines which channel caused the interrupt before queueing any received + * chars and dequeueing chars waiting for transmission. + */ +static rtems_isr IntUartInterruptHandler(rtems_vector_number v) +{ + unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); + struct IntUartInfoStruct *info = &IntUartInfo[chan]; + + /* check to see if received data */ + if ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_RXRDY ) { + /* read data and put into the receive buffer */ + while ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_RXRDY ) { + + if ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_ERROR ) { + /* clear the error */ + MCF5282_UART_UCR(chan) = MCF5282_UART_UCR_RESET_ERROR; + } + /* put data in rx buffer and check for errors */ + info->rx_buffer[info->rx_in] = MCF5282_UART_URB(chan); + + /* update buffer values */ + info->rx_in++; + + if ( info->rx_in >= RX_BUFFER_SIZE ) { + info->rx_in = 0; + } + } + + /* Make sure the port has been opened */ + if ( info->ttyp ) { + + /* check to see if task driven */ + if ( info->iomode == TERMIOS_TASK_DRIVEN ) { + /* notify rx task that rx buffer has data */ + rtems_termios_rxirq_occured(info->ttyp); + } else { + /* Push up the received data */ + rtems_termios_enqueue_raw_characters( + info->ttyp, info->rx_buffer, info->rx_in); + info->rx_in = 0; + } + } + } + + /* check to see if data needs to be transmitted */ + if ( ( info->uimr & MCF5282_UART_UIMR_TXRDY ) && + ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_TXRDY ) ) + { + + /* disable tx interrupts */ + info->uimr &= ~MCF5282_UART_UIMR_TXRDY; + MCF5282_UART_UIMR(chan) = info->uimr; + + /* tell upper level that character has been sent */ + if ( info->ttyp ) + rtems_termios_dequeue_characters(info->ttyp, 1); + } +} + +/* + * Function : IntUartInitialize + * + * Description : This initialises the internal uart hardware for all + * internal uarts. If the internal uart is to be interrupt driven then the + * interrupt vectors are hooked. + */ +static void IntUartInitialize(void) +{ + unsigned int chan; + struct IntUartInfoStruct *info; + rtems_isr_entry old_handler; + rtems_interrupt_level level; + + for ( chan = 0; chan < MAX_UART_INFO; chan++ ) { + info = &IntUartInfo[chan]; + + info->ttyp = NULL; + info->rx_in = 0; + info->rx_out = 0; + info->baud = -1; + info->databits = -1; + info->parity = -1; + info->stopbits = -1; + info->hwflow = -1; + info->iomode = TERMIOS_POLLED; + + MCF5282_UART_UACR(chan) = 0; + MCF5282_UART_UIMR(chan) = 0; + if ( info->iomode != TERMIOS_POLLED ) { + rtems_interrupt_catch (IntUartInterruptHandler, + UART_INTC0_IRQ_VECTOR(chan), + &old_handler); + } + + /* set uart default values */ + IntUartSetAttributes(chan, NULL); + + /* unmask interrupt */ + rtems_interrupt_disable(level); + switch(chan) { + case 0: + MCF5282_INTC0_ICR13 = MCF5282_INTC_ICR_IL(UART0_IRQ_LEVEL) | + MCF5282_INTC_ICR_IP(UART0_IRQ_PRIORITY); + MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT13 | + MCF5282_INTC_IMRL_MASKALL); + break; + + case 1: + MCF5282_INTC0_ICR14 = MCF5282_INTC_ICR_IL(UART1_IRQ_LEVEL) | + MCF5282_INTC_ICR_IP(UART1_IRQ_PRIORITY); + MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT14 | + MCF5282_INTC_IMRL_MASKALL); + break; + + case 2: + MCF5282_INTC0_ICR15 = MCF5282_INTC_ICR_IL(UART2_IRQ_LEVEL) | + MCF5282_INTC_ICR_IP(UART2_IRQ_PRIORITY); + MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT15 | + MCF5282_INTC_IMRL_MASKALL); + break; + } + rtems_interrupt_enable(level); + + } /* of chan loop */ + + +} /* IntUartInitialise */ + + +/* + * Function : IntUartInterruptWrite + * + * Description : This writes a single character to the appropriate uart + * channel. This is either called during an interrupt or in the user's task + * to initiate a transmit sequence. Calling this routine enables Tx + * interrupts. + */ +static ssize_t IntUartInterruptWrite( + int minor, + const char *buf, + size_t len +) +{ + if (len > 0) { + /* write out character */ + MCF5282_UART_UTB(minor) = *buf; + + /* enable tx interrupt */ + IntUartInfo[minor].uimr |= MCF5282_UART_UIMR_TXRDY; + MCF5282_UART_UIMR(minor) = IntUartInfo[minor].uimr; + } + + return 0; +} + +/* + * Function : IntUartInterruptOpen + * + * Description : This enables interrupts when the tty is opened. + */ +static int IntUartInterruptOpen( + int major, + int minor, + void *arg +) +{ + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* enable the uart */ + MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_ENABLED | + MCF5282_UART_UCR_RX_ENABLED); + + /* check to see if interrupts need to be enabled */ + if ( info->iomode != TERMIOS_POLLED ) { + /* enable rx interrupts */ + info->uimr |= MCF5282_UART_UIMR_FFULL; + MCF5282_UART_UIMR(minor) = info->uimr; + } + + /* check to see if doing hardware flow control */ + if ( info->hwflow ) { + /* assert the RTS line */ + MCF5282_UART_UOP1(minor) = 1; + } + + return 0; +} + +/* + * Function : IntUartInterruptClose + * + * Description : This disables interrupts when the tty is closed. + */ +static int IntUartInterruptClose( + int major, + int minor, + void *arg +) +{ + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* disable the interrupts and the uart */ + MCF5282_UART_UIMR(minor) = 0; + MCF5282_UART_UCR(minor) = + (MCF5282_UART_UCR_TX_DISABLED | MCF5282_UART_UCR_RX_DISABLED); + + /* reset values */ + info->ttyp = NULL; + info->uimr = 0; + info->rx_in = 0; + info->rx_out = 0; + + return 0; +} + +/* + * Function : IntUartTaskRead + * + * Description : This reads all available characters from the internal uart + * and places them into the termios buffer. The rx interrupts will be + * re-enabled after all data has been read. + */ +static int IntUartTaskRead(int minor) +{ + char buffer[RX_BUFFER_SIZE]; + int count; + int rx_in; + int index = 0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* determine number of values to copy out */ + rx_in = info->rx_in; + if ( info->rx_out <= rx_in ) { + count = rx_in - info->rx_out; + } else { + count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; + } + + /* copy data into local buffer from rx buffer */ + while ( ( index < count ) && ( index < RX_BUFFER_SIZE ) ) { + /* copy data byte */ + buffer[index] = info->rx_buffer[info->rx_out]; + index++; + + /* increment rx buffer values */ + info->rx_out++; + if ( info->rx_out >= RX_BUFFER_SIZE ) { + info->rx_out = 0; + } + } + + /* check to see if buffer is not empty */ + if ( count > 0 ) { + /* set characters into termios buffer */ + rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); + } + + return EOF; +} + + + +/* + * Function : IntUartPollRead + * + * Description : This reads a character from the internal uart. It returns + * to the caller without blocking if not character is waiting. + */ +static int IntUartPollRead(int minor) +{ + if ( (MCF5282_UART_USR(minor) & MCF5282_UART_USR_RXRDY) == 0 ) + return-1; + + return MCF5282_UART_URB(minor); +} + + +/* + * Function : IntUartPollWrite + * + * Description : This writes out each character in the buffer to the + * appropriate internal uart channel waiting till each one is sucessfully + * transmitted. + */ +static ssize_t IntUartPollWrite( + int minor, + const char *buf, + size_t len +) +{ + size_t retval = len; + /* loop over buffer */ + + while ( len-- ) { + /* block until we can transmit */ + while ( (MCF5282_UART_USR(minor) & MCF5282_UART_USR_TXRDY) == 0 ) + continue; + /* transmit data byte */ + MCF5282_UART_UTB(minor) = *buf++; + } + return retval; +} + +/* + * Function : console_initialize + * + * Description : This initialises termios, both sets of uart hardware before + * registering /dev/tty devices for each channel and the system /dev/console. + */ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + + /* Set up TERMIOS */ + rtems_termios_initialize (); + + /* set io modes for the different channels and initialize device */ + IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN; + IntUartInitialize(); + + /* Register the console port */ + status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT); + if ( status != RTEMS_SUCCESSFUL ) { + rtems_fatal_error_occurred (status); + } + + /* Register the other port */ + if ( CONSOLE_PORT != 0 ) { + status = rtems_io_register_name ("/dev/tty00", major, 0); + if ( status != RTEMS_SUCCESSFUL ) { + rtems_fatal_error_occurred (status); + } + } + if ( CONSOLE_PORT != 1 ) { + status = rtems_io_register_name ("/dev/tty01", major, 1); + if ( status != RTEMS_SUCCESSFUL ) { + rtems_fatal_error_occurred (status); + } + } + + return RTEMS_SUCCESSFUL; +} + +/* + * Function : console_open + * + * Description : This actually opens the device depending on the minor + * number set during initialisation. The device specific access routines are + * passed to termios when the devices is opened depending on whether it is + * polled or not. + */ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_status_code status = RTEMS_INVALID_NUMBER; + rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *)arg; + struct IntUartInfoStruct *info; + + static const rtems_termios_callbacks IntUartPollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + IntUartPollRead, /* pollRead */ + IntUartPollWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_POLLED /* mode */ + }; + static const rtems_termios_callbacks IntUartIntrCallbacks = { + IntUartInterruptOpen, /* firstOpen */ + IntUartInterruptClose, /* lastClose */ + NULL, /* pollRead */ + IntUartInterruptWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_IRQ_DRIVEN /* mode */ + }; + + static const rtems_termios_callbacks IntUartTaskCallbacks = { + IntUartInterruptOpen, /* firstOpen */ + IntUartInterruptClose, /* lastClose */ + IntUartTaskRead, /* pollRead */ + IntUartInterruptWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_TASK_DRIVEN /* mode */ + }; + + /* open the port depending on the minor device number */ + if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) ) { + info = &IntUartInfo[minor]; + switch ( info->iomode ) { + case TERMIOS_POLLED: + status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); + break; + case TERMIOS_IRQ_DRIVEN: + status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); + info->ttyp = args->iop->data1; + break; + case TERMIOS_TASK_DRIVEN: + status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); + info->ttyp = args->iop->data1; + break; + } + } + + return status; +} + +/* + * Function : console_close + * + * Description : This closes the device via termios + */ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_close(arg); +} + +/* + * Function : console_read + * + * Description : Read from the device via termios + */ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + return rtems_termios_read(arg); +} + +/* + * Function : console_write + * + * Description : Write to the device via termios + */ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + return rtems_termios_write(arg); +} + +/* + * Function : console_ioctl + * + * Description : Pass the IOCtl call to termios + */ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + return rtems_termios_ioctl(arg); +} diff --git a/bsps/m68k/csb360/console/console-io.c b/bsps/m68k/csb360/console/console-io.c new file mode 100644 index 0000000000..9b0aeac5bb --- /dev/null +++ b/bsps/m68k/csb360/console/console-io.c @@ -0,0 +1,97 @@ +/* + * This file contains the hardware specific portions of the TTY driver + * for the serial ports on the mcf5272 + */ + +/* + * COPYRIGHT (c) 1989-2000. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include + +volatile int g_cnt = 0; + +/* + * console_initialize_hardware + * + * This routine initializes the console hardware. + * + */ + +void console_initialize_hardware(void) +{ +} + + +/* + * console_outbyte_polled + * + * This routine transmits a character using polling. + */ + +void console_outbyte_polled( + int port, + char ch +) +{ + uart_regs_t *uart; + int i; + if (port == 0) { + uart = g_uart0_regs; + } else { + uart = g_uart1_regs; + } + + /* wait for the fifo to make room */ +/* while ((uart->usr & MCF5272_USR_TXRDY) == 0) { */ + while ((uart->ucsr & MCF5272_USR_TXRDY) == 0) { + continue; + } + + uart->udata = ch; + for (i = 0; i < 1000; i++) g_cnt++; +} + +/* + * console_inbyte_nonblocking + * + * This routine polls for a character. + */ + +int console_inbyte_nonblocking( + int port +) +{ + uart_regs_t *uart; + unsigned char c; + + if (port == 0) { + uart = g_uart0_regs; + } else { + uart = g_uart1_regs; + } + +/* if (uart->usr & MCF5272_USR_RXRDY) { */ + if (uart->ucsr & MCF5272_USR_RXRDY) { + c = (char)uart->udata; + return c; + } else { + return -1; + } +} + +#include + +static void mcf5272_output_char(char c) { console_outbyte_polled( 0, c ); } + +BSP_output_char_function_type BSP_output_char = mcf5272_output_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; + diff --git a/bsps/m68k/gen68340/console/console.c b/bsps/m68k/gen68340/console/console.c new file mode 100644 index 0000000000..d6634b1079 --- /dev/null +++ b/bsps/m68k/gen68340/console/console.c @@ -0,0 +1,690 @@ +/* + * 68340/68349 console serial I/O. + */ + +/* + * Author: + * Geoffroy Montel + * France Telecom - CNET/DSM/TAM/CAT + * 4, rue du Clos Courtel + * 35512 CESSON-SEVIGNE + * FRANCE + * + * e-mail: g_montel@yahoo.com + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define CONSOLE_VECTOR 121 +#define CONSOLE_IRQ_LEVEL 3 +#define CONSOLE_INTERRUPT_ARBITRATION 2 + +static void *ttypA; /* to remember which tty has been opened on channel A + used when interrupts are enabled */ + +static void *ttypB; /* to remember which tty has been opened on channel B + used when interrupts are enabled */ + +unsigned char DUIER_mirror = 0 ; /* reflects the state of IER register, which is Write Only */ +unsigned char Error_Status_A = 0; /* error status on Channel A */ +unsigned char Error_Status_B = 0; /* error status on Channel A */ + +/* + * Device-specific routines + */ + +#define USE_INTERRUPTS_A (m340_uart_config[UART_CHANNEL_A].mode==UART_INTERRUPTS) +#define USE_INTERRUPTS_B (m340_uart_config[UART_CHANNEL_B].mode==UART_INTERRUPTS) +#define CHANNEL_ENABLED_A m340_uart_config[UART_CHANNEL_A].enable +#define CHANNEL_ENABLED_B m340_uart_config[UART_CHANNEL_B].enable + +#define set_DUIER(a) DUIER_mirror |= (a); DUIER = DUIER_mirror +#define unset_DUIER(a) DUIER_mirror &= ~(a); DUIER = DUIER_mirror + +#define Enable_Interrupts_Tx_A if (USE_INTERRUPTS_A) set_DUIER(m340_TxRDYA) +#define Disable_Interrupts_Tx_A if (USE_INTERRUPTS_A) unset_DUIER(m340_TxRDYA) + +#define Enable_Interrupts_Tx_B if (USE_INTERRUPTS_B) set_DUIER(m340_TxRDYB) +#define Disable_Interrupts_Tx_B if (USE_INTERRUPTS_B) unset_DUIER(m340_TxRDYB) + +/****************************************************** + Name: InterruptHandler + Input parameters: vector number + Output parameters: - + Description: UART ISR Routine, called by _RTEMS_ISR + *****************************************************/ +rtems_isr +InterruptHandler (rtems_vector_number v) +{ + char ch; + + /***************************************************************************** + ** CHANNEL A ** + *****************************************************************************/ + + /* check Received Break*/ + if (DUSRA & m340_RB) { + Error_Status_A |= m340_RB; + /* reset error status */ + DUCRA = m340_Reset_Error_Status; + } + + /* buffer received ? */ + if (DUSRA & m340_Rx_RDY) { + do { + /* error encountered? */ + if (DUSRA & (m340_OE | m340_PE | m340_FE | m340_RB)) { + Error_Status_A |= DUSRA; + /* reset error status */ + DUCRA = m340_Reset_Error_Status; + /* all the characters in the queue may not be good */ + while (DUSRA & m340_Rx_RDY) + /* push them in a trash */ + ch = DURBA; + } + else { + /* this is necessary, otherwise it blocks when FIFO is full */ + ch = DURBA; + rtems_termios_enqueue_raw_characters(ttypA,&ch,1); + } + } while (DUSRA & m340_Rx_RDY); + Restart_Fifo_Full_A_Timer(); /* only if necessary (pointer to a fake function if + not in FIFO full mode) */ + } + + else /* if no character has been received */ + Restart_Check_A_Timer(); /* same remark */ + + /* ready to accept a character ? */ + if (DUISR & DUIER_mirror & m340_TxRDYA) { + Disable_Interrupts_Tx_A; + /* one character has been transmitted */ + rtems_termios_dequeue_characters(ttypA,1); + } + + /***************************************************************************** + ** CHANNEL B ** + *****************************************************************************/ + + /* check Received Break*/ + if (DUSRB & m340_RB) { + Error_Status_B |= m340_RB; + /* reset error status */ + DUCRB = m340_Reset_Error_Status; + } + + /* buffer received ? */ + if (DUSRB & m340_Rx_RDY) { + do { + if (DUSRB & (m340_OE | m340_PE | m340_FE | m340_RB)) { + Error_Status_B |= DUSRB; + /* reset error status */ + DUCRB = m340_Reset_Error_Status; + /* all the characters in the queue may not be good */ + while (DUSRB & m340_Rx_RDY) + /* push them in a trash */ + ch = DURBB; + } + else { + ch = DURBB; + rtems_termios_enqueue_raw_characters(ttypB,&ch,1); + } + + } while (DUSRB & m340_Rx_RDY); + Restart_Fifo_Full_B_Timer(); + } + else /* if no character has been received */ + Restart_Check_B_Timer(); + + /* ready to accept a character ? */ + if (DUISR & DUIER_mirror & m340_TxRDYB) { + Disable_Interrupts_Tx_B; + /* one character has been transmitted */ + rtems_termios_dequeue_characters(ttypB,1); + } +} + +/****************************************************** + Name: InterruptWrite + Input parameters: minor = channel, pointer to buffer, + and length of buffer to transmit + Output parameters: - + Description: write the first character of buf only + may be called by either console_write + or rtems_termios_enqueue_raw_characters + *****************************************************/ +static ssize_t +InterruptWrite (int minor, const char *buf, size_t len) +{ + if (minor==UART_CHANNEL_A) { + if (len>0) { + DUTBA=*buf; + Enable_Interrupts_Tx_A; + } + } + else if (minor==UART_CHANNEL_B) { + if (len>0) { + DUTBB=*buf; + Enable_Interrupts_Tx_B; + } + } + return 0; +} + +/****************************************************** + Name: dbug_out_char + Input parameters: channel, character to emit + Output parameters: - + Description: wait for the UART to be ready to emit + a character and send it + *****************************************************/ +void dbug_out_char( int minor, int ch ) +{ + if (minor==UART_CHANNEL_A) { + while (!(DUSRA & m340_Tx_RDY)) continue; + DUTBA=ch; + } + else if (minor==UART_CHANNEL_B) { + while (!(DUSRB & m340_Tx_RDY)) continue; + DUTBB=ch; + } +} + +/****************************************************** + Name: dbug_in_char + Input parameters: - + Output parameters: received character + Description: return the character in the UART + *****************************************************/ +int dbug_in_char( int minor ) +{ + if (minor==UART_CHANNEL_A) { + return DURBA; + } + else if (minor==UART_CHANNEL_B) { + return DURBB; + } + return 0; +} + +/****************************************************** + Name: dbug_char_present + Input parameters: channel # + Output parameters: TRUE or FALSE + Description: return whether there's a character + in the receive buffer + *****************************************************/ +int dbug_char_present( int minor ) +{ + if (minor==UART_CHANNEL_A) { + return (DUSRA & m340_Rx_RDY); + } + else if (minor==UART_CHANNEL_B) { + return (DUSRB & m340_Rx_RDY); + } + return 0; +} + +/****************************************************** + Name: dbugInitialise + Input parameters: - + Output parameters: - + Description: Init the UART + *****************************************************/ +static void +dbugInitialise (void) +{ + t_baud_speed_table uart_config; /* configuration of UARTS */ + + /* + * Reset Receiver + */ + DUCRA = m340_Reset_Receiver; + DUCRB = m340_Reset_Receiver; + + /* + * Reset Transmitter + */ + DUCRA = m340_Reset_Transmitter; + DUCRB = m340_Reset_Transmitter; + + /* + * Enable serial module for normal operation, ignore FREEZE, select the crystal clock, + * supervisor/user serial registers unrestricted + * interrupt arbitration at priority CONSOLE_INTERRUPT_ARBITRATION + * WARNING : 8 bits access only on this UART! + */ + DUMCRH = 0x00; + DUMCRL = CONSOLE_INTERRUPT_ARBITRATION; + + /* + * Interrupt level register + */ + DUILR = CONSOLE_IRQ_LEVEL; + + /* sets the IVR */ + DUIVR = CONSOLE_VECTOR; + + /* search for a correct m340 uart configuration */ + uart_config = Find_Right_m340_UART_Config(m340_uart_config[UART_CHANNEL_A].rx_baudrate, + m340_uart_config[UART_CHANNEL_A].tx_baudrate, + CHANNEL_ENABLED_A, + m340_uart_config[UART_CHANNEL_B].rx_baudrate, + m340_uart_config[UART_CHANNEL_B].tx_baudrate, + CHANNEL_ENABLED_B); + + /***************************************************************************** + ** CHANNEL A ** + *****************************************************************************/ + if (CHANNEL_ENABLED_A) { + + if (USE_INTERRUPTS_A) { + rtems_isr_entry old_handler; + + (void) rtems_interrupt_catch (InterruptHandler, + CONSOLE_VECTOR, + &old_handler); + + /* uncomment this if you want to pass control to your own ISR handler + it may be usefull to do so to check for performances with an oscilloscope */ + /* + { + proc_ptr ignored; + _CPU_ISR_install_raw_handler( CONSOLE_VECTOR, _Debug_ISR_Handler_Console, &ignored ); + } + */ + + /* + * Interrupt Enable Register + * Enable Interrupts on Channel A Receiver Ready + */ + set_DUIER(m340_RxRDYA); + } + else { + /* + * Disable Interrupts on channel A + */ + unset_DUIER(m340_RxRDYA&m340_TxRDYA); + } + + /* + * Change set of baud speeds + * disable input control + */ + /* no good uart configuration ? */ + if (uart_config.nb<1) rtems_fatal_error_occurred (-1); + + if (uart_config.baud_speed_table[UART_CHANNEL_A].set==1) + DUACR = m340_BRG_Set1; + else + DUACR = m340_BRG_Set2; + + /* + * make OPCR an auxiliary function serving the communication channels + */ + DUOPCR = m340_OPCR_Aux; + + /* poll the XTAL_RDY bit until it is cleared to ensure that an unstable crystal + input is not applied to the baud rate generator */ + while (DUISR & m340_XTAL_RDY) continue; + + /* + * Serial Channel Baud Speed + */ + DUCSRA = (uart_config.baud_speed_table[UART_CHANNEL_A].rcs << 4) + | (uart_config.baud_speed_table[UART_CHANNEL_A].tcs); + + /* + * Serial Channel Configuration + */ + DUMR1A = m340_uart_config[UART_CHANNEL_A].parity_mode + | m340_uart_config[UART_CHANNEL_A].bits_per_char + | m340_RxRTS; + + if (m340_uart_config[UART_CHANNEL_A].rx_mode==UART_FIFO_FULL) DUMR1A |= m340_R_F | m340_ERR; + + /* + * Serial Channel Configuration 2 + */ + DUMR2A |= m340_normal; + + /* + * Enable Channel A: transmitter and receiver + */ + DUCRA = m340_Transmitter_Enable | m340_Receiver_Enable; + } /* channel A enabled */ + + /***************************************************************************** + ** CHANNEL B ** + *****************************************************************************/ + if (CHANNEL_ENABLED_B) { + + /* we mustn't set the console vector twice! */ + if ((USE_INTERRUPTS_B && !(CHANNEL_ENABLED_A)) + || (USE_INTERRUPTS_B && CHANNEL_ENABLED_A && !USE_INTERRUPTS_A)) { + rtems_isr_entry old_handler; + + (void) rtems_interrupt_catch (InterruptHandler, + CONSOLE_VECTOR, + &old_handler); + + /* uncomment this if you want to pass control to your own ISR handler + it may be usefull to do so to check for performances with an oscilloscope */ + /* + { + proc_ptr ignored; + _CPU_ISR_install_raw_handler( CONSOLE_VECTOR, _Debug_ISR_Handler_Console, &ignored ); + } + */ + + /* + * Interrupt Enable Register + * Enable Interrupts on Channel A Receiver Ready + */ + set_DUIER(m340_RxRDYB); + } + else { + /* + * Disable Interrupts on channel B + */ + unset_DUIER(m340_RxRDYB&m340_TxRDYB); + } + + /* + * Change set of baud speeds + * disable input control + */ + + /* no good uart configuration ? */ + if (uart_config.nb<2) rtems_fatal_error_occurred (-1); + + /* don't set DUACR twice! */ + if (!CHANNEL_ENABLED_A) { + if (uart_config.baud_speed_table[UART_CHANNEL_B].set==1) + DUACR = m340_BRG_Set1; + else + DUACR = m340_BRG_Set2; + } + + /* + * make OPCR an auxiliary function serving the communication channels + */ + if (!CHANNEL_ENABLED_A) DUOPCR = m340_OPCR_Aux; + + /* poll the XTAL_RDY bit until it is cleared to ensure that an unstable crystal + input is not applied to the baud rate generator */ + while (DUISR & m340_XTAL_RDY) continue; + + /* + * Serial Channel Baud Speed + */ + DUCSRB = (uart_config.baud_speed_table[UART_CHANNEL_B].rcs << 4) + | (uart_config.baud_speed_table[UART_CHANNEL_B].tcs); + + /* + * Serial Channel Configuration + */ + DUMR1B = m340_uart_config[UART_CHANNEL_B].parity_mode + | m340_uart_config[UART_CHANNEL_B].bits_per_char + | m340_RxRTS; + + if (m340_uart_config[UART_CHANNEL_B].rx_mode==UART_FIFO_FULL) DUMR1B |= m340_R_F | m340_ERR; + + /* + * Serial Channel Configuration 2 + */ + DUMR2B |= m340_normal; + + /* + * Enable Channel A: transmitter and receiver + */ + DUCRB = m340_Transmitter_Enable | m340_Receiver_Enable; + } /* channel B enabled */ +} + +/****************************************************** + Name: SetAttributes + Input parameters: termios structure, channel + Output parameters: - + Description: return whether there's a character + in the receive buffer + TO DO: add the channel # to check for!! + *****************************************************/ +static int +SetAttributes (int minor, const struct termios *t) +{ + rtems_interrupt_level level; + float ispeed, ospeed; + + /* convert it */ + ispeed = rtems_termios_baud_to_number(t->c_ispeed); + ospeed = rtems_termios_baud_to_number(t->c_ospeed); + + if (ispeed || ospeed) { + /* update config table */ + m340_uart_config[UART_CHANNEL_A].rx_baudrate = ((minor==UART_CHANNEL_A)&&(ispeed!=0)) ? ispeed : m340_uart_config[UART_CHANNEL_A].rx_baudrate; + m340_uart_config[UART_CHANNEL_A].tx_baudrate = ((minor==UART_CHANNEL_A)&&(ospeed!=0)) ? ospeed : m340_uart_config[UART_CHANNEL_A].tx_baudrate; + m340_uart_config[UART_CHANNEL_B].rx_baudrate = ((minor==UART_CHANNEL_B)&&(ispeed!=0)) ? ispeed : m340_uart_config[UART_CHANNEL_B].rx_baudrate; + m340_uart_config[UART_CHANNEL_B].tx_baudrate = ((minor==UART_CHANNEL_B)&&(ospeed!=0)) ? ospeed : m340_uart_config[UART_CHANNEL_B].tx_baudrate; + } + + /* change parity */ + if (t->c_cflag & PARENB) { + if (t->c_cflag & PARODD) m340_uart_config[minor].parity_mode = m340_Odd_Parity; + else m340_uart_config[minor].parity_mode = m340_Even_Parity; + } + + /* change bits per character */ + if (t->c_cflag & CSIZE) { + switch (t->c_cflag & CSIZE) { + default: break; + case CS5: m340_uart_config[minor].bits_per_char = m340_5bpc; break; + case CS6: m340_uart_config[minor].bits_per_char = m340_6bpc; break; + case CS7: m340_uart_config[minor].bits_per_char = m340_7bpc; break; + case CS8: m340_uart_config[minor].bits_per_char = m340_8bpc; break; + } + } + + /* if serial module configuration has been changed */ + if (t->c_cflag & (CSIZE | PARENB)) { + rtems_interrupt_disable(level); + /* reinit the UART */ + dbugInitialise(); + rtems_interrupt_enable (level); + } + + return 0; +} + +/****************************************************** + Name: console_initialize + Input parameters: MAJOR # of console_driver, + minor is always 0, + args are always NULL + Output parameters: - + Description: Reserve resources consumed by this driver + TODO: We should pass m340_uart_config table in arg + *****************************************************/ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + int i; + + /* + * Set up TERMIOS + */ + rtems_termios_initialize (); + + /* + * Do device-specific initialization + */ + Init_UART_Table(); + dbugInitialise (); + Fifo_Full_benchmark_timer_initialize(); + + /* + * Register the devices + */ + for (i=0; iiop->data1; + } + else { + sc |= rtems_termios_open (major, minor, arg, &pollCallbacks); + } + } + + else if (minor==UART_CHANNEL_B) { + if (USE_INTERRUPTS_B) { + rtems_libio_open_close_args_t *args = arg; + + sc |= rtems_termios_open (major, minor, arg, &intrCallbacks); + ttypB = args->iop->data1; + } + else { + sc |= rtems_termios_open (major, minor, arg, &pollCallbacks); + } + } + + else return RTEMS_INVALID_NUMBER; + + return sc; +} + +/****************************************************** + Name: console_close + Input parameters: channel #, termios args + Output parameters: - + Description: close the device + *****************************************************/ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_close (arg); +} + +/****************************************************** + Name: console_read + Input parameters: channel #, termios args + Output parameters: - + Description: read the device + *****************************************************/ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_read (arg); +} + +/****************************************************** + Name: console_write + Input parameters: channel #, termios args + Output parameters: - + Description: write to the device + *****************************************************/ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_write (arg); +} + +/****************************************************** + Name: console_control + Input parameters: channel #, termios args + Output parameters: - + Description: Handle ioctl request + *****************************************************/ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_ioctl_args_t *args = arg; + + if (args->command == TIOCSETA) + SetAttributes (minor, (struct termios *)args->buffer); + + return rtems_termios_ioctl (arg); +} diff --git a/bsps/m68k/gen68340/console/m340uart.c b/bsps/m68k/gen68340/console/m340uart.c new file mode 100644 index 0000000000..56ad29c256 --- /dev/null +++ b/bsps/m68k/gen68340/console/m340uart.c @@ -0,0 +1,311 @@ +/* + * M68340/349 UART management tools + */ + +/* + * Author: + * Geoffroy Montel + * France Telecom - CNET/DSM/TAM/CAT + * 4, rue du Clos Courtel + * 35512 CESSON-SEVIGNE + * FRANCE + * + * e-mail: g_montel@yahoo.com + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* this table shows compatible speed configurations for the MC68340: + the first row shows baud rates for baud speed set 1 + the second row shows baud rates for baud speed set 2 + look at Motorola's MC68340 Integrated Processor User's Manual + page 7-30 for more infos */ + +float m340_Baud_Rates_Table[16][2] = { + { 50, 75 }, + { 110, 110 }, + { 134.5, 134.5 }, + { 200, 150 }, + { 300, 300 }, + { 600, 600 }, + { 1200, 1200 }, + { 1050, 2000 }, + { 2400, 2400 }, + { 4800, 4800 }, + { 7200, 1800 }, + { 9600, 9600 }, + { 38400, 19200 }, + { 76800, 38400 }, + { SCLK/16, SCLK/16}, + { SCLK, SCLK }, +}; + +/* config on both 340 channels */ +uart_channel_config m340_uart_config[UART_NUMBER_OF_CHANNELS]; + +/* + * Init UART table + */ + +#define NOT_IMPLEMENTED_YET 0 + +/****************************************************** + Name: Init_UART_Table + Input parameters: - + Output parameters: - + Description: Init the m340_uart_config + THIS SHOULD NOT BE HERE! + Its aim was to let the user configure + UARTs for each application. + As we can't pass args to the console + driver initialisation routine at the + moment, this was not done. + ATTENTION: TERMIOS init presupposes that the channel + baud rates is 9600/9600. + -> risks when using IOCTL + *****************************************************/ +void Init_UART_Table(void) +{ + m340_uart_config[UART_CHANNEL_A].enable = TRUE; + strcpy(m340_uart_config[UART_CHANNEL_A].name, UART_CONSOLE_NAME); + m340_uart_config[UART_CHANNEL_A].parity_mode = m340_No_Parity; + m340_uart_config[UART_CHANNEL_A].bits_per_char = m340_8bpc; + m340_uart_config[UART_CHANNEL_A].rx_baudrate = 9600; + m340_uart_config[UART_CHANNEL_A].tx_baudrate = 9600; + m340_uart_config[UART_CHANNEL_A].rx_mode = UART_CRR; + m340_uart_config[UART_CHANNEL_A].mode = UART_POLLING; + + m340_uart_config[UART_CHANNEL_A].termios.enable = TRUE; + m340_uart_config[UART_CHANNEL_A].termios.rx_buffer_size = NOT_IMPLEMENTED_YET; + m340_uart_config[UART_CHANNEL_A].termios.tx_buffer_size = NOT_IMPLEMENTED_YET; + + m340_uart_config[UART_CHANNEL_B].enable = FALSE; + strcpy(m340_uart_config[UART_CHANNEL_B].name, UART_RAW_IO_NAME); + m340_uart_config[UART_CHANNEL_B].parity_mode = m340_No_Parity; + m340_uart_config[UART_CHANNEL_B].bits_per_char = m340_8bpc; + m340_uart_config[UART_CHANNEL_B].rx_baudrate = 38400; + m340_uart_config[UART_CHANNEL_B].tx_baudrate = 38400; + m340_uart_config[UART_CHANNEL_B].rx_mode = UART_CRR; + m340_uart_config[UART_CHANNEL_B].mode = UART_INTERRUPTS; + + m340_uart_config[UART_CHANNEL_B].termios.enable = TRUE; + m340_uart_config[UART_CHANNEL_B].termios.rx_buffer_size = NOT_IMPLEMENTED_YET; + m340_uart_config[UART_CHANNEL_B].termios.tx_buffer_size = NOT_IMPLEMENTED_YET; +} + +/****************************************************** + Name: Find_Right_m340_UART_Channel_Config + Input parameters: Send/Receive baud rates for a + given channel + Output parameters: UART compatible configs for this + channel + Description: returns which uart configurations fit + Receiver Baud Rate and Transmitter Baud + Rate for a given channel + For instance, according to the + m340_Baud_Rates_Table: + - Output Speed = 50, Input Speed = 75 + is not a correct config, because + 50 bauds implies set 1 and 75 bauds + implies set 2 + - Output Speed = 9600, Input Speed = 9600 + two correct configs for this: + RCS=11, TCS=11, Set=1 or 2 + *****************************************************/ +static t_baud_speed_table +Find_Right_m340_UART_Channel_Config( + float ReceiverBaudRate, + float TransmitterBaudRate +) +{ + t_baud_speed_table return_value; + int i,j; + + struct { + int cs; + int set; + } Receiver[2], Transmitter[2]; + + int Receiver_nb_of_config = 0; + int Transmitter_nb_of_config = 0; + + /* Receiver and Transmitter baud rates must be compatible, ie in the + * same set. + */ + + /* search for configurations for ReceiverBaudRate + * there can't be more than two (only two sets). + */ + for (i=0;i<16;i++) { + for (j=0;j<2;j++) { + if (m340_Baud_Rates_Table[i][j]==ReceiverBaudRate) { + Receiver[Receiver_nb_of_config].cs=i; + Receiver[Receiver_nb_of_config].set=j; + Receiver_nb_of_config++; + } + } + } + + /* search for configurations for TransmitterBaudRate + * there can't be more than two (only two sets) + */ + for (i=0;i<16;i++) { + for (j=0;j<2;j++) { + if (m340_Baud_Rates_Table[i][j]==TransmitterBaudRate) { + Transmitter[Transmitter_nb_of_config].cs=i; + Transmitter[Transmitter_nb_of_config].set=j; + Transmitter_nb_of_config++; + } + } + } + + /* now check if there's a compatible config */ + return_value.nb=0; + + for (i=0; i +#include +#include +#include +#include +#include + +/* + * Declare clock speed -- may be overwritten by downloader or debugger + */ +int m360_clock_rate = 25000000; + +/* + * Interrupt-driven input buffer + * Declare console baud rate -- may also be overwritten + */ +int console_baud_rate = 9600; + +/* + */ +#define RXBUFSIZE 16 + +/* + * Interrupt-driven callback + */ +static int m360_smc1_interrupt = 1; +static void *smc1ttyp; + +/* + * I/O buffers and pointers to buffer descriptors + */ +static volatile char rxBuf[RXBUFSIZE]; +static volatile m360BufferDescriptor_t *smcRxBd, *smcTxBd; + +/* + * Device-specific routines + */ + +/* + * Compute baud-rate-generator configuration register value + */ +static int +smc1BRGC (int baud) +{ + int divisor; + int div16 = 0; + + divisor = ((m360_clock_rate / 16) + (baud / 2)) / baud; + if (divisor > 4096) { + div16 = 1; + divisor = (divisor + 8) / 16; + } + return M360_BRG_EN | M360_BRG_EXTC_BRGCLK | ((divisor - 1) << 1) | div16; +} + +/* + * Hardware-dependent portion of tcsetattr(). + */ +static int +smc1SetAttributes (int minor, const struct termios *t) +{ + int baud; + + baud = rtems_termios_baud_to_number(t->c_ospeed); + if (baud > 0) + m360.brgc1 = smc1BRGC (baud); + return 0; +} + +/* + * Interrupt handler + */ +static rtems_isr +smc1InterruptHandler (rtems_vector_number v) +{ + /* + * Buffer received? + */ + if (m360.smc1.smce & 0x1) { + m360.smc1.smce = 0x1; + while ((smcRxBd->status & M360_BD_EMPTY) == 0) { + rtems_termios_enqueue_raw_characters (smc1ttyp, + (char *)smcRxBd->buffer, + smcRxBd->length); + smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT; + } + } + + /* + * Buffer transmitted? + */ + if (m360.smc1.smce & 0x2) { + m360.smc1.smce = 0x2; + if ((smcTxBd->status & M360_BD_READY) == 0) + rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length); + } + m360.cisr = 1UL << 4; /* Clear SMC1 interrupt-in-service bit */ +} + +static int +smc1Initialize (int major, int minor, void *arg) +{ + /* + * Allocate buffer descriptors + */ + smcRxBd = M360AllocateBufferDescriptors (1); + smcTxBd = M360AllocateBufferDescriptors (1); + + /* + * Configure port B pins to enable SMTXD1 and SMRXD1 pins + */ + m360.pbpar |= 0xC0; + m360.pbdir &= ~0xC0; + m360.pbodr &= ~0xC0; + + /* + * Set up BRG1 (9,600 baud) + */ + m360.brgc1 = M360_BRG_RST; + m360.brgc1 = smc1BRGC (console_baud_rate); + + /* + * Put SMC1 in NMSI mode, connect SMC1 to BRG1 + */ + m360.simode |= M360_SI_SMC1_BRG1; + + /* + * Set up SMC1 parameter RAM common to all protocols + */ + m360.smc1p.rbase = (char *)smcRxBd - (char *)&m360; + m360.smc1p.tbase = (char *)smcTxBd - (char *)&m360; + m360.smc1p.rfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE; + m360.smc1p.tfcr = M360_TFCR_MOT | M360_TFCR_DMA_SPACE; + if (m360_smc1_interrupt) + m360.smc1p.mrblr = RXBUFSIZE; + else + m360.smc1p.mrblr = 1; + + /* + * Set up SMC1 parameter RAM UART-specific parameters + */ + m360.smc1p.un.uart.max_idl = 10; + m360.smc1p.un.uart.brklen = 0; + m360.smc1p.un.uart.brkec = 0; + m360.smc1p.un.uart.brkcr = 0; + + /* + * Set up the Receive Buffer Descriptor + */ + smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT; + smcRxBd->length = 0; + smcRxBd->buffer = rxBuf; + + /* + * Setup the Transmit Buffer Descriptor + */ + smcTxBd->status = M360_BD_WRAP; + + /* + * Set up SMC1 general and protocol-specific mode registers + */ + m360.smc1.smce = ~0; /* Clear any pending events */ + m360.smc1.smcm = 0; /* Mask all interrupt/event sources */ + m360.smc1.smcmr = M360_SMCMR_CLEN(9) | M360_SMCMR_SM_UART; + + /* + * Send "Init parameters" command + */ + M360ExecuteRISC (M360_CR_OP_INIT_RX_TX | M360_CR_CHAN_SMC1); + + /* + * Enable receiver and transmitter + */ + m360.smc1.smcmr |= M360_SMCMR_TEN | M360_SMCMR_REN; + + if (m360_smc1_interrupt) { + rtems_isr_entry old_handler; + + (void) rtems_interrupt_catch (smc1InterruptHandler, + (m360.cicr & 0xE0) | 0x04, + &old_handler); + m360.smc1.smcm = 3; /* Enable SMC1 TX and RX interrupts */ + m360.cimr |= 1UL << 4; /* Enable SMC1 interrupts */ + } + + return 0; +} + +static int +smc1PollRead (int minor) +{ + unsigned char c; + + if (smcRxBd->status & M360_BD_EMPTY) + return -1; + c = rxBuf[0]; + smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP; + return c; +} + +/* + * Device-dependent write routine + * Interrupt-driven devices: + * Begin transmission of as many characters as possible (minimum is 1). + * Polling devices: + * Transmit all characters. + */ +static ssize_t +smc1InterruptWrite (int minor, const char *buf, size_t len) +{ + if (len > 0) { + smcTxBd->buffer = (char *)buf; + smcTxBd->length = len; + smcTxBd->status = M360_BD_READY | M360_BD_WRAP | M360_BD_INTERRUPT; + } + + return 0; +} + +static ssize_t +smc1PollWrite (int minor, const char *buf, size_t len) +{ + size_t retval = len; + while (len--) { + static char txBuf; + while (smcTxBd->status & M360_BD_READY) + continue; + txBuf = *buf++; + smcTxBd->buffer = &txBuf; + smcTxBd->length = 1; + smcTxBd->status = M360_BD_READY | M360_BD_WRAP; + } + return retval; +} + +/* + *************** + * BOILERPLATE * + *************** + */ + +/* + * Reserve resources consumed by this driver + * + * NOTE: This is in another file to reduce dependencies on the minimum size. + */ + +/* + * Initialize and register the device + */ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + + /* + * Set up TERMIOS + */ + rtems_termios_initialize (); + + /* + * Register the device + */ + status = rtems_io_register_name ("/dev/console", major, 0); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + return RTEMS_SUCCESSFUL; +} + +/* + * Open the device + */ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_status_code sc; + static const rtems_termios_callbacks intrCallbacks = { + smc1Initialize, /* firstOpen */ + NULL, /* lastClose */ + NULL, /* pollRead */ + smc1InterruptWrite, /* write */ + smc1SetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + 1 /* outputUsesInterrupts */ + }; + static const rtems_termios_callbacks pollCallbacks = { + smc1Initialize, /* firstOpen */ + NULL, /* lastClose */ + smc1PollRead, /* pollRead */ + smc1PollWrite, /* write */ + smc1SetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + 0 /* outputUsesInterrupts */ + }; + + /* + * Do generic termios initialization + */ + if (m360_smc1_interrupt) { + rtems_libio_open_close_args_t *args = arg; + + sc = rtems_termios_open (major, minor, arg, &intrCallbacks); + smc1ttyp = args->iop->data1; + } + else { + sc = rtems_termios_open (major, minor, arg, &pollCallbacks); + } + return sc; +} + +/* + * Close the device + */ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_close (arg); +} + +/* + * Read from the device + */ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_read (arg); +} + +/* + * Write to the device + */ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_write (arg); +} + +/* + * Handle ioctl request. + */ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_ioctl (arg); +} diff --git a/bsps/m68k/genmcf548x/console/console.c b/bsps/m68k/genmcf548x/console/console.c new file mode 100644 index 0000000000..32e5601a17 --- /dev/null +++ b/bsps/m68k/genmcf548x/console/console.c @@ -0,0 +1,843 @@ +/*===============================================================*\ +| Project: RTEMS generic mcf548x BSP | ++-----------------------------------------------------------------+ +| File: console.c | ++-----------------------------------------------------------------+ +| The file contains the console driver code of generic MCF548x | +| BSP. | ++-----------------------------------------------------------------+ +| Copyright (c) 2007 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| | +| Parts of the code has been derived from the "dBUG source code" | +| package Freescale is providing for M548X EVBs. The usage of | +| the modified or unmodified code and it's integration into the | +| generic mcf548x BSP has been done according to the Freescale | +| license terms. | +| | +| The Freescale license terms can be reviewed in the file | +| | +| Freescale_license.txt | +| | ++-----------------------------------------------------------------+ +| | +| The generic mcf548x BSP has been developed on the basic | +| structures and modules of the av5282 BSP. | +| | ++-----------------------------------------------------------------+ +| | +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.org/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| | +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 12.11.07 1.0 ras | +| | +\*===============================================================*/ + + /* + * Multi UART console serial I/O. + * + * TO DO: Add DMA input/output + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define UART_INTC0_IRQ_VECTOR(x) (64+35-(x)) + +#define MCF548X_PSC_SR_ERROR ( MCF548X_PSC_SR_RB_NEOF | \ + MCF548X_PSC_SR_FE_PHYERR | \ + MCF548X_PSC_SR_PE_CRCERR | \ + MCF548X_PSC_SR_OE ) + +static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); +static int IntUartPollRead (int minor); +static int IntUartSetAttributes(int minor, const struct termios *t); + +static void +psc_output_char( char c ) +{ + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + while (!((MCF548X_PSC_SR(CONSOLE_PORT) & MCF548X_PSC_SR_TXRDY))) + continue; + *((uint8_t *) &MCF548X_PSC_TB(CONSOLE_PORT)) = c; + while (!((MCF548X_PSC_SR(CONSOLE_PORT) & MCF548X_PSC_SR_TXRDY))) + continue; + rtems_interrupt_enable(level); +} + +static void +psc_output_char_init(char c) +{ + IntUartSetAttributes(CONSOLE_PORT, NULL); + BSP_output_char = psc_output_char; + psc_output_char(c); +} + +BSP_output_char_function_type BSP_output_char = psc_output_char_init; + +BSP_polling_getchar_function_type BSP_poll_char = NULL; + +#define MAX_UART_INFO 4 +#define RX_BUFFER_SIZE 248 + +struct IntUartInfoStruct +{ + int iomode; + volatile int imr; + int baud; + int databits; + int parity; + int stopbits; + int hwflow; + int rx_in; + int rx_out; + char rx_buffer[RX_BUFFER_SIZE]; + void *ttyp; +}; + +struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; + +static int GetBaud( int baudHandle ) +{ + int baud = BSP_CONSOLE_BAUD; + switch(baudHandle) + { + case B0: + baud = (int)0; + break; + case B1200: + baud = (int)1200; + break; + case B2400: + baud = (int)2400; + break; + case B4800: + baud = (int)4800; + break; + case B9600: + baud = (int)9600; + break; + case B19200: + baud = (int)19200; + break; + case B38400: + baud = (int)38400; + break; + case B57600: + baud = (int)57600; + break; + case B115200: + baud = (int)115200; + break; + } + return baud; +} + +/*************************************************************************** + Function : IntUartSet + + Description : This updates the hardware UART settings. + ***************************************************************************/ +static void +IntUartSet(int minor, int baud, int databits, int parity, int stopbits, int hwflow) +{ + uint8_t psc_mode_1 = 0, psc_mode_2 = 0; + uint16_t divider; + int level; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + rtems_interrupt_disable(level); + + /* disable interrupts, clear RTS line, and disable the UARTS */ + /* Mask all psc interrupts */ + MCF548X_PSC_IMR(minor) = 0x0000; + + /* Clear RTS to send */ + MCF548X_PSC_OPSET(minor) &= ~(MCF548X_PSC_OPSET_RTS); + + /* Disable receiver and transmitter */ + MCF548X_PSC_CR(minor) &= ~(MCF548X_PSC_CR_RX_ENABLED | MCF548X_PSC_CR_TX_ENABLED); + + /* provide gpio settings */ + switch (minor) + { + case 0: + MCF548X_GPIO_PAR_PSC0 = (0 | MCF548X_GPIO_PAR_PSC0_PAR_TXD0 | MCF548X_GPIO_PAR_PSC0_PAR_RXD0); + + if(hwflow) + { + MCF548X_GPIO_PAR_PSC0 |= (0 | MCF548X_GPIO_PAR_PSC0_PAR_CTS0_CTS | MCF548X_GPIO_PAR_PSC0_PAR_RTS0_RTS); + } + break; + case 1: + MCF548X_GPIO_PAR_PSC1 = (0 | MCF548X_GPIO_PAR_PSC1_PAR_TXD1 | MCF548X_GPIO_PAR_PSC1_PAR_RXD1); + + if(hwflow) + { + MCF548X_GPIO_PAR_PSC1 |= (0 | MCF548X_GPIO_PAR_PSC1_PAR_CTS1_CTS | MCF548X_GPIO_PAR_PSC1_PAR_RTS1_RTS); + } + break; + case 2: + MCF548X_GPIO_PAR_PSC2 = (0 | MCF548X_GPIO_PAR_PSC2_PAR_TXD2 | MCF548X_GPIO_PAR_PSC2_PAR_RXD2); + + if(hwflow) + { + MCF548X_GPIO_PAR_PSC2 |= (0 | MCF548X_GPIO_PAR_PSC2_PAR_CTS2_CTS | MCF548X_GPIO_PAR_PSC2_PAR_RTS2_RTS); + } + break; + case 3: + MCF548X_GPIO_PAR_PSC3 = (0 | MCF548X_GPIO_PAR_PSC3_PAR_TXD3 | MCF548X_GPIO_PAR_PSC3_PAR_RXD3); + + if(hwflow) + { + MCF548X_GPIO_PAR_PSC3 |= (0 | MCF548X_GPIO_PAR_PSC3_PAR_CTS3_CTS | MCF548X_GPIO_PAR_PSC3_PAR_RTS3_RTS); + } + break; + default: + break; + } + + /* save the current values */ + info->imr = 0; + info->baud = baud; + info->databits = databits; + info->parity = parity; + info->stopbits = stopbits; + info->hwflow = hwflow; + + /* Put PSC in UART mode */ + MCF548X_PSC_SICR(minor) = MCF548X_PSC_SICR_SIM_UART; + + /* set the baud rate values */ + MCF548X_PSC_CSR(minor) = (0 | MCF548X_PSC_CSR_RCSEL_SYS_CLK | MCF548X_PSC_CSR_TCSEL_SYS_CLK); + + /* Calculate baud settings */ + divider = (uint16_t)((get_CPU_clock_speed())/(baud * 32)); + MCF548X_PSC_CTUR(minor) = (uint8_t) ((divider >> 8) & 0xFF); + MCF548X_PSC_CTLR(minor) = (uint8_t) (divider & 0xFF); + + /* Reset transmitter, receiver, mode register, and error conditions */ + MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_RX; + MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_TX; + MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_ERROR; + MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_BKCHGINT; + MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_MR; + + /* check to see if doing hardware flow control */ + if ( hwflow ) + { + /* set hardware flow options */ + psc_mode_1 = MCF548X_PSC_MR_RXRTS; + psc_mode_2 = MCF548X_PSC_MR_TXCTS; + } + + /* set mode registers */ + psc_mode_1 |= (uint8_t)(parity | databits); + psc_mode_2 |= (uint8_t)(stopbits); + + /* set mode registers */ + MCF548X_PSC_MR(minor) = psc_mode_1; + MCF548X_PSC_MR(minor) = psc_mode_2; + + /* Setup FIFO Alarms */ + MCF548X_PSC_RFAR(minor) = MCF548X_PSC_RFAR_ALARM(248); + MCF548X_PSC_TFAR(minor) = MCF548X_PSC_TFAR_ALARM(248); + + /* check to see if interrupts need to be enabled */ + if ( info->iomode != TERMIOS_POLLED ) + { + /* enable rx interrupts */ + info->imr |= MCF548X_PSC_IMR_RXRDY_FU; + MCF548X_PSC_IMR(minor) = info->imr; + } + + /* check to see if doing hardware flow control */ + if ( hwflow ) + { + /* assert the RTS line */ + MCF548X_PSC_OPSET(minor) = MCF548X_PSC_OPSET_RTS; + } + + rtems_interrupt_enable(level); + + /* Enable receiver and transmitter */ + MCF548X_PSC_CR(minor) =(0 | MCF548X_PSC_CR_RX_ENABLED | MCF548X_PSC_CR_TX_ENABLED); + + +} + +/*************************************************************************** + Function : IntUartSetAttributes + + Description : This provides the hardware-dependent portion of tcsetattr(). + value and sets it. At the moment this just sets the baud rate. + + Note: The highest baudrate is 115200 as this stays within + an error of +/- 5% at 25MHz processor clock + ***************************************************************************/ +static int +IntUartSetAttributes(int minor, const struct termios *t) +{ +/* set default index values */ +#ifdef HAS_DBUG + int baud = DBUG_SETTINGS.console_baudrate; +#else + int baud = (int)BSP_CONSOLE_BAUD; +#endif + int databits = (int)MCF548X_PSC_MR_BC_8; + int parity = (int)MCF548X_PSC_MR_PM_NONE; + int stopbits = (int)MCF548X_PSC_MR_SB_STOP_BITS_1; + int hwflow = (int)1; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* check to see if input is valid */ + if ( t != (const struct termios *)0 ) + { + /* determine baud rate index */ + baud = GetBaud( t->c_ospeed ); + + /* determine data bits */ + switch ( t->c_cflag & CSIZE ) + { + case CS5: + databits = (int)MCF548X_PSC_MR_BC_5; + break; + case CS6: + databits = (int)MCF548X_PSC_MR_BC_6; + break; + case CS7: + databits = (int)MCF548X_PSC_MR_BC_7; + break; + case CS8: + databits = (int)MCF548X_PSC_MR_BC_8; + break; + } + + /* determine if parity is enabled */ + if ( t->c_cflag & PARENB ) + { + if ( t->c_cflag & PARODD ) + { + /* odd parity */ + parity = (int)MCF548X_PSC_MR_PM_ODD; + } + else + { + /* even parity */ + parity = (int)MCF548X_PSC_MR_PM_EVEN; + } + } + + /* determine stop bits */ + if ( t->c_cflag & CSTOPB ) + { + /* two stop bits */ + stopbits = (int)MCF548X_PSC_MR_SB_STOP_BITS_2; + } + + /* check to see if hardware flow control */ + if ( t->c_cflag & CRTSCTS ) + { + hwflow = 1; + } + } + + /* check to see if values have changed */ + if ( ( baud != info->baud ) || + ( databits != info->databits ) || + ( parity != info->parity ) || + ( stopbits != info->stopbits ) || + ( hwflow != info->hwflow ) ) + { + + /* call function to set values */ + IntUartSet(minor, baud, databits, parity, stopbits, hwflow); + } + +return RTEMS_SUCCESSFUL; + +} + +/*************************************************************************** + Function : IntUartInterruptHandler + + Description : This is the interrupt handler for the internal uart. It + determines which channel caused the interrupt before queueing any received + chars and dequeueing chars waiting for transmission. + ***************************************************************************/ +static rtems_isr +IntUartInterruptHandler(rtems_vector_number v) +{ + unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); + struct IntUartInfoStruct *info = &IntUartInfo[chan]; + + /* check to see if received data */ + if ( MCF548X_PSC_ISR(chan) & MCF548X_PSC_ISR_RXRDY_FU ) + { + /* read data and put into the receive buffer */ + while ( MCF548X_PSC_SR(chan) & MCF548X_PSC_SR_RXRDY ) + { + + /* put data in rx buffer */ + info->rx_buffer[info->rx_in] = *((volatile uint8_t *)&MCF548X_PSC_RB(chan)); + + /* check for errors */ + if ( MCF548X_PSC_SR(chan) & MCF548X_PSC_SR_ERROR ) + { + /* clear the error */ + MCF548X_PSC_CR(chan) = MCF548X_PSC_CR_RESET_ERROR; + } + + /* update buffer values */ + info->rx_in++; + + if ( info->rx_in >= RX_BUFFER_SIZE ) + { + info->rx_in = 0; + } + } + /* Make sure the port has been opened */ + if ( info->ttyp ) + { + + /* check to see if task driven */ + if ( info->iomode == TERMIOS_TASK_DRIVEN ) + { + /* notify rx task that rx buffer has data */ + rtems_termios_rxirq_occured(info->ttyp); + } + else + { + /* Push up the received data */ + rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, info->rx_in); + info->rx_in = 0; + } + } + } + + /* check to see if data needs to be transmitted */ + if ( ( info->imr & MCF548X_PSC_IMR_TXRDY ) && + ( MCF548X_PSC_ISR(chan) & MCF548X_PSC_ISR_TXRDY ) ) + { + + /* disable tx interrupts */ + info->imr &= ~MCF548X_PSC_IMR_TXRDY; + MCF548X_PSC_IMR(chan) = info->imr; + + /* tell upper level that character has been sent */ + if ( info->ttyp ) + rtems_termios_dequeue_characters(info->ttyp, 1); + } + +} + +/*************************************************************************** + Function : IntUartInitialize + + Description : This initialises the internal uart hardware for all + internal uarts. If the internal uart is to be interrupt driven then the + interrupt vectors are hooked. + ***************************************************************************/ +static void +IntUartInitialize(void) +{ + unsigned int chan; + struct IntUartInfoStruct *info; + rtems_isr_entry old_handler; + + for ( chan = 0; chan < MAX_UART_INFO; chan++ ) + { + info = &IntUartInfo[chan]; + + info->ttyp = NULL; + info->rx_in = 0; + info->rx_out = 0; + info->baud = -1; + info->databits = -1; + info->parity = -1; + info->stopbits = -1; + info->hwflow = -1; + + MCF548X_PSC_ACR(chan) = 0; + MCF548X_PSC_IMR(chan) = 0; + if ( info->iomode != TERMIOS_POLLED ) + { + rtems_interrupt_catch (IntUartInterruptHandler, + UART_INTC0_IRQ_VECTOR(chan), + &old_handler); + } + + /* set uart default values */ + IntUartSetAttributes(chan, NULL); + + /* unmask interrupt */ + bsp_interrupt_vector_enable(MCF548X_IRQ_PSC(chan)); + } /* of chan loop */ + + BSP_output_char = psc_output_char; +} /* IntUartInitialise */ + +/*************************************************************************** + Function : IntUartInterruptWrite + + Description : This writes a single character to the appropriate uart + channel. This is either called during an interrupt or in the user's task + to initiate a transmit sequence. Calling this routine enables Tx + interrupts. + ***************************************************************************/ +static ssize_t +IntUartInterruptWrite (int minor, const char *buf, size_t len) +{ + if (len > 0) { + /* write out character */ + *(volatile uint8_t *)(&MCF548X_PSC_TB(minor)) = *buf; + + /* enable tx interrupt */ + IntUartInfo[minor].imr |= MCF548X_PSC_IMR_TXRDY; + MCF548X_PSC_IMR(minor) = IntUartInfo[minor].imr; + } + + return 0; +} + +/*************************************************************************** + Function : IntUartInterruptOpen + + Description : This enables interrupts when the tty is opened. + ***************************************************************************/ +static int +IntUartInterruptOpen(int major, int minor, void *arg) +{ + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* enable the uart */ + MCF548X_PSC_CR(minor) = (MCF548X_PSC_CR_TX_ENABLED | MCF548X_PSC_CR_RX_ENABLED); + + /* check to see if interrupts need to be enabled */ + if ( info->iomode != TERMIOS_POLLED ) + { + /* enable rx interrupts */ + info->imr |= MCF548X_PSC_IMR_RXRDY_FU; + MCF548X_PSC_IMR(minor) = info->imr; + } + + /* check to see if doing hardware flow control */ + if ( info->hwflow ) + { + /* assert the RTS line */ + MCF548X_PSC_OPSET(minor) = MCF548X_PSC_OPSET_RTS; + } + + return 0; +} + + +/*************************************************************************** + Function : IntUartInterruptClose + + Description : This disables interrupts when the tty is closed. + ***************************************************************************/ +static int +IntUartInterruptClose(int major, int minor, void *arg) +{ + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* disable the interrupts and the uart */ + MCF548X_PSC_IMR(minor) = 0; + MCF548X_PSC_CR(minor) = (MCF548X_PSC_CR_TX_ENABLED | MCF548X_PSC_CR_RX_ENABLED); + + /* reset values */ + info->ttyp = NULL; + info->imr = 0; + info->rx_in = 0; + info->rx_out = 0; + + return 0; +} + +/*************************************************************************** + Function : IntUartTaskRead + + Description : This reads all available characters from the internal uart + and places them into the termios buffer. The rx interrupts will be + re-enabled after all data has been read. + ***************************************************************************/ +static int +IntUartTaskRead(int minor) +{ + char buffer[RX_BUFFER_SIZE]; + int count; + int rx_in; + int index = 0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* determine number of values to copy out */ + rx_in = info->rx_in; + if ( info->rx_out <= rx_in ) + { + count = rx_in - info->rx_out; + } + else + { + count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; + } + + /* copy data into local buffer from rx buffer */ + while ( ( index < count ) && ( index < RX_BUFFER_SIZE ) ) + { + /* copy data byte */ + buffer[index] = info->rx_buffer[info->rx_out]; + index++; + + /* increment rx buffer values */ + info->rx_out++; + if ( info->rx_out >= RX_BUFFER_SIZE ) + { + info->rx_out = 0; + } + } + + /* check to see if buffer is not empty */ + if ( count > 0 ) + { + /* set characters into termios buffer */ + rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); + } + + return EOF; +} + + +/*************************************************************************** + Function : IntUartPollRead + + Description : This reads a character from the internal uart. It returns + to the caller without blocking if not character is waiting. + ***************************************************************************/ +static int +IntUartPollRead (int minor) +{ +if (!((MCF548X_PSC_SR(minor) & MCF548X_PSC_SR_RXRDY))) + return(-1); + + return *((uint8_t *)&MCF548X_PSC_RB(minor)); +} + + +/*************************************************************************** + Function : IntUartPollWrite + + Description : This writes out each character in the buffer to the + appropriate internal uart channel waiting till each one is sucessfully + transmitted. + ***************************************************************************/ +static ssize_t +IntUartPollWrite (int minor, const char *buf, size_t len) +{ + size_t retval = len; +/* loop over buffer */ + while ( len-- ) + { + /* block until we can transmit */ + while (!((MCF548X_PSC_SR(minor) & MCF548X_PSC_SR_TXRDY))) + continue; + /* transmit data byte */ + *((uint8_t *)&MCF548X_PSC_TB(minor)) = *buf++; + } + return retval; +} + +/*************************************************************************** + Function : console_initialize + + Description : This initialises termios, both sets of uart hardware before + registering /dev/tty devices for each channel and the system /dev/console. + ***************************************************************************/ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg ) +{ + rtems_status_code status; + + + /* Set up TERMIOS */ + rtems_termios_initialize (); + + /* set io modes for the different channels and initialize device */ + IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN; //TERMIOS_POLLED; + IntUartInitialize(); + + /* Register the console port */ + status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT); + if ( status != RTEMS_SUCCESSFUL ) + { + rtems_fatal_error_occurred (status); + } + + /* Register the other port */ + if ( CONSOLE_PORT != 0 ) + { + status = rtems_io_register_name ("/dev/tty00", major, 0); + if ( status != RTEMS_SUCCESSFUL ) + { + rtems_fatal_error_occurred (status); + } + } + if ( CONSOLE_PORT != 1 ) + { + status = rtems_io_register_name ("/dev/tty01", major, 1); + if ( status != RTEMS_SUCCESSFUL ) + { + rtems_fatal_error_occurred (status); + } + } + + return(RTEMS_SUCCESSFUL); +} + +/*************************************************************************** + Function : console_open + + Description : This actually opens the device depending on the minor + number set during initialisation. The device specific access routines are + passed to termios when the devices is opened depending on whether it is + polled or not. + ***************************************************************************/ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + rtems_status_code status = RTEMS_INVALID_NUMBER; + rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *)arg; + struct IntUartInfoStruct *info; + + static const rtems_termios_callbacks IntUartPollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + IntUartPollRead, /* pollRead */ + IntUartPollWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_POLLED /* mode */ + }; + static const rtems_termios_callbacks IntUartIntrCallbacks = { + IntUartInterruptOpen, /* firstOpen */ + IntUartInterruptClose, /* lastClose */ + NULL, /* pollRead */ + IntUartInterruptWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_IRQ_DRIVEN /* mode */ + }; + + static const rtems_termios_callbacks IntUartTaskCallbacks = { + IntUartInterruptOpen, /* firstOpen */ + IntUartInterruptClose, /* lastClose */ + IntUartTaskRead, /* pollRead */ + IntUartInterruptWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_TASK_DRIVEN /* mode */ + }; + + /* open the port depending on the minor device number */ + if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) ) + { + info = &IntUartInfo[minor]; + switch ( info->iomode ) + { + case TERMIOS_POLLED: + status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); + break; + case TERMIOS_IRQ_DRIVEN: + status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); + info->ttyp = args->iop->data1; + break; + case TERMIOS_TASK_DRIVEN: + status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); + info->ttyp = args->iop->data1; + break; + } + } + + return( status ); +} + +/*************************************************************************** + Function : console_close + + Description : This closes the device via termios + ***************************************************************************/ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return(rtems_termios_close (arg)); +} + +/*************************************************************************** + Function : console_read + + Description : Read from the device via termios + ***************************************************************************/ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return(rtems_termios_read (arg)); +} + +/*************************************************************************** + Function : console_write + + Description : Write to the device via termios + ***************************************************************************/ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return(rtems_termios_write (arg)); +} + +/*************************************************************************** + Function : console_ioctl + + Description : Pass the IOCtl call to termios + ***************************************************************************/ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return( rtems_termios_ioctl (arg) ); +} diff --git a/bsps/m68k/mcf5206elite/console/console.c b/bsps/m68k/mcf5206elite/console/console.c new file mode 100644 index 0000000000..bbf343d0f3 --- /dev/null +++ b/bsps/m68k/mcf5206elite/console/console.c @@ -0,0 +1,431 @@ +/* + * Console driver for Motorola MCF5206E UART modules + */ + +/* + * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia + * Author: Victor V. Vengerov + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include "mcf5206/mcf5206e.h" +#include "mcf5206/mcfuart.h" + +/* Descriptor structures for two on-chip UART channels */ +static mcfuart uart[2]; + +/* Console operations mode: + * 0 - raw (non-termios) polled input/output + * 1 - termios-based polled input/output + * 2 - termios-based interrupt-driven input/output + */ +int console_mode = 2; +#define CONSOLE_MODE_RAW (0) +#define CONSOLE_MODE_POLL (1) +#define CONSOLE_MODE_INT (2) + +/* Wrapper functions for MCF UART generic driver */ + +/* console_poll_read -- + * wrapper for poll read function + * + * PARAMETERS: + * minor - minor device number + * + * RETURNS: + * character code readed from UART, or -1 if there is no characters + * available + */ +static int +console_poll_read(int minor) +{ + return mcfuart_poll_read(&uart[minor]); +} + +/* console_interrupt_write -- + * wrapper for interrupt write function + * + * PARAMETERS: + * minor - minor device number + * buf - output buffer + * len - output buffer length + * + * RETURNS: + * result code + */ +static ssize_t +console_interrupt_write(int minor, const char *buf, size_t len) +{ + return mcfuart_interrupt_write(&uart[minor], buf, len); +} + +/* console_poll_write -- + * wrapper for polling mode write function + * + * PARAMETERS: + * minor - minor device number + * buf - output buffer + * len - output buffer length + * + * RETURNS: + * result code + */ +static ssize_t +console_poll_write(int minor, const char *buf, size_t len) +{ + return mcfuart_poll_write(&uart[minor], buf, len); +} + +/* console_set_attributes -- + * wrapper for hardware-dependent termios attributes setting + * + * PARAMETERS: + * minor - minor device number + * t - pointer to the termios structure + * + * RETURNS: + * result code + */ +static int +console_set_attributes(int minor, const struct termios *t) +{ + return mcfuart_set_attributes(&uart[minor], t); +} + +/* console_stop_remote_tx -- + * wrapper for stopping data flow from remote party. + * + * PARAMETERS: + * minor - minor device number + * + * RETURNS: + * result code + */ +static int +console_stop_remote_tx(int minor) +{ + if (minor < sizeof(uart)/sizeof(uart[0])) + return mcfuart_stop_remote_tx(&uart[minor]); + else + return RTEMS_INVALID_NUMBER; +} + +/* console_start_remote_tx -- + * wrapper for resuming data flow from remote party. + * + * PARAMETERS: + * minor - minor device number + * + */ +static int +console_start_remote_tx(int minor) +{ + if (minor < sizeof(uart)/sizeof(uart[0])) + return mcfuart_start_remote_tx(&uart[minor]); + else + return RTEMS_INVALID_NUMBER; +} + +/* console_first_open -- + * wrapper for UART controller initialization functions + * + * PARAMETERS: + * major - major device number + * minor - minor device number + * arg - libio device open argument + * + * RETURNS: + * error code + */ +static int +console_first_open(int major, int minor, void *arg) +{ + rtems_libio_open_close_args_t *args = arg; + rtems_status_code sc; + uint8_t intvec; + + switch (minor) { + case 0: intvec = BSP_INTVEC_UART1; break; + case 1: intvec = BSP_INTVEC_UART2; break; + default: + return RTEMS_INVALID_NUMBER; + } + + if (console_mode != CONSOLE_MODE_INT) { + intvec = 0; + } + + sc = mcfuart_init( + &uart[minor], /* uart */ + args->iop->data1, /* tty */ + intvec, /* interrupt vector number */ + minor+1); + + if (sc == RTEMS_SUCCESSFUL) + sc = mcfuart_reset(&uart[minor]); + + return sc; +} + +/* console_last_close -- + * wrapper for UART controller close function + * + * PARAMETERS: + * major - major device number + * minor - minor device number + * arg - libio device close argument + * + * RETURNS: + * error code + */ +static int +console_last_close(int major, int minor, void *arg) +{ + return mcfuart_disable(&uart[minor]); +} + +/* console_initialize -- + * This routine initializes the console IO drivers and register devices + * in RTEMS I/O system. + * + * PARAMETERS: + * major - major console device number + * minor - minor console device number (not used) + * arg - device initialize argument + * + * RETURNS: + * RTEMS error code (RTEMS_SUCCESSFUL if device initialized successfuly) + */ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + rtems_status_code status; + + /* + * Set up TERMIOS + */ + if (console_mode != CONSOLE_MODE_RAW) + rtems_termios_initialize (); + + /* + * Register the devices + */ + status = rtems_io_register_name ("/dev/console", major, 0); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + + status = rtems_io_register_name ("/dev/aux", major, 1); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + + if (console_mode == CONSOLE_MODE_RAW) { + rtems_status_code sc; + sc = mcfuart_init(&uart[0], /* uart */ + NULL, /* tty */ + 0, /* interrupt vector number */ + 1); /* UART channel number */ + + if (sc == RTEMS_SUCCESSFUL) + sc = mcfuart_reset(&uart[0]); + + sc = mcfuart_init(&uart[1], /* uart */ + NULL, /* tty */ + 0, /* interrupt vector number */ + 2); /* UART channel number */ + + if (sc == RTEMS_SUCCESSFUL) + sc = mcfuart_reset(&uart[1]); + return sc; + } + + return RTEMS_SUCCESSFUL; +} + +/* console_open -- + * Open console device driver. Pass appropriate termios callback + * functions to termios library. + * + * PARAMETERS: + * major - major device number for console devices + * minor - minor device number for console + * arg - device opening argument + * + * RETURNS: + * RTEMS error code + */ +rtems_device_driver +console_open(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + static const rtems_termios_callbacks intr_callbacks = { + console_first_open, /* firstOpen */ + console_last_close, /* lastClose */ + NULL, /* pollRead */ + console_interrupt_write, /* write */ + console_set_attributes, /* setAttributes */ + console_stop_remote_tx, /* stopRemoteTx */ + console_start_remote_tx, /* startRemoteTx */ + 1 /* outputUsesInterrupts */ + }; + static const rtems_termios_callbacks poll_callbacks = { + console_first_open, /* firstOpen */ + console_last_close, /* lastClose */ + console_poll_read, /* pollRead */ + console_poll_write, /* write */ + console_set_attributes, /* setAttributes */ + console_stop_remote_tx, /* stopRemoteTx */ + console_start_remote_tx, /* startRemoteTx */ + 0 /* outputUsesInterrupts */ + }; + + switch (console_mode) { + case CONSOLE_MODE_RAW: + return RTEMS_SUCCESSFUL; + + case CONSOLE_MODE_INT: + return rtems_termios_open(major, minor, arg, &intr_callbacks); + + case CONSOLE_MODE_POLL: + return rtems_termios_open(major, minor, arg, &poll_callbacks); + + default: + rtems_fatal_error_occurred(0xC07A1310); + } + return RTEMS_INTERNAL_ERROR; +} + +/* console_close -- + * Close console device. + * + * PARAMETERS: + * major - major device number for console devices + * minor - minor device number for console + * arg - device close argument + * + * RETURNS: + * RTEMS error code + */ +rtems_device_driver +console_close(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + if (console_mode != CONSOLE_MODE_RAW) + return rtems_termios_close (arg); + else + return RTEMS_SUCCESSFUL; +} + +/* console_read -- + * Read from the console device + * + * PARAMETERS: + * major - major device number for console devices + * minor - minor device number for console + * arg - device read argument + * + * RETURNS: + * RTEMS error code + */ +rtems_device_driver +console_read(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + if (console_mode != CONSOLE_MODE_RAW) { + return rtems_termios_read (arg); + } else { + rtems_libio_rw_args_t *argp = arg; + char *buf = argp->buffer; + int count = argp->count; + int n = 0; + int c; + + while (n < count) { + do { + c = mcfuart_poll_read(&uart[minor]); + } while (c == -1); + if (c == '\r') + c = '\n'; + *(buf++) = c; + n++; + if (c == '\n') + break; + } + argp->bytes_moved = n; + return RTEMS_SUCCESSFUL; + } +} + +/* console_write -- + * Write to the console device + * + * PARAMETERS: + * major - major device number for console devices + * minor - minor device number for console + * arg - device write argument + * + * RETURNS: + * RTEMS error code + */ +rtems_device_driver +console_write(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + if (console_mode != CONSOLE_MODE_RAW) { + return rtems_termios_write (arg); + } else { + rtems_libio_rw_args_t *argp = arg; + char cr = '\r'; + char *buf = argp->buffer; + int count = argp->count; + int i; + + for (i = 0; i < count; i++) { + if (*buf == '\n') + mcfuart_poll_write(&uart[minor], &cr, 1); + mcfuart_poll_write(&uart[minor], buf, 1); + buf++; + } + argp->bytes_moved = count; + return RTEMS_SUCCESSFUL; + } +} + +/* console_control -- + * Handle console device I/O control (IOCTL) + * + * PARAMETERS: + * major - major device number for console devices + * minor - minor device number for console + * arg - device ioctl argument + * + * RETURNS: + * RTEMS error code + */ +rtems_device_driver +console_control(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + if (console_mode != CONSOLE_MODE_RAW) { + return rtems_termios_ioctl (arg); + } else { + return RTEMS_SUCCESSFUL; + } +} diff --git a/bsps/m68k/mcf52235/console/console.c b/bsps/m68k/mcf52235/console/console.c new file mode 100644 index 0000000000..c2b6e36bfa --- /dev/null +++ b/bsps/m68k/mcf52235/console/console.c @@ -0,0 +1,656 @@ + /* + * Multi UART console serial I/O. + * + * TO DO: Add DMA input/output + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x)) + +#define MCF_UART_USR_ERROR ( MCF_UART_USR_RB | \ + MCF_UART_USR_FE | \ + MCF_UART_USR_PE | \ + MCF_UART_USR_OE ) + +static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); +static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len); + +#define MAX_UART_INFO 3 +#define RX_BUFFER_SIZE 512 + +struct IntUartInfoStruct +{ + int iomode; + volatile int uimr; + int baud; + int databits; + int parity; + int stopbits; + int hwflow; + int rx_in; + int rx_out; + char rx_buffer[RX_BUFFER_SIZE]; + void *ttyp; +}; + +struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; + +/*************************************************************************** + Function : IntUartSet + + Description : This updates the hardware UART settings. + ***************************************************************************/ +static void +IntUartSet(int minor, int baud, int databits, int parity, int stopbits, + int hwflow) +{ + int divisor; + uint32_t clock_speed; + uint8_t umr1 = 0; + uint8_t umr2 = 0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + int level; + + rtems_interrupt_disable(level); + + /* disable interrupts, clear RTS line, and disable the UARTS */ + MCF_UART_UIMR(minor) = 0; + MCF_UART_UOP0(minor) = 1; + MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED); + + /* save the current values */ + info->uimr = 0; + info->baud = baud; + info->databits = databits; + info->parity = parity; + info->stopbits = stopbits; + info->hwflow = hwflow; + + clock_speed = bsp_get_CPU_clock_speed(); + /* determine the baud divisor value */ + divisor = ((clock_speed) / (32 * baud)); + if (divisor < 2) + divisor = 2; + + /* check to see if doing hardware flow control */ + if (hwflow) { + /* set hardware flow options */ + umr1 |= MCF_UART_UMR_RXRTS; + umr2 |= MCF_UART_UMR_TXCTS; + } + + /* determine the new umr values */ + umr1 |= (parity | databits); + umr2 |= (stopbits); + + /* reset the uart */ + MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_ERROR; + MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_RX; + MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_TX; + + /* reset the uart mode register and update values */ + MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_MR; + MCF_UART_UMR(minor) = umr1; + MCF_UART_UMR(minor) = umr2; + + /* set the baud rate values */ + MCF_UART_UCSR(minor) = + (MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK); + MCF_UART_UBG1(minor) = (divisor & 0xff00) >> 8; + MCF_UART_UBG2(minor) = (divisor & 0x00ff); + + /* enable the uart */ + MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); + + /* check to see if interrupts need to be enabled */ + if (info->iomode != TERMIOS_POLLED) { + /* enable rx interrupts */ + info->uimr |= MCF_UART_UIMR_RXRDY_FU; + MCF_UART_UIMR(minor) = info->uimr; + } + + /* check to see if doing hardware flow control */ + if (hwflow) { + /* assert the RTS line */ + MCF_UART_UOP1(minor) = 1; + } + + rtems_interrupt_enable(level); + +} + +/*************************************************************************** + Function : IntUartSetAttributes + + Description : This provides the hardware-dependent portion of tcsetattr(). + value and sets it. At the moment this just sets the baud rate. + + Note: The highest baudrate is 115200 as this stays within + an error of +/- 5% at 25MHz processor clock + ***************************************************************************/ +static int IntUartSetAttributes(int minor, const struct termios *t) +{ + /* set default index values */ + int baud = (int) 19200; + int databits = (int) MCF_UART_UMR_BC_8; + int parity = (int) MCF_UART_UMR_PM_NONE; + int stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_1; + int hwflow = (int) 0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* check to see if input is valid */ + if (t != (const struct termios *) 0) { + /* determine baud rate index */ + baud = rtems_termios_baud_to_number(t->c_ospeed); + + /* determine data bits */ + switch (t->c_cflag & CSIZE) { + case CS5: + databits = (int) MCF_UART_UMR_BC_5; + break; + case CS6: + databits = (int) MCF_UART_UMR_BC_6; + break; + case CS7: + databits = (int) MCF_UART_UMR_BC_7; + break; + case CS8: + databits = (int) MCF_UART_UMR_BC_8; + break; + } + + /* determine if parity is enabled */ + if (t->c_cflag & PARENB) { + if (t->c_cflag & PARODD) { + /* odd parity */ + parity = (int) MCF_UART_UMR_PM_ODD; + } else { + /* even parity */ + parity = (int) MCF_UART_UMR_PM_EVEN; + } + } + + /* determine stop bits */ + if (t->c_cflag & CSTOPB) { + /* two stop bits */ + stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_2; + } + + /* check to see if hardware flow control */ + if (t->c_cflag & CRTSCTS) { + hwflow = 1; + } + } + + /* check to see if values have changed */ + if ((baud != info->baud) || + (databits != info->databits) || + (parity != info->parity) || + (stopbits != info->stopbits) || (hwflow != info->hwflow)) { + + /* call function to set values */ + IntUartSet(minor, baud, databits, parity, stopbits, hwflow); + } + + return (RTEMS_SUCCESSFUL); + +} + +/*************************************************************************** + Function : IntUartInterruptHandler + + Description : This is the interrupt handler for the internal uart. It + determines which channel caused the interrupt before queueing any received + chars and dequeueing chars waiting for transmission. + ***************************************************************************/ +static rtems_isr IntUartInterruptHandler(rtems_vector_number v) +{ + unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); + struct IntUartInfoStruct *info = &IntUartInfo[chan]; + + /* check to see if received data */ + if (MCF_UART_UISR(chan) & MCF_UART_UISR_RXRDY_FU) { + /* read data and put into the receive buffer */ + while (MCF_UART_USR(chan) & MCF_UART_USR_RXRDY) { + + if (MCF_UART_USR(chan) & MCF_UART_USR_ERROR) { + /* clear the error */ + MCF_UART_UCR(chan) = MCF_UART_UCR_RESET_ERROR; + } + /* put data in rx buffer and check for errors */ + info->rx_buffer[info->rx_in] = MCF_UART_URB(chan); + + /* update buffer values */ + info->rx_in++; + + if (info->rx_in >= RX_BUFFER_SIZE) { + info->rx_in = 0; + } + } + /* Make sure the port has been opened */ + if (info->ttyp) { + + /* check to see if task driven */ + if (info->iomode == TERMIOS_TASK_DRIVEN) { + /* notify rx task that rx buffer has data */ + rtems_termios_rxirq_occured(info->ttyp); + } else { + /* Push up the received data */ + rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, + info->rx_in); + info->rx_in = 0; + } + } + } + + /* check to see if data needs to be transmitted */ + if ((info->uimr & MCF_UART_UIMR_TXRDY) && + (MCF_UART_UISR(chan) & MCF_UART_UISR_TXRDY)) { + + /* disable tx interrupts */ + info->uimr &= ~MCF_UART_UIMR_TXRDY; + MCF_UART_UIMR(chan) = info->uimr; + + /* tell upper level that character has been sent */ + if (info->ttyp) + rtems_termios_dequeue_characters(info->ttyp, 1); + } +} + +/*************************************************************************** + Function : IntUartInitialize + + Description : This initialises the internal uart hardware for all + internal uarts. If the internal uart is to be interrupt driven then the + interrupt vectors are hooked. + ***************************************************************************/ +static void IntUartInitialize(void) +{ + unsigned int chan; + struct IntUartInfoStruct *info; + rtems_isr_entry old_handler; + int level; + + for (chan = 0; chan < MAX_UART_INFO; chan++) { + info = &IntUartInfo[chan]; + + info->ttyp = NULL; + info->rx_in = 0; + info->rx_out = 0; + info->baud = -1; + info->databits = -1; + info->parity = -1; + info->stopbits = -1; + info->hwflow = -1; + info->iomode = TERMIOS_POLLED; /*polled console io */ + + MCF_UART_UACR(chan) = 0; + MCF_UART_UIMR(chan) = 0; + if (info->iomode != TERMIOS_POLLED) { + rtems_interrupt_catch(IntUartInterruptHandler, + UART_INTC0_IRQ_VECTOR(chan), &old_handler); + } + + /* set uart default values */ + IntUartSetAttributes(chan, NULL); + + /* unmask interrupt */ + rtems_interrupt_disable(level); + switch (chan) { + case 0: + MCF_INTC0_ICR13 = MCF_INTC_ICR_IL(UART0_IRQ_LEVEL) | + MCF_INTC_ICR_IP(UART0_IRQ_PRIORITY); + MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK13 | MCF_INTC_IMRL_MASKALL); + break; + + case 1: + MCF_INTC0_ICR14 = MCF_INTC_ICR_IL(UART1_IRQ_LEVEL) | + MCF_INTC_ICR_IP(UART1_IRQ_PRIORITY); + MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK14 | MCF_INTC_IMRL_MASKALL); + break; + + case 2: + MCF_INTC0_ICR15 = MCF_INTC_ICR_IL(UART2_IRQ_LEVEL) | + MCF_INTC_ICR_IP(UART2_IRQ_PRIORITY); + MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK15 | MCF_INTC_IMRL_MASKALL); + break; + } + rtems_interrupt_enable(level); + + } /* of chan loop */ + +} /* IntUartInitialise */ + +/*************************************************************************** + Function : IntUartInterruptWrite + + Description : This writes a single character to the appropriate uart + channel. This is either called during an interrupt or in the user's task + to initiate a transmit sequence. Calling this routine enables Tx + interrupts. + ***************************************************************************/ +static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len) +{ + if (len > 0) { + /* write out character */ + MCF_UART_UTB(minor) = *buf; + + /* enable tx interrupt */ + IntUartInfo[minor].uimr |= MCF_UART_UIMR_TXRDY; + MCF_UART_UIMR(minor) = IntUartInfo[minor].uimr; + } + + return (0); +} + +/*************************************************************************** + Function : IntUartInterruptOpen + + Description : This enables interrupts when the tty is opened. + ***************************************************************************/ +static int IntUartInterruptOpen(int major, int minor, void *arg) +{ + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* enable the uart */ + MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); + + /* check to see if interrupts need to be enabled */ + if (info->iomode != TERMIOS_POLLED) { + /* enable rx interrupts */ + info->uimr |= MCF_UART_UIMR_RXRDY_FU; + MCF_UART_UIMR(minor) = info->uimr; + } + + /* check to see if doing hardware flow control */ + if (info->hwflow) { + /* assert the RTS line */ + MCF_UART_UOP1(minor) = 1; + } + + return (0); +} + +/*************************************************************************** + Function : IntUartInterruptClose + + Description : This disables interrupts when the tty is closed. + ***************************************************************************/ +static int IntUartInterruptClose(int major, int minor, void *arg) +{ + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* disable the interrupts and the uart */ + MCF_UART_UIMR(minor) = 0; + MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED); + + /* reset values */ + info->ttyp = NULL; + info->uimr = 0; + info->rx_in = 0; + info->rx_out = 0; + + return (0); +} + +/*************************************************************************** + Function : IntUartTaskRead + + Description : This reads all available characters from the internal uart + and places them into the termios buffer. The rx interrupts will be + re-enabled after all data has been read. + ***************************************************************************/ +static int IntUartTaskRead(int minor) +{ + char buffer[RX_BUFFER_SIZE]; + int count; + int rx_in; + int index = 0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* determine number of values to copy out */ + rx_in = info->rx_in; + if (info->rx_out <= rx_in) { + count = rx_in - info->rx_out; + } else { + count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; + } + + /* copy data into local buffer from rx buffer */ + while ((index < count) && (index < RX_BUFFER_SIZE)) { + /* copy data byte */ + buffer[index] = info->rx_buffer[info->rx_out]; + index++; + + /* increment rx buffer values */ + info->rx_out++; + if (info->rx_out >= RX_BUFFER_SIZE) { + info->rx_out = 0; + } + } + + /* check to see if buffer is not empty */ + if (count > 0) { + /* set characters into termios buffer */ + rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); + } + + return (EOF); +} + +/*************************************************************************** + Function : IntUartPollRead + + Description : This reads a character from the internal uart. It returns + to the caller without blocking if not character is waiting. + ***************************************************************************/ +static int IntUartPollRead(int minor) +{ + if ((MCF_UART_USR(minor) & MCF_UART_USR_RXRDY) == 0) + return (-1); + + return (MCF_UART_URB(minor)); +} + +/*************************************************************************** + Function : IntUartPollWrite + + Description : This writes out each character in the buffer to the + appropriate internal uart channel waiting till each one is sucessfully + transmitted. + ***************************************************************************/ +static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len) +{ + size_t retval = len; + /* loop over buffer */ + while (len--) { + /* block until we can transmit */ + while ((MCF_UART_USR(minor) & MCF_UART_USR_TXRDY) == 0) + continue; + /* transmit data byte */ + MCF_UART_UTB(minor) = *buf++; + } + return retval; +} + +/*************************************************************************** + Function : console_initialize + + Description : This initialises termios, both sets of uart hardware before + registering /dev/tty devices for each channel and the system /dev/console. + ***************************************************************************/ +rtems_device_driver console_initialize(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + rtems_status_code status; + + /* Set up TERMIOS */ + rtems_termios_initialize(); + + /* set io modes for the different channels and initialize device */ + IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN; + IntUartInitialize(); + + /* Register the console port */ + status = rtems_io_register_name("/dev/console", major, CONSOLE_PORT); + if (status != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(status); + } + + /* Register the other port */ + if (CONSOLE_PORT != 0) { + status = rtems_io_register_name("/dev/tty00", major, 0); + if (status != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(status); + } + } + if (CONSOLE_PORT != 1) { + status = rtems_io_register_name("/dev/tty01", major, 1); + if (status != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(status); + } + } + + return (RTEMS_SUCCESSFUL); +} + +/*************************************************************************** + Function : console_open + + Description : This actually opens the device depending on the minor + number set during initialisation. The device specific access routines are + passed to termios when the devices is opened depending on whether it is + polled or not. + ***************************************************************************/ +rtems_device_driver console_open(rtems_device_major_number major, + rtems_device_minor_number minor, void *arg) +{ + rtems_status_code status = RTEMS_INVALID_NUMBER; + rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *) arg; + struct IntUartInfoStruct *info; + + static const rtems_termios_callbacks IntUartPollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + IntUartPollRead, /* pollRead */ + IntUartPollWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_POLLED /* mode */ + }; + static const rtems_termios_callbacks IntUartIntrCallbacks = { + IntUartInterruptOpen, /* firstOpen */ + IntUartInterruptClose, /* lastClose */ + NULL, /* pollRead */ + IntUartInterruptWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_IRQ_DRIVEN /* mode */ + }; + + static const rtems_termios_callbacks IntUartTaskCallbacks = { + IntUartInterruptOpen, /* firstOpen */ + IntUartInterruptClose, /* lastClose */ + IntUartTaskRead, /* pollRead */ + IntUartInterruptWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_TASK_DRIVEN /* mode */ + }; + + /* open the port depending on the minor device number */ + if ((minor >= 0) && (minor < MAX_UART_INFO)) { + info = &IntUartInfo[minor]; + switch (info->iomode) { + case TERMIOS_POLLED: + status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); + break; + case TERMIOS_IRQ_DRIVEN: + status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); + info->ttyp = args->iop->data1; + break; + case TERMIOS_TASK_DRIVEN: + status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); + info->ttyp = args->iop->data1; + break; + } + } + + if (status == RTEMS_SUCCESSFUL) { + /* + * Reset the default baudrate. + */ + struct termios term; + + if (tcgetattr(STDIN_FILENO, &term) >= 0) { + term.c_cflag &= ~(CSIZE); + term.c_cflag |= CS8; + term.c_ispeed = B19200; + term.c_ospeed = B19200; + tcsetattr(STDIN_FILENO, TCSANOW, &term); + } + } + + return (status); +} + +/*************************************************************************** + Function : console_close + + Description : This closes the device via termios + ***************************************************************************/ +rtems_device_driver console_close(rtems_device_major_number major, + rtems_device_minor_number minor, void *arg) +{ + return (rtems_termios_close(arg)); +} + +/****************** +********************************************************* + Function : console_read + + Description : Read from the device via termios + ***************************************************************************/ +rtems_device_driver console_read(rtems_device_major_number major, + rtems_device_minor_number minor, void *arg) +{ + return (rtems_termios_read(arg)); +} + +/*************************************************************************** + Function : console_write + + Description : Write to the device via termios + ***************************************************************************/ +rtems_device_driver console_write(rtems_device_major_number major, + rtems_device_minor_number minor, void *arg) +{ + return (rtems_termios_write(arg)); +} + +/*************************************************************************** + Function : console_ioctl + + Description : Pass the IOCtl call to termios + ***************************************************************************/ +rtems_device_driver console_control(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + return (rtems_termios_ioctl(arg)); +} diff --git a/bsps/m68k/mcf52235/console/debugio.c b/bsps/m68k/mcf52235/console/debugio.c new file mode 100644 index 0000000000..1fbf4b09d7 --- /dev/null +++ b/bsps/m68k/mcf52235/console/debugio.c @@ -0,0 +1,32 @@ + /* + * Multi UART console serial I/O. + * + * TO DO: Add DMA input/output + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +static void _BSP_null_char(char c) +{ + int level; + + rtems_interrupt_disable(level); + while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0) + continue; + MCF_UART_UTB(CONSOLE_PORT) = c; + while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0) + continue; + rtems_interrupt_enable(level); +} + +BSP_output_char_function_type BSP_output_char = _BSP_null_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; + diff --git a/bsps/m68k/mcf5225x/console/console.c b/bsps/m68k/mcf5225x/console/console.c new file mode 100644 index 0000000000..9e36e3945a --- /dev/null +++ b/bsps/m68k/mcf5225x/console/console.c @@ -0,0 +1,689 @@ +/* + * Multi UART console serial I/O. + * + * TO DO: Add DMA input/output + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x)) + +#define MCF_UART_USR_ERROR ( MCF_UART_USR_RB | \ + MCF_UART_USR_FE | \ + MCF_UART_USR_PE | \ + MCF_UART_USR_OE ) + +static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); +static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len); + +#define MAX_UART_INFO 3 +#define RX_BUFFER_SIZE 512 + +struct IntUartInfoStruct +{ + int iomode; + volatile int uimr; + int baud; + int databits; + int parity; + int stopbits; + int hwflow; + int rx_in; + int rx_out; + char rx_buffer[RX_BUFFER_SIZE]; + void *ttyp; +}; + +struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; + +/*************************************************************************** + Function : IntUartSet + + Description : This updates the hardware UART settings. + ***************************************************************************/ +static void +IntUartSet(int minor, int baud, int databits, int parity, int stopbits, + int hwflow) +{ + int divisor; + uint32_t clock_speed; + uint8_t umr1 = 0; + uint8_t umr2 = 0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + rtems_interrupt_level level=UART0_IRQ_LEVEL; + + rtems_interrupt_disable(level); + + /* disable interrupts, clear RTS line, and disable the UARTS */ + MCF_UART_UIMR(minor) = 0; + MCF_UART_UOP0(minor) = 1; + MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED); + + /* save the current values */ + info->uimr = 0; + info->baud = baud; + info->databits = databits; + info->parity = parity; + info->stopbits = stopbits; + info->hwflow = hwflow; + + clock_speed = bsp_get_CPU_clock_speed(); + /* determine the baud divisor value */ + divisor = ((clock_speed) / (32 * baud)); + if (divisor < 2) + divisor = 2; + + /* check to see if doing hardware flow control */ + if (hwflow) { + /* set hardware flow options */ + umr1 |= MCF_UART_UMR_RXRTS; + umr2 |= MCF_UART_UMR_TXCTS; + } + + /* determine the new umr values */ + umr1 |= (parity | databits); + +#if 1 /* TZN: maybe needed for santec bus modul handling */ + if (minor==STATIONS_PORT) + umr2 |= (stopbits) | 0x20; /* 0x20 ... set TXRTS just4testing */ + else + umr2 |= (stopbits); +#else + umr2 |= (stopbits); +#endif + + /* reset the uart */ + MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_ERROR; + MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_RX; + MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_TX; + + /* reset the uart mode register and update values */ + MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_MR; + MCF_UART_UMR(minor) = umr1; + MCF_UART_UMR(minor) = umr2; + + /* set the baud rate values */ + MCF_UART_UCSR(minor) = + (MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK); + MCF_UART_UBG1(minor) = (divisor & 0xff00) >> 8; + MCF_UART_UBG2(minor) = (divisor & 0x00ff); + + /* enable the uart */ + MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); + + /* check to see if interrupts need to be enabled */ + if (info->iomode != TERMIOS_POLLED) { + /* enable rx interrupts */ + info->uimr |= MCF_UART_UIMR_RXRDY_FU; + MCF_UART_UIMR(minor) = info->uimr; + } + + /* check to see if doing hardware flow control */ + if (hwflow) { + /* assert the RTS line */ + MCF_UART_UOP1(minor) = 1; + } + + if (minor==STATIONS_PORT) //maybe needed for santec handling + MCF_UART_UOP0(minor) = 1; + + rtems_interrupt_enable(level); + +} + +/*************************************************************************** + Function : IntUartSetAttributes + + Description : This provides the hardware-dependent portion of tcsetattr(). + value and sets it. At the moment this just sets the baud rate. + + Note: The highest baudrate is 115200 as this stays within + an error of +/- 5% at 25MHz processor clock + ***************************************************************************/ +static int IntUartSetAttributes(int minor, const struct termios *t) +{ + /* set default index values */ + int baud = (int) 19200; + int databits = (int) MCF_UART_UMR_BC_8; + int parity = (int) MCF_UART_UMR_PM_NONE; + int stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_1; + int hwflow = (int) 0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* check to see if input is valid */ + if (t != (const struct termios *) 0) { + /* determine baud rate index */ + baud = rtems_termios_baud_to_number(t->c_ospeed); + + /* determine data bits */ + switch (t->c_cflag & CSIZE) { + case CS5: + databits = (int) MCF_UART_UMR_BC_5; + break; + case CS6: + databits = (int) MCF_UART_UMR_BC_6; + break; + case CS7: + databits = (int) MCF_UART_UMR_BC_7; + break; + case CS8: + databits = (int) MCF_UART_UMR_BC_8; + break; + } + + /* determine if parity is enabled */ + if (t->c_cflag & PARENB) { + if (t->c_cflag & PARODD) { + /* odd parity */ + parity = (int) MCF_UART_UMR_PM_ODD; + } else { + /* even parity */ + parity = (int) MCF_UART_UMR_PM_EVEN; + } + } + + /* determine stop bits */ + if (t->c_cflag & CSTOPB) { + /* two stop bits */ + stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_2; + } + + /* check to see if hardware flow control */ + if (t->c_cflag & CRTSCTS) { + hwflow = 1; + } + } + + /* check to see if values have changed */ + if ((baud != info->baud) || + (databits != info->databits) || + (parity != info->parity) || + (stopbits != info->stopbits) || (hwflow != info->hwflow)) { + + /* call function to set values */ + IntUartSet(minor, baud, databits, parity, stopbits, hwflow); + } + + return (RTEMS_SUCCESSFUL); + +} + +/*************************************************************************** + Function : IntUartInterruptHandler + + Description : This is the interrupt handler for the internal uart. It + determines which channel caused the interrupt before queueing any received + chars and dequeueing chars waiting for transmission. + ***************************************************************************/ +static rtems_isr IntUartInterruptHandler(rtems_vector_number v) +{ + unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); + struct IntUartInfoStruct *info = &IntUartInfo[chan]; + + + /* check to see if received data */ + if (MCF_UART_UISR(chan) & MCF_UART_UISR_RXRDY_FU) { + +#if 0 /* TZN ... just4testing */ + if (MCF_GPIO_PORTTC&MCF_GPIO_PORTTC_PORTTC0) + MCF_GPIO_PORTTC &= ~MCF_GPIO_PORTTC_PORTTC0; + else + MCF_GPIO_PORTTC |= MCF_GPIO_PORTTC_PORTTC0; +#endif + + /* read data and put into the receive buffer */ + while (MCF_UART_USR(chan) & MCF_UART_USR_RXRDY) { + + if (MCF_UART_USR(chan) & MCF_UART_USR_ERROR) { + /* clear the error */ + MCF_UART_UCR(chan) = MCF_UART_UCR_RESET_ERROR; + } + /* put data in rx buffer and check for errors */ + info->rx_buffer[info->rx_in] = MCF_UART_URB(chan); + + /* update buffer values */ + info->rx_in++; + + if (info->rx_in >= RX_BUFFER_SIZE) { + info->rx_in = 0; + } + } + /* Make sure the port has been opened */ + if (info->ttyp) { + + /* check to see if task driven */ + if (info->iomode == TERMIOS_TASK_DRIVEN) { + /* notify rx task that rx buffer has data */ + rtems_termios_rxirq_occured(info->ttyp); + } else { + /* Push up the received data */ + rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, + info->rx_in); + info->rx_in = 0; + } + } + } + + /* check to see if data needs to be transmitted */ + if ((info->uimr & MCF_UART_UIMR_TXRDY) && + (MCF_UART_UISR(chan) & MCF_UART_UISR_TXRDY)) { + + /* disable tx interrupts */ + info->uimr &= ~MCF_UART_UIMR_TXRDY; + MCF_UART_UIMR(chan) = info->uimr; + + /* tell upper level that character has been sent */ + if (info->ttyp) + rtems_termios_dequeue_characters(info->ttyp, 1); + } +} + +/*************************************************************************** + Function : IntUartInitialize + + Description : This initialises the internal uart hardware for all + internal uarts. If the internal uart is to be interrupt driven then the + interrupt vectors are hooked. + ***************************************************************************/ +static void IntUartInitialize(void) +{ + unsigned int chan; + struct IntUartInfoStruct *info; + rtems_isr_entry old_handler; + rtems_interrupt_level level=UART0_IRQ_LEVEL; + + for (chan = 0; chan < MAX_UART_INFO; chan++) { + info = &IntUartInfo[chan]; + + info->ttyp = NULL; + info->rx_in = 0; + info->rx_out = 0; + info->baud = -1; + info->databits = -1; + info->parity = -1; + info->stopbits = -1; + info->hwflow = -1; + info->iomode = TERMIOS_IRQ_DRIVEN; /*TZN, irq driven console io */ + //info->iomode = TERMIOS_POLLED; /*TZN, just4testint, use polling mode for all UARTS */ + + MCF_UART_UACR(chan) = 0; + MCF_UART_UIMR(chan) = 0; + if (info->iomode != TERMIOS_POLLED) { + rtems_interrupt_catch(IntUartInterruptHandler, + UART_INTC0_IRQ_VECTOR(chan), &old_handler); + } + + /* set uart default values */ + IntUartSetAttributes(chan, NULL); + + /* unmask interrupt */ + rtems_interrupt_disable(level); + switch (chan) { + case 0: + MCF_INTC0_ICR13 = MCF_INTC_ICR_IL(UART0_IRQ_LEVEL) | + MCF_INTC_ICR_IP(UART0_IRQ_PRIORITY); + MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK13 | MCF_INTC_IMRL_MASKALL); + break; + + case 1: + MCF_INTC0_ICR14 = MCF_INTC_ICR_IL(UART1_IRQ_LEVEL) | + MCF_INTC_ICR_IP(UART1_IRQ_PRIORITY); + MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK14 | MCF_INTC_IMRL_MASKALL); + break; + + case 2: + MCF_INTC0_ICR15 = MCF_INTC_ICR_IL(UART2_IRQ_LEVEL) | + MCF_INTC_ICR_IP(UART2_IRQ_PRIORITY); + MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK15 | MCF_INTC_IMRL_MASKALL); + break; + } + rtems_interrupt_enable(level); + + } /* of chan loop */ + +} /* IntUartInitialise */ + +/*************************************************************************** + Function : IntUartInterruptWrite + + Description : This writes a single character to the appropriate uart + channel. This is either called during an interrupt or in the user's task + to initiate a transmit sequence. Calling this routine enables Tx + interrupts. + ***************************************************************************/ +static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len) +{ + if (len > 0) { + /* write out character */ + MCF_UART_UTB(minor) = *buf; + + /* enable tx interrupt */ + IntUartInfo[minor].uimr |= MCF_UART_UIMR_TXRDY; + MCF_UART_UIMR(minor) = IntUartInfo[minor].uimr; + } + + return (0); +} + +/*************************************************************************** + Function : IntUartInterruptOpen + + Description : This enables interrupts when the tty is opened. + ***************************************************************************/ +static int IntUartInterruptOpen(int major, int minor, void *arg) +{ + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* enable the uart */ + MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); + + /* check to see if interrupts need to be enabled */ + if (info->iomode != TERMIOS_POLLED) { + /* enable rx interrupts */ + info->uimr |= MCF_UART_UIMR_RXRDY_FU; + MCF_UART_UIMR(minor) = info->uimr; + } + + /* check to see if doing hardware flow control */ + if (info->hwflow) { + /* assert the RTS line */ + MCF_UART_UOP1(minor) = 1; + } + + return (0); +} + +/*************************************************************************** + Function : IntUartInterruptClose + + Description : This disables interrupts when the tty is closed. + ***************************************************************************/ +static int IntUartInterruptClose(int major, int minor, void *arg) +{ + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* disable the interrupts and the uart */ + MCF_UART_UIMR(minor) = 0; + MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED); + + /* reset values */ + info->ttyp = NULL; + info->uimr = 0; + info->rx_in = 0; + info->rx_out = 0; + + return (0); +} + +/*************************************************************************** + Function : IntUartTaskRead + + Description : This reads all available characters from the internal uart + and places them into the termios buffer. The rx interrupts will be + re-enabled after all data has been read. + ***************************************************************************/ +static int IntUartTaskRead(int minor) +{ + char buffer[RX_BUFFER_SIZE]; + int count; + int rx_in; + int index = 0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* determine number of values to copy out */ + rx_in = info->rx_in; + if (info->rx_out <= rx_in) { + count = rx_in - info->rx_out; + } else { + count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; + } + + /* copy data into local buffer from rx buffer */ + while ((index < count) && (index < RX_BUFFER_SIZE)) { + /* copy data byte */ + buffer[index] = info->rx_buffer[info->rx_out]; + index++; + + /* increment rx buffer values */ + info->rx_out++; + if (info->rx_out >= RX_BUFFER_SIZE) { + info->rx_out = 0; + } + } + + /* check to see if buffer is not empty */ + if (count > 0) { + /* set characters into termios buffer */ + rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); + } + + return (EOF); +} + +/*************************************************************************** + Function : IntUartPollRead + + Description : This reads a character from the internal uart. It returns + to the caller without blocking if not character is waiting. + ***************************************************************************/ +static +int IntUartPollRead(int minor) +{ + if ((MCF_UART_USR(minor) & MCF_UART_USR_RXRDY) == 0) + return (-1); + + return (MCF_UART_URB(minor)); +} + +/*************************************************************************** + Function : IntUartPollWrite + + Description : This writes out each character in the buffer to the + appropriate internal uart channel waiting till each one is sucessfully + transmitted. + ***************************************************************************/ +static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len) +{ + /* loop over buffer */ + while (len--) { + /* block until we can transmit */ + while ((MCF_UART_USR(minor) & MCF_UART_USR_TXRDY) == 0) + continue; + /* transmit data byte */ + MCF_UART_UTB(minor) = *buf++; + } + return (0); +} + +/*************************************************************************** + Function : console_initialize + + Description : This initialises termios, both sets of uart hardware before + registering /dev/tty devices for each channel and the system /dev/console. + ***************************************************************************/ +rtems_device_driver console_initialize(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + rtems_status_code status; + + /* Set up TERMIOS */ + rtems_termios_initialize(); + + /* set io modes for the different channels and initialize device */ + IntUartInitialize(); + + /* Register the console port */ + status = rtems_io_register_name("/dev/console", major, CONSOLE_PORT); + if (status != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(status); + } + + /* Register the RS485 port to communicate with SANTEC stations */ + if ((STATIONS_PORT!=CONSOLE_PORT) && (STATIONS_PORT!=BLUETOOTH_PORT)) { + status = rtems_io_register_name("/dev/tty00", major,STATIONS_PORT); + if (status != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(status); + } + } + else { + status=RTEMS_TOO_MANY; + rtems_fatal_error_occurred(status); + } + + /* Register the Bluetooth port */ + if ((BLUETOOTH_PORT!=CONSOLE_PORT) && (BLUETOOTH_PORT!=STATIONS_PORT)) { + status = rtems_io_register_name("/dev/tty01", major, BLUETOOTH_PORT); + if (status != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(status); + } + } + else { + status=RTEMS_TOO_MANY; + rtems_fatal_error_occurred(status); + } + + return (RTEMS_SUCCESSFUL); +} + +/*************************************************************************** + Function : console_open + + Description : This actually opens the device depending on the minor + number set during initialisation. The device specific access routines are + passed to termios when the devices is opened depending on whether it is + polled or not. + ***************************************************************************/ +rtems_device_driver console_open(rtems_device_major_number major, + rtems_device_minor_number minor, void *arg) +{ + rtems_status_code status = RTEMS_INVALID_NUMBER; + rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *) arg; + struct IntUartInfoStruct *info; + + static const rtems_termios_callbacks IntUartPollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + IntUartPollRead, /* pollRead */ + IntUartPollWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_POLLED /* mode */ + }; + static const rtems_termios_callbacks IntUartIntrCallbacks = { + IntUartInterruptOpen, /* firstOpen */ + IntUartInterruptClose, /* lastClose */ + NULL, /* pollRead */ + IntUartInterruptWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_IRQ_DRIVEN /* mode */ + }; + + static const rtems_termios_callbacks IntUartTaskCallbacks = { + IntUartInterruptOpen, /* firstOpen */ + IntUartInterruptClose, /* lastClose */ + IntUartTaskRead, /* pollRead */ + IntUartInterruptWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_TASK_DRIVEN /* mode */ + }; + + /* open the port depending on the minor device number */ + if ((minor >= 0) && (minor < MAX_UART_INFO)) { + info = &IntUartInfo[minor]; + switch (info->iomode) { + case TERMIOS_POLLED: + status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); + break; + case TERMIOS_IRQ_DRIVEN: + status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); + info->ttyp = args->iop->data1; + break; + case TERMIOS_TASK_DRIVEN: + status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); + info->ttyp = args->iop->data1; + break; + } + } + + if (status == RTEMS_SUCCESSFUL) { + /* + * Reset the default baudrate. + */ + struct termios term; + + if (tcgetattr(STDIN_FILENO, &term) >= 0) { + term.c_cflag &= ~(CSIZE); + term.c_cflag |= CS8; + term.c_ispeed = B115200; + term.c_ospeed = B115200; + tcsetattr(STDIN_FILENO, TCSANOW, &term); + } + } + + return (status); +} + +/*************************************************************************** + Function : console_close + + Description : This closes the device via termios + ***************************************************************************/ +rtems_device_driver console_close(rtems_device_major_number major, + rtems_device_minor_number minor, void *arg) +{ + return (rtems_termios_close(arg)); +} + +/****************** +********************************************************* + Function : console_read + + Description : Read from the device via termios + ***************************************************************************/ +rtems_device_driver console_read(rtems_device_major_number major, + rtems_device_minor_number minor, void *arg) +{ + return (rtems_termios_read(arg)); +} + +/*************************************************************************** + Function : console_write + + Description : Write to the device via termios + ***************************************************************************/ +rtems_device_driver console_write(rtems_device_major_number major, + rtems_device_minor_number minor, void *arg) +{ + return (rtems_termios_write(arg)); +} + +/*************************************************************************** + Function : console_ioctl + + Description : Pass the IOCtl call to termios + ***************************************************************************/ +rtems_device_driver console_control(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + return (rtems_termios_ioctl(arg)); +} diff --git a/bsps/m68k/mcf5225x/console/debugio.c b/bsps/m68k/mcf5225x/console/debugio.c new file mode 100644 index 0000000000..b91048a310 --- /dev/null +++ b/bsps/m68k/mcf5225x/console/debugio.c @@ -0,0 +1,35 @@ +/* + * Multi UART console serial I/O. + * + * TO DO: Add DMA input/output + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +static void _BSP_null_char(char c) +{ + rtems_interrupt_level level=UART0_IRQ_LEVEL; + + rtems_interrupt_disable(level); + while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0) + continue; + MCF_UART_UTB(CONSOLE_PORT) = c; + while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0) + continue; + rtems_interrupt_enable(level); +} + +BSP_output_char_function_type BSP_output_char = _BSP_null_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/m68k/mcf5235/console/console.c b/bsps/m68k/mcf5235/console/console.c new file mode 100644 index 0000000000..38317130cb --- /dev/null +++ b/bsps/m68k/mcf5235/console/console.c @@ -0,0 +1,745 @@ + /* + * Multi UART console serial I/O. + * + * TO DO: Add DMA input/output + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x)) + +#define MCF5235_UART_USR_ERROR ( MCF5235_UART_USR_RB | \ + MCF5235_UART_USR_FE | \ + MCF5235_UART_USR_PE | \ + MCF5235_UART_USR_OE ) + +static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); +static ssize_t IntUartInterruptWrite (int minor, const char *buf, size_t len); + +static void +_BSP_null_char( char c ) +{ + int level; + + rtems_interrupt_disable(level); + while ( (MCF5235_UART_USR(CONSOLE_PORT) & MCF5235_UART_USR_TXRDY) == 0 ) + continue; + MCF5235_UART_UTB(CONSOLE_PORT) = c; + while ( (MCF5235_UART_USR(CONSOLE_PORT) & MCF5235_UART_USR_TXRDY) == 0 ) + continue; + rtems_interrupt_enable(level); +} +BSP_output_char_function_type BSP_output_char = _BSP_null_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; + +#define MAX_UART_INFO 3 +#define RX_BUFFER_SIZE 512 + +struct IntUartInfoStruct +{ + int iomode; + volatile int uimr; + int baud; + int databits; + int parity; + int stopbits; + int hwflow; + int rx_in; + int rx_out; + char rx_buffer[RX_BUFFER_SIZE]; + void *ttyp; +}; + +struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; + +/*************************************************************************** + Function : IntUartSet + + Description : This updates the hardware UART settings. + ***************************************************************************/ +static void +IntUartSet(int minor, int baud, int databits, int parity, int stopbits, int hwflow) +{ + int divisor; + uint32_t clock_speed; + uint8_t umr1 = 0; + uint8_t umr2 = 0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + int level; + + rtems_interrupt_disable(level); + + + /* disable interrupts, clear RTS line, and disable the UARTS */ + MCF5235_UART_UIMR(minor) = 0; + MCF5235_UART_UOP0(minor) = 1; + MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_DISABLED | MCF5235_UART_UCR_RX_DISABLED); + + /* save the current values */ + info->uimr = 0; + info->baud = baud; + info->databits = databits; + info->parity = parity; + info->stopbits = stopbits; + info->hwflow = hwflow; + + clock_speed = get_CPU_clock_speed(); + /* determine the baud divisor value */ + divisor = ((clock_speed/2) / ( 32 * baud )); + if ( divisor < 2 ) { + divisor = 2; + } + + /* check to see if doing hardware flow control */ + if ( hwflow ) + { + /* set hardware flow options */ + umr1 |= MCF5235_UART_UMR_RXRTS; + umr2 |= MCF5235_UART_UMR_TXCTS; + } + + /* determine the new umr values */ + umr1 |= (parity | databits); + umr2 |= (stopbits); + + /* reset the uart */ + MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_ERROR; + MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_RX; + MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_TX; + + /* reset the uart mode register and update values */ + MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_MR; + MCF5235_UART_UMR(minor) = umr1; + MCF5235_UART_UMR(minor) = umr2; + + /* set the baud rate values */ + MCF5235_UART_UCSR(minor) = (MCF5235_UART_UCSR_RCS_SYS_CLK | MCF5235_UART_UCSR_TCS_SYS_CLK); + MCF5235_UART_UBG1(minor) = (divisor & 0xff00) >> 8; + MCF5235_UART_UBG2(minor) = (divisor & 0x00ff); + + /* enable the uart */ + MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_ENABLED | MCF5235_UART_UCR_RX_ENABLED); + + /* check to see if interrupts need to be enabled */ + if ( info->iomode != TERMIOS_POLLED ) + { + /* enable rx interrupts */ + info->uimr |= MCF5235_UART_UIMR_FFULL; + MCF5235_UART_UIMR(minor) = info->uimr; + } + + /* check to see if doing hardware flow control */ + if ( hwflow ) + { + /* assert the RTS line */ + MCF5235_UART_UOP1(minor) = 1; + } + + rtems_interrupt_enable(level); + +} + + +/*************************************************************************** + Function : IntUartSetAttributes + + Description : This provides the hardware-dependent portion of tcsetattr(). + value and sets it. At the moment this just sets the baud rate. + + Note: The highest baudrate is 115200 as this stays within + an error of +/- 5% at 25MHz processor clock + ***************************************************************************/ +static int +IntUartSetAttributes(int minor, const struct termios *t) +{ + /* set default index values */ + int baud = (int)19200; + int databits = (int)MCF5235_UART_UMR_BC_8; + int parity = (int)MCF5235_UART_UMR_PM_NONE; + int stopbits = (int)MCF5235_UART_UMR_STOP_BITS_1; + int hwflow = (int)0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* check to see if input is valid */ + if ( t != (const struct termios *)0 ) + { + /* determine baud rate index */ + baud = rtems_termios_baud_to_number(t->c_ospeed); + + /* determine data bits */ + switch ( t->c_cflag & CSIZE ) + { + case CS5: + databits = (int)MCF5235_UART_UMR_BC_5; + break; + case CS6: + databits = (int)MCF5235_UART_UMR_BC_6; + break; + case CS7: + databits = (int)MCF5235_UART_UMR_BC_7; + break; + case CS8: + databits = (int)MCF5235_UART_UMR_BC_8; + break; + } + + /* determine if parity is enabled */ + if ( t->c_cflag & PARENB ) + { + if ( t->c_cflag & PARODD ) + { + /* odd parity */ + parity = (int)MCF5235_UART_UMR_PM_ODD; + } + else + { + /* even parity */ + parity = (int)MCF5235_UART_UMR_PM_EVEN; + } + } + + /* determine stop bits */ + if ( t->c_cflag & CSTOPB ) + { + /* two stop bits */ + stopbits = (int)MCF5235_UART_UMR_STOP_BITS_2; + } + + /* check to see if hardware flow control */ + if ( t->c_cflag & CRTSCTS ) + { + hwflow = 1; + } + } + + /* check to see if values have changed */ + if ( ( baud != info->baud ) || + ( databits != info->databits ) || + ( parity != info->parity ) || + ( stopbits != info->stopbits ) || + ( hwflow != info->hwflow ) ) + { + + /* call function to set values */ + IntUartSet(minor, baud, databits, parity, stopbits, hwflow); + } + + return( RTEMS_SUCCESSFUL ); + +} + +/*************************************************************************** + Function : IntUartInterruptHandler + + Description : This is the interrupt handler for the internal uart. It + determines which channel caused the interrupt before queueing any received + chars and dequeueing chars waiting for transmission. + ***************************************************************************/ +static rtems_isr +IntUartInterruptHandler(rtems_vector_number v) +{ + unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); + struct IntUartInfoStruct *info = &IntUartInfo[chan]; + + /* check to see if received data */ + if ( MCF5235_UART_UISR(chan) & MCF5235_UART_UISR_RXRDY ) + { + /* read data and put into the receive buffer */ + while ( MCF5235_UART_USR(chan) & MCF5235_UART_USR_RXRDY ) + { + + if ( MCF5235_UART_USR(chan) & MCF5235_UART_USR_ERROR ) + { + /* clear the error */ + MCF5235_UART_UCR(chan) = MCF5235_UART_UCR_RESET_ERROR; + } + /* put data in rx buffer and check for errors */ + info->rx_buffer[info->rx_in] = MCF5235_UART_URB(chan); + + /* update buffer values */ + info->rx_in++; + + if ( info->rx_in >= RX_BUFFER_SIZE ) + { + info->rx_in = 0; + } + } + /* Make sure the port has been opened */ + if ( info->ttyp ) + { + + /* check to see if task driven */ + if ( info->iomode == TERMIOS_TASK_DRIVEN ) + { + /* notify rx task that rx buffer has data */ + rtems_termios_rxirq_occured(info->ttyp); + } + else + { + /* Push up the received data */ + rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, info->rx_in); + info->rx_in = 0; + } + } + } + + /* check to see if data needs to be transmitted */ + if ( ( info->uimr & MCF5235_UART_UIMR_TXRDY ) && + ( MCF5235_UART_UISR(chan) & MCF5235_UART_UISR_TXRDY ) ) + { + + /* disable tx interrupts */ + info->uimr &= ~MCF5235_UART_UIMR_TXRDY; + MCF5235_UART_UIMR(chan) = info->uimr; + + /* tell upper level that character has been sent */ + if ( info->ttyp ) + rtems_termios_dequeue_characters(info->ttyp, 1); + } +} + + + +/*************************************************************************** + Function : IntUartInitialize + + Description : This initialises the internal uart hardware for all + internal uarts. If the internal uart is to be interrupt driven then the + interrupt vectors are hooked. + ***************************************************************************/ +static void +IntUartInitialize(void) +{ + unsigned int chan; + struct IntUartInfoStruct *info; + rtems_isr_entry old_handler; + int level; + + for ( chan = 0; chan < MAX_UART_INFO; chan++ ) + { + info = &IntUartInfo[chan]; + + info->ttyp = NULL; + info->rx_in = 0; + info->rx_out = 0; + info->baud = -1; + info->databits = -1; + info->parity = -1; + info->stopbits = -1; + info->hwflow = -1; + info->iomode = TERMIOS_POLLED; /*polled console io */ + + MCF5235_UART_UACR(chan) = 0; + MCF5235_UART_UIMR(chan) = 0; + if ( info->iomode != TERMIOS_POLLED ) + { + rtems_interrupt_catch (IntUartInterruptHandler, + UART_INTC0_IRQ_VECTOR(chan), + &old_handler); + } + + /* set uart default values */ + IntUartSetAttributes(chan, NULL); + + /* unmask interrupt */ + rtems_interrupt_disable(level); + switch(chan) { + case 0: + MCF5235_INTC0_ICR13 = MCF5235_INTC_ICR_IL(UART0_IRQ_LEVEL) | + MCF5235_INTC_ICR_IP(UART0_IRQ_PRIORITY); + MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT13 | + MCF5235_INTC0_IMRL_MASKALL); + break; + + case 1: + MCF5235_INTC0_ICR14 = MCF5235_INTC_ICR_IL(UART1_IRQ_LEVEL) | + MCF5235_INTC_ICR_IP(UART1_IRQ_PRIORITY); + MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT14 | + MCF5235_INTC0_IMRL_MASKALL); + break; + + case 2: + MCF5235_INTC0_ICR15 = MCF5235_INTC_ICR_IL(UART2_IRQ_LEVEL) | + MCF5235_INTC_ICR_IP(UART2_IRQ_PRIORITY); + MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT15 | + MCF5235_INTC0_IMRL_MASKALL); + break; + } + rtems_interrupt_enable(level); + + } /* of chan loop */ + + +} /* IntUartInitialise */ + + +/*************************************************************************** + Function : IntUartInterruptWrite + + Description : This writes a single character to the appropriate uart + channel. This is either called during an interrupt or in the user's task + to initiate a transmit sequence. Calling this routine enables Tx + interrupts. + ***************************************************************************/ +static ssize_t +IntUartInterruptWrite (int minor, const char *buf, size_t len) +{ + if (len > 0) { + /* write out character */ + MCF5235_UART_UTB(minor) = *buf; + + /* enable tx interrupt */ + IntUartInfo[minor].uimr |= MCF5235_UART_UIMR_TXRDY; + MCF5235_UART_UIMR(minor) = IntUartInfo[minor].uimr; + } + + return( 0 ); +} + +/*************************************************************************** + Function : IntUartInterruptOpen + + Description : This enables interrupts when the tty is opened. + ***************************************************************************/ +static int +IntUartInterruptOpen(int major, int minor, void *arg) +{ + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* enable the uart */ + MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_ENABLED | MCF5235_UART_UCR_RX_ENABLED); + + /* check to see if interrupts need to be enabled */ + if ( info->iomode != TERMIOS_POLLED ) + { + /* enable rx interrupts */ + info->uimr |= MCF5235_UART_UIMR_FFULL; + MCF5235_UART_UIMR(minor) = info->uimr; + } + + /* check to see if doing hardware flow control */ + if ( info->hwflow ) + { + /* assert the RTS line */ + MCF5235_UART_UOP1(minor) = 1; + } + + return( 0 ); +} + + + +/*************************************************************************** + Function : IntUartInterruptClose + + Description : This disables interrupts when the tty is closed. + ***************************************************************************/ +static int +IntUartInterruptClose(int major, int minor, void *arg) +{ + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* disable the interrupts and the uart */ + MCF5235_UART_UIMR(minor) = 0; + MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_DISABLED | MCF5235_UART_UCR_RX_DISABLED); + + /* reset values */ + info->ttyp = NULL; + info->uimr = 0; + info->rx_in = 0; + info->rx_out = 0; + + return( 0 ); +} + +/*************************************************************************** + Function : IntUartTaskRead + + Description : This reads all available characters from the internal uart + and places them into the termios buffer. The rx interrupts will be + re-enabled after all data has been read. + ***************************************************************************/ +static int +IntUartTaskRead(int minor) +{ + char buffer[RX_BUFFER_SIZE]; + int count; + int rx_in; + int index = 0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* determine number of values to copy out */ + rx_in = info->rx_in; + if ( info->rx_out <= rx_in ) + { + count = rx_in - info->rx_out; + } + else + { + count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; + } + + /* copy data into local buffer from rx buffer */ + while ( ( index < count ) && ( index < RX_BUFFER_SIZE ) ) + { + /* copy data byte */ + buffer[index] = info->rx_buffer[info->rx_out]; + index++; + + /* increment rx buffer values */ + info->rx_out++; + if ( info->rx_out >= RX_BUFFER_SIZE ) + { + info->rx_out = 0; + } + } + + /* check to see if buffer is not empty */ + if ( count > 0 ) + { + /* set characters into termios buffer */ + rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); + } + + return( EOF ); +} + + + +/*************************************************************************** + Function : IntUartPollRead + + Description : This reads a character from the internal uart. It returns + to the caller without blocking if not character is waiting. + ***************************************************************************/ +static int +IntUartPollRead (int minor) +{ + if ( (MCF5235_UART_USR(minor) & MCF5235_UART_USR_RXRDY) == 0 ) + return(-1); + + return(MCF5235_UART_URB(minor)); +} + + +/*************************************************************************** + Function : IntUartPollWrite + + Description : This writes out each character in the buffer to the + appropriate internal uart channel waiting till each one is sucessfully + transmitted. + ***************************************************************************/ +static ssize_t +IntUartPollWrite (int minor, const char *buf, size_t len) +{ + size_t retval = len; + /* loop over buffer */ + while ( len-- ) + { + /* block until we can transmit */ + while ( (MCF5235_UART_USR(minor) & MCF5235_UART_USR_TXRDY) == 0 ) + continue; + /* transmit data byte */ + MCF5235_UART_UTB(minor) = *buf++; + } + return retval; +} + +/*************************************************************************** + Function : console_initialize + + Description : This initialises termios, both sets of uart hardware before + registering /dev/tty devices for each channel and the system /dev/console. + ***************************************************************************/ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg ) +{ + rtems_status_code status; + + + /* Set up TERMIOS */ + rtems_termios_initialize (); + + /* set io modes for the different channels and initialize device */ + IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN; + IntUartInitialize(); + + /* Register the console port */ + status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT); + if ( status != RTEMS_SUCCESSFUL ) + { + rtems_fatal_error_occurred (status); + } + + /* Register the other port */ + if ( CONSOLE_PORT != 0 ) + { + status = rtems_io_register_name ("/dev/tty00", major, 0); + if ( status != RTEMS_SUCCESSFUL ) + { + rtems_fatal_error_occurred (status); + } + } + if ( CONSOLE_PORT != 1 ) + { + status = rtems_io_register_name ("/dev/tty01", major, 1); + if ( status != RTEMS_SUCCESSFUL ) + { + rtems_fatal_error_occurred (status); + } + } + + return(RTEMS_SUCCESSFUL); +} + +/*************************************************************************** + Function : console_open + + Description : This actually opens the device depending on the minor + number set during initialisation. The device specific access routines are + passed to termios when the devices is opened depending on whether it is + polled or not. + ***************************************************************************/ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + rtems_status_code status = RTEMS_INVALID_NUMBER; + rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *)arg; + struct IntUartInfoStruct *info; + + static const rtems_termios_callbacks IntUartPollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + IntUartPollRead, /* pollRead */ + IntUartPollWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_POLLED /* mode */ + }; + static const rtems_termios_callbacks IntUartIntrCallbacks = { + IntUartInterruptOpen, /* firstOpen */ + IntUartInterruptClose, /* lastClose */ + NULL, /* pollRead */ + IntUartInterruptWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_IRQ_DRIVEN /* mode */ + }; + + static const rtems_termios_callbacks IntUartTaskCallbacks = { + IntUartInterruptOpen, /* firstOpen */ + IntUartInterruptClose, /* lastClose */ + IntUartTaskRead, /* pollRead */ + IntUartInterruptWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_TASK_DRIVEN /* mode */ + }; + + /* open the port depending on the minor device number */ + if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) ) + { + info = &IntUartInfo[minor]; + switch ( info->iomode ) + { + case TERMIOS_POLLED: + status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); + break; + case TERMIOS_IRQ_DRIVEN: + status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); + info->ttyp = args->iop->data1; + break; + case TERMIOS_TASK_DRIVEN: + status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); + info->ttyp = args->iop->data1; + break; + } + } + + if (status == RTEMS_SUCCESSFUL) + { + /* + * Reset the default baudrate. + */ + struct termios term; + if (tcgetattr (STDIN_FILENO, &term) >= 0) + { + term.c_cflag &= ~(CSIZE); + term.c_cflag |= CS8; + term.c_ispeed = B19200; + term.c_ospeed = B19200; + tcsetattr (STDIN_FILENO, TCSANOW, &term); + } + } + + return( status ); +} + +/*************************************************************************** + Function : console_close + + Description : This closes the device via termios + ***************************************************************************/ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return(rtems_termios_close (arg)); +} + +/****************** +********************************************************* + Function : console_read + + Description : Read from the device via termios + ***************************************************************************/ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return(rtems_termios_read (arg)); +} + +/*************************************************************************** + Function : console_write + + Description : Write to the device via termios + ***************************************************************************/ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return(rtems_termios_write (arg)); +} + +/*************************************************************************** + Function : console_ioctl + + Description : Pass the IOCtl call to termios + ***************************************************************************/ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return( rtems_termios_ioctl (arg) ); +} diff --git a/bsps/m68k/mcf5329/console/console.c b/bsps/m68k/mcf5329/console/console.c new file mode 100644 index 0000000000..797e5b0606 --- /dev/null +++ b/bsps/m68k/mcf5329/console/console.c @@ -0,0 +1,668 @@ + /* + * Multi UART console serial I/O. + * + * TO DO: Add DMA input/output + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#define UART_INTC0_IRQ_VECTOR(x) (64+26+(x)) + +#define MCF_UART_USR_ERROR ( MCF_UART_USR_RB | \ + MCF_UART_USR_FE | \ + MCF_UART_USR_PE | \ + MCF_UART_USR_OE ) + +static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); +static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len); + +static void _BSP_null_char(char c) +{ + int level; + + rtems_interrupt_disable(level); + while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0) + continue; + MCF_UART_UTB(CONSOLE_PORT) = c; + while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0) + continue; + rtems_interrupt_enable(level); +} + +BSP_output_char_function_type BSP_output_char = _BSP_null_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; + +#define MAX_UART_INFO 3 +#define RX_BUFFER_SIZE 512 + +struct IntUartInfoStruct +{ + int iomode; + volatile int uimr; + int baud; + int databits; + int parity; + int stopbits; + int hwflow; + int rx_in; + int rx_out; + char rx_buffer[RX_BUFFER_SIZE]; + void *ttyp; +}; + +struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; + +/*************************************************************************** + Function : IntUartSet + + Description : This updates the hardware UART settings. + ***************************************************************************/ +static void +IntUartSet(int minor, int baud, int databits, int parity, int stopbits, + int hwflow) +{ + int divisor; + uint32_t clock_speed; + uint8_t umr1 = 0; + uint8_t umr2 = 0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + int level; + + rtems_interrupt_disable(level); + + /* disable interrupts, clear RTS line, and disable the UARTS */ + MCF_UART_UIMR(minor) = 0; + MCF_UART_UOP0(minor) = 1; + MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED); + + /* save the current values */ + info->uimr = 0; + info->baud = baud; + info->databits = databits; + info->parity = parity; + info->stopbits = stopbits; + info->hwflow = hwflow; + + clock_speed = bsp_get_BUS_clock_speed(); + /* determine the baud divisor value */ + divisor = ((clock_speed) / (32 * baud)); + if (divisor < 2) + divisor = 2; + + /* check to see if doing hardware flow control */ + if (hwflow) { + /* set hardware flow options */ + umr1 |= MCF_UART_UMR_RXRTS; + umr2 |= MCF_UART_UMR_TXCTS; + } + + /* determine the new umr values */ + umr1 |= (parity | databits); + umr2 |= (stopbits); + + /* reset the uart */ + MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_ERROR; + MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_RX; + MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_TX; + + /* reset the uart mode register and update values */ + MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_MR; + MCF_UART_UMR(minor) = umr1; + MCF_UART_UMR(minor) = umr2; + + /* set the baud rate values */ + MCF_UART_UCSR(minor) = + (MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK); + MCF_UART_UBG1(minor) = (divisor & 0xff00) >> 8; + MCF_UART_UBG2(minor) = (divisor & 0x00ff); + + /* enable the uart */ + MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); + + /* check to see if interrupts need to be enabled */ + if (info->iomode != TERMIOS_POLLED) { + /* enable rx interrupts */ + info->uimr |= MCF_UART_UIMR_RXRDY_FU; + MCF_UART_UIMR(minor) = info->uimr; + } + + /* check to see if doing hardware flow control */ + if (hwflow) { + /* assert the RTS line */ + MCF_UART_UOP1(minor) = 1; + } + + rtems_interrupt_enable(level); + +} + +/*************************************************************************** + Function : IntUartSetAttributes + + Description : This provides the hardware-dependent portion of tcsetattr(). + value and sets it. At the moment this just sets the baud rate. + + Note: The highest baudrate is 115200 as this stays within + an error of +/- 5% at 25MHz processor clock + ***************************************************************************/ +static int IntUartSetAttributes(int minor, const struct termios *t) +{ + /* set default index values */ + int baud = (int) 19200; + int databits = (int) MCF_UART_UMR_BC_8; + int parity = (int) MCF_UART_UMR_PM_NONE; + int stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_1; + int hwflow = (int) 0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* check to see if input is valid */ + if (t != (const struct termios *) 0) { + /* determine baud rate index */ + baud = rtems_termios_baud_to_number(t->c_ospeed); + + /* determine data bits */ + switch (t->c_cflag & CSIZE) { + case CS5: + databits = (int) MCF_UART_UMR_BC_5; + break; + case CS6: + databits = (int) MCF_UART_UMR_BC_6; + break; + case CS7: + databits = (int) MCF_UART_UMR_BC_7; + break; + case CS8: + databits = (int) MCF_UART_UMR_BC_8; + break; + } + + /* determine if parity is enabled */ + if (t->c_cflag & PARENB) { + if (t->c_cflag & PARODD) { + /* odd parity */ + parity = (int) MCF_UART_UMR_PM_ODD; + } else { + /* even parity */ + parity = (int) MCF_UART_UMR_PM_EVEN; + } + } + + /* determine stop bits */ + if (t->c_cflag & CSTOPB) { + /* two stop bits */ + stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_2; + } + + /* check to see if hardware flow control */ + if (t->c_cflag & CRTSCTS) { + hwflow = 1; + } + } + + /* check to see if values have changed */ + if ((baud != info->baud) || + (databits != info->databits) || + (parity != info->parity) || + (stopbits != info->stopbits) || (hwflow != info->hwflow)) { + + /* call function to set values */ + IntUartSet(minor, baud, databits, parity, stopbits, hwflow); + } + + return (RTEMS_SUCCESSFUL); + +} + +/*************************************************************************** + Function : IntUartInterruptHandler + + Description : This is the interrupt handler for the internal uart. It + determines which channel caused the interrupt before queueing any received + chars and dequeueing chars waiting for transmission. + ***************************************************************************/ +static rtems_isr IntUartInterruptHandler(rtems_vector_number v) +{ + unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); + struct IntUartInfoStruct *info = &IntUartInfo[chan]; + + /* check to see if received data */ + if (MCF_UART_UISR(chan) & MCF_UART_UISR_RXRDY_FU) { + /* read data and put into the receive buffer */ + while (MCF_UART_USR(chan) & MCF_UART_USR_RXRDY) { + + if (MCF_UART_USR(chan) & MCF_UART_USR_ERROR) { + /* clear the error */ + MCF_UART_UCR(chan) = MCF_UART_UCR_RESET_ERROR; + } + /* put data in rx buffer and check for errors */ + info->rx_buffer[info->rx_in] = MCF_UART_URB(chan); + + /* update buffer values */ + info->rx_in++; + + if (info->rx_in >= RX_BUFFER_SIZE) { + info->rx_in = 0; + } + } + /* Make sure the port has been opened */ + if (info->ttyp) { + + /* check to see if task driven */ + if (info->iomode == TERMIOS_TASK_DRIVEN) { + /* notify rx task that rx buffer has data */ + rtems_termios_rxirq_occured(info->ttyp); + } else { + /* Push up the received data */ + rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, + info->rx_in); + info->rx_in = 0; + } + } + } + + /* check to see if data needs to be transmitted */ + if ((info->uimr & MCF_UART_UIMR_TXRDY) && + (MCF_UART_UISR(chan) & MCF_UART_UISR_TXRDY)) { + + /* disable tx interrupts */ + info->uimr &= ~MCF_UART_UIMR_TXRDY; + MCF_UART_UIMR(chan) = info->uimr; + + /* tell upper level that character has been sent */ + if (info->ttyp) + rtems_termios_dequeue_characters(info->ttyp, 1); + } +} + +/*************************************************************************** + Function : IntUartInitialize + + Description : This initialises the internal uart hardware for all + internal uarts. If the internal uart is to be interrupt driven then the + interrupt vectors are hooked. + ***************************************************************************/ +static void IntUartInitialize(void) +{ + unsigned int chan; + struct IntUartInfoStruct *info; + rtems_isr_entry old_handler; + int level; + + for (chan = 0; chan < MAX_UART_INFO; chan++) { + info = &IntUartInfo[chan]; + + info->ttyp = NULL; + info->rx_in = 0; + info->rx_out = 0; + info->baud = -1; + info->databits = -1; + info->parity = -1; + info->stopbits = -1; + info->hwflow = -1; + info->iomode = TERMIOS_POLLED; /*polled console io */ + + MCF_UART_UACR(chan) = 0; + MCF_UART_UIMR(chan) = 0; + if (info->iomode != TERMIOS_POLLED) { + rtems_interrupt_catch(IntUartInterruptHandler, + UART_INTC0_IRQ_VECTOR(chan), &old_handler); + } + + /* set uart default values */ + IntUartSetAttributes(chan, NULL); + + /* unmask interrupt */ + rtems_interrupt_disable(level); + switch (chan) { + case 0: + MCF_INTC0_ICR26 = MCF_INTC_ICR_IL(UART0_IRQ_LEVEL); + MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_INT_MASK26); + break; + + case 1: + MCF_INTC0_ICR27 = MCF_INTC_ICR_IL(UART1_IRQ_LEVEL); + MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_INT_MASK27); + break; + + case 2: + MCF_INTC0_ICR28 = MCF_INTC_ICR_IL(UART2_IRQ_LEVEL); + MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_INT_MASK28); + break; + } + rtems_interrupt_enable(level); + + } /* of chan loop */ + +} /* IntUartInitialise */ + +/*************************************************************************** + Function : IntUartInterruptWrite + + Description : This writes a single character to the appropriate uart + channel. This is either called during an interrupt or in the user's task + to initiate a transmit sequence. Calling this routine enables Tx + interrupts. + ***************************************************************************/ +static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len) +{ + if (len > 0) { + /* write out character */ + MCF_UART_UTB(minor) = *buf; + + /* enable tx interrupt */ + IntUartInfo[minor].uimr |= MCF_UART_UIMR_TXRDY; + MCF_UART_UIMR(minor) = IntUartInfo[minor].uimr; + } + + return (0); +} + +/*************************************************************************** + Function : IntUartInterruptOpen + + Description : This enables interrupts when the tty is opened. + ***************************************************************************/ +static int IntUartInterruptOpen(int major, int minor, void *arg) +{ + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* enable the uart */ + MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); + + /* check to see if interrupts need to be enabled */ + if (info->iomode != TERMIOS_POLLED) { + /* enable rx interrupts */ + info->uimr |= MCF_UART_UIMR_RXRDY_FU; + MCF_UART_UIMR(minor) = info->uimr; + } + + /* check to see if doing hardware flow control */ + if (info->hwflow) { + /* assert the RTS line */ + MCF_UART_UOP1(minor) = 1; + } + + return (0); +} + +/*************************************************************************** + Function : IntUartInterruptClose + + Description : This disables interrupts when the tty is closed. + ***************************************************************************/ +static int IntUartInterruptClose(int major, int minor, void *arg) +{ + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* disable the interrupts and the uart */ + MCF_UART_UIMR(minor) = 0; + MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED); + + /* reset values */ + info->ttyp = NULL; + info->uimr = 0; + info->rx_in = 0; + info->rx_out = 0; + + return (0); +} + +/*************************************************************************** + Function : IntUartTaskRead + + Description : This reads all available characters from the internal uart + and places them into the termios buffer. The rx interrupts will be + re-enabled after all data has been read. + ***************************************************************************/ +static int IntUartTaskRead(int minor) +{ + char buffer[RX_BUFFER_SIZE]; + int count; + int rx_in; + int index = 0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* determine number of values to copy out */ + rx_in = info->rx_in; + if (info->rx_out <= rx_in) { + count = rx_in - info->rx_out; + } else { + count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; + } + + /* copy data into local buffer from rx buffer */ + while ((index < count) && (index < RX_BUFFER_SIZE)) { + /* copy data byte */ + buffer[index] = info->rx_buffer[info->rx_out]; + index++; + + /* increment rx buffer values */ + info->rx_out++; + if (info->rx_out >= RX_BUFFER_SIZE) { + info->rx_out = 0; + } + } + + /* check to see if buffer is not empty */ + if (count > 0) { + /* set characters into termios buffer */ + rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); + } + + return (EOF); +} + +/*************************************************************************** + Function : IntUartPollRead + + Description : This reads a character from the internal uart. It returns + to the caller without blocking if not character is waiting. + ***************************************************************************/ +static int IntUartPollRead(int minor) +{ + if ((MCF_UART_USR(minor) & MCF_UART_USR_RXRDY) == 0) + return (-1); + + return (MCF_UART_URB(minor)); +} + +/*************************************************************************** + Function : IntUartPollWrite + + Description : This writes out each character in the buffer to the + appropriate internal uart channel waiting till each one is sucessfully + transmitted. + ***************************************************************************/ +static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len) +{ + size_t retval = len; + /* loop over buffer */ + while (len--) { + /* block until we can transmit */ + while ((MCF_UART_USR(minor) & MCF_UART_USR_TXRDY) == 0) + continue; + /* transmit data byte */ + MCF_UART_UTB(minor) = *buf++; + } + return retval; +} + +/*************************************************************************** + Function : console_initialize + + Description : This initialises termios, both sets of uart hardware before + registering /dev/tty devices for each channel and the system /dev/console. + ***************************************************************************/ +rtems_device_driver console_initialize(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + rtems_status_code status; + + /* Set up TERMIOS */ + rtems_termios_initialize(); + + /* set io modes for the different channels and initialize device */ + IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN; + IntUartInitialize(); + + /* Register the console port */ + status = rtems_io_register_name("/dev/console", major, CONSOLE_PORT); + if (status != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(status); + } + + /* Register the other port */ + if (CONSOLE_PORT != 0) { + status = rtems_io_register_name("/dev/tty00", major, 0); + if (status != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(status); + } + } + if (CONSOLE_PORT != 1) { + status = rtems_io_register_name("/dev/tty01", major, 1); + if (status != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(status); + } + } + + return (RTEMS_SUCCESSFUL); +} + +/*************************************************************************** + Function : console_open + + Description : This actually opens the device depending on the minor + number set during initialisation. The device specific access routines are + passed to termios when the devices is opened depending on whether it is + polled or not. + ***************************************************************************/ +rtems_device_driver console_open(rtems_device_major_number major, + rtems_device_minor_number minor, void *arg) +{ + rtems_status_code status = RTEMS_INVALID_NUMBER; + rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *) arg; + struct IntUartInfoStruct *info; + + static const rtems_termios_callbacks IntUartPollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + IntUartPollRead, /* pollRead */ + IntUartPollWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_POLLED /* mode */ + }; + static const rtems_termios_callbacks IntUartIntrCallbacks = { + IntUartInterruptOpen, /* firstOpen */ + IntUartInterruptClose, /* lastClose */ + NULL, /* pollRead */ + IntUartInterruptWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_IRQ_DRIVEN /* mode */ + }; + + static const rtems_termios_callbacks IntUartTaskCallbacks = { + IntUartInterruptOpen, /* firstOpen */ + IntUartInterruptClose, /* lastClose */ + IntUartTaskRead, /* pollRead */ + IntUartInterruptWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_TASK_DRIVEN /* mode */ + }; + + /* open the port depending on the minor device number */ + if ((minor >= 0) && (minor < MAX_UART_INFO)) { + info = &IntUartInfo[minor]; + switch (info->iomode) { + case TERMIOS_POLLED: + status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); + break; + case TERMIOS_IRQ_DRIVEN: + status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); + info->ttyp = args->iop->data1; + break; + case TERMIOS_TASK_DRIVEN: + status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); + info->ttyp = args->iop->data1; + break; + } + } + + if (status == RTEMS_SUCCESSFUL) { + /* + * Reset the default baudrate. + */ + struct termios term; + + if (tcgetattr(STDIN_FILENO, &term) >= 0) { + term.c_cflag &= ~(CSIZE); + term.c_cflag |= CS8; + term.c_ispeed = B19200; + term.c_ospeed = B19200; + tcsetattr(STDIN_FILENO, TCSANOW, &term); + } + } + + return (status); +} + +/*************************************************************************** + Function : console_close + + Description : This closes the device via termios + ***************************************************************************/ +rtems_device_driver console_close(rtems_device_major_number major, + rtems_device_minor_number minor, void *arg) +{ + return (rtems_termios_close(arg)); +} + +/*************************************************************************** + Function : console_read + + Description : Read from the device via termios + ***************************************************************************/ +rtems_device_driver console_read(rtems_device_major_number major, + rtems_device_minor_number minor, void *arg) +{ + return (rtems_termios_read(arg)); +} + +/*************************************************************************** + Function : console_write + + Description : Write to the device via termios + ***************************************************************************/ +rtems_device_driver console_write(rtems_device_major_number major, + rtems_device_minor_number minor, void *arg) +{ + return (rtems_termios_write(arg)); +} + +/*************************************************************************** + Function : console_ioctl + + Description : Pass the IOCtl call to termios + ***************************************************************************/ +rtems_device_driver console_control(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + return (rtems_termios_ioctl(arg)); +} diff --git a/bsps/m68k/mrm332/console/console.c b/bsps/m68k/mrm332/console/console.c new file mode 100644 index 0000000000..7b5ae7d51c --- /dev/null +++ b/bsps/m68k/mrm332/console/console.c @@ -0,0 +1,155 @@ +/* + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include +#include +#include +#include "sci.h" + +/* + * console_open + * + * open a port as a termios console. + */ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_status_code status; + + /* the console is opened three times at startup */ + /* for standard input, output, and error */ + + /* Get correct callback structure for the device */ + + /* argument of FALSE gives us interrupt driven serial io */ + /* argument of TRUE gives us polling based serial io */ + + /* SCI internal uart */ + + status = rtems_termios_open( major, minor, arg, SciGetTermiosHandlers( FALSE ) ); + + return status; +} + +/* + * console_close + * + * This routine closes a port that has been opened as console. + */ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_close (arg); +} + +/* + * console_read + * + * This routine uses the termios driver to read a character. + */ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_read (arg); +} + +/* + * console_write + * + * this routine uses the termios driver to write a character. + */ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_write (arg); +} + +/* + * console_control + * + * this routine uses the termios driver to process io + */ + +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_ioctl (arg); +} + +/* + * console_initialize + * + * Routine called to initialize the console device driver. + */ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor_arg, + void *arg +) +{ + rtems_status_code status; + + /* + * initialize the termio interface. + */ + rtems_termios_initialize(); + + /* + * register the SCI device name for termios + * do this over in the sci driver init routine? + */ + + status = rtems_io_register_name( "/dev/sci", major, 0 ); + + if (status != RTEMS_SUCCESSFUL) + { + rtems_fatal_error_occurred(status); + } + + /* + * Link the uart device to the console device + */ + +#if 1 + status = rtems_io_register_name( "/dev/console", major, 0 ); + + if (status != RTEMS_SUCCESSFUL) + { + rtems_fatal_error_occurred(status); + } +#else + if ( link( "/dev/sci", "/dev/console") < 0 ) + { + rtems_fatal_error_occurred( RTEMS_IO_ERROR ); + } +#endif + + /* + * Console Initialize Succesful + */ + + return RTEMS_SUCCESSFUL; +} diff --git a/bsps/m68k/mrm332/console/sci.c b/bsps/m68k/mrm332/console/sci.c new file mode 100644 index 0000000000..c6b4933f13 --- /dev/null +++ b/bsps/m68k/mrm332/console/sci.c @@ -0,0 +1,1586 @@ +/***************************************************************************** +* File: sci.c +* +* Desc: This file contains the console IO routines for the SCI port. +* There are two interfaces in this module. One is for the rtems +* termios/console code and the other is a device driver interface. +* This module works together with the termio module which is +* sometimes referred to as the "line disciplines" which implements +* terminal i/o processing like tabs, backspaces, and newlines. +* The rtems printf uses interrupt io and the rtems printk routine +* uses polled io which is better for debugging. +* +* Index: Documentation +* Section A - Include Files +* Section B - Manifest Constants +* Section C - External Data +* Section D - External Functions +* Section E - Local Functions +* Section F - Local Variables +* Section G - A circular data buffer for rcv chars +* Section H - RTEMS termios callbacks for the interrupt api +* Section I - RTEMS termios callbacks for the polled api + +* Section 0 - Miscellaneous routines +* Section 1 - Routines to manipulate the circular buffer +* Section 2 - Interrupt based entry points for the termios module +* Section 3 - Polling based entry points for the termios module +* Section 4 - Device driver public api entry points +* Section 5 - Hardware level routines +* Section 6 - Testing and debugging code +* +* Refer: Motorola QSM Reference Manual - Chapter 5 - SCI sub-module +* +* Note: See bsp.h,confdefs.h,system.h for installing drivers into RTEMS. +* +*****************************************************************************/ + +/***************************************************************************** + Overview of serial port console terminal input/output +*****************************************************************************/ + +/* + +-----------+ +---------+ + | app | | app | + +-----------+ +---------+ + | | + | (printf,scanf,etc.) | + v | + +-----------+ | + | libc | | + +-----------+ | + | | + | | + | (open,close,read,write,ioctl) | + ======|==========================================|======================== + | /dev/console | /dev/sci + | (stdin,stdout,stderr) | + ======|==========================================|======================== + | | + | | + v v + +-----------+ +-----------+ +---------+ + | console | <---> | termios | <---> | sci | + | driver | | module | | driver | + +-----------+ +-----------+ +---------+ + | + | + v + +---------+ + | | + | uart | + | | + +---------+ +*/ + + +/***************************************************************************** + Section A - Include Files +*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include "sci.h" +#include +#include +/*#include "../misc/include/cpu332.h" */ + +/***************************************************************************** + Section B - Manifest Constants +*****************************************************************************/ + +#define SCI_MINOR 0 /* minor device number */ + +/* IMPORTANT - if the device driver api is opened, it means the sci is being + * used for direct hardware access, so other users (like termios) get ignored + */ +#define DRIVER_CLOSED 0 /* the device driver api is closed */ +#define DRIVER_OPENED 1 /* the device driver api is opened */ + +/* system clock definitions, i dont have documentation on this... */ + +#if 0 /* Not needed, this is provided in mrm332.h */ +#define XTAL 32768.0 /* crystal frequency in Hz */ +#define NUMB_W 0 /* system clock parameters */ +#define NUMB_X 1 +#define NUMB_Y 0x38 /* for 14.942 Mhz */ +#define NUMB_Y 0x3F /* for 16.777 Mhz */ + +#define SYS_CLOCK (XTAL * 4.0 * (NUMB_Y+1) * (1 << (2 * NUMB_W + NUMB_X))) + +#endif + + +/***************************************************************************** + Section C - External Data +*****************************************************************************/ + + + +/***************************************************************************** + Section D - External Functions +*****************************************************************************/ + + + +/***************************************************************************** + Section E - Local Functions +*****************************************************************************/ + +void SCI_output_char(char c); + +/*rtems_isr SciIsr( rtems_vector_number vector ); interrupt handler */ + +const rtems_termios_callbacks * SciGetTermiosHandlers( int32_t polled ); + +rtems_device_driver SciInitialize( /* device driver api */ + rtems_device_major_number, rtems_device_minor_number, void *); +rtems_device_driver SciOpen( /* device driver api */ + rtems_device_major_number, rtems_device_minor_number, void *); +rtems_device_driver SciClose( /* device driver api */ + rtems_device_major_number, rtems_device_minor_number, void *); +rtems_device_driver SciRead( /* device driver api */ + rtems_device_major_number, rtems_device_minor_number, void *); +rtems_device_driver SciWrite( /* device driver api */ + rtems_device_major_number, rtems_device_minor_number, void *); +rtems_device_driver SciControl( /* device driver api */ + rtems_device_major_number, rtems_device_minor_number, void *); +rtems_device_driver SciRead ( + rtems_device_major_number, rtems_device_minor_number, void *); + +rtems_isr SciIsr( rtems_vector_number vector ); + +int SciInterruptOpen(int, int, void *); /* termios api */ +int SciInterruptClose(int, int, void *); /* termios api */ +ssize_t SciInterruptWrite(int, const char *, size_t); /* termios api */ + +int SciSetAttributes(int, const struct termios*); /* termios api */ +int SciPolledOpen(int, int, void *); /* termios api */ +int SciPolledClose(int, int, void *); /* termios api */ +int SciPolledRead(int); /* termios api */ +ssize_t SciPolledWrite(int, const char *, size_t); /* termios api */ + +static void SciSetBaud(uint32_t rate); /* hardware routine */ +static void SciSetDataBits(uint16_t bits); /* hardware routine */ +static void SciSetParity(uint16_t parity); /* hardware routine */ + +static void inline SciDisableAllInterrupts( void ); /* hardware routine */ +static void inline SciDisableTransmitInterrupts( void );/* hardware routine */ +static void inline SciDisableReceiveInterrupts( void ); /* hardware routine */ + +static void inline SciEnableTransmitInterrupts( void ); /* hardware routine */ +static void inline SciEnableReceiveInterrupts( void ); /* hardware routine */ + +static void inline SciDisableReceiver( void ); /* hardware routine */ +static void inline SciDisableTransmitter( void ); /* hardware routine */ + +static void inline SciEnableReceiver( void ); /* hardware routine */ +static void inline SciEnableTransmitter( void ); /* hardware routine */ + +void SciWriteCharWait ( uint8_t ); /* hardware routine */ +void SciWriteCharNoWait( uint8_t ); /* hardware routine */ + +uint8_t inline SciCharAvailable( void ); /* hardware routine */ + +static uint8_t inline SciReadCharWait( void ); /* hardware routine */ +static uint8_t inline SciReadCharNoWait( void ); /* hardware routine */ + +void SciSendBreak( void ); /* test routine */ + +static int8_t SciRcvBufGetChar(void); /* circular rcv buf */ +static void SciRcvBufPutChar( uint8_t); /* circular rcv buf */ +#if 0 +static void SciRcvBufFlush( void ); /* unused routine */ +#endif + +void SciUnitTest(void); /* test routine */ +void SciPrintStats(void); /* test routine */ + + +/***************************************************************************** + Section F - Local Variables +*****************************************************************************/ + +static struct rtems_termios_tty *SciTermioTty; + +static uint8_t SciInited = 0; /* has the driver been inited */ + +static uint8_t SciOpened; /* has the driver been opened */ + +static uint8_t SciMajor; /* major device number */ + +static uint16_t SciBaud; /* current value in baud register */ + +static uint32_t SciBytesIn = 0; /* bytes received */ +static uint32_t SciBytesOut = 0; /* bytes transmitted */ + +static uint32_t SciErrorsParity = 0; /* error counter */ +static uint32_t SciErrorsNoise = 0; /* error counter */ +static uint32_t SciErrorsFraming = 0; /* error counter */ +static uint32_t SciErrorsOverrun = 0; /* error counter */ + +#if defined(CONSOLE_SCI) + +/* this is what rtems printk uses to do polling based output */ + +BSP_output_char_function_type BSP_output_char = SCI_output_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; + +#endif + +/***************************************************************************** + Section G - A circular buffer for rcv chars when the driver interface is used. +*****************************************************************************/ + +/* it is trivial to wrap your buffer pointers when size is a power of two */ + +#define SCI_RCV_BUF_SIZE 256 /* must be a power of 2 !!! */ + +/* if someone opens the sci device using the device driver interface, + * then the receive data interrupt handler will put characters in this buffer + * instead of sending them up to the termios module for the console + */ +static uint8_t SciRcvBuffer[SCI_RCV_BUF_SIZE]; + +static uint8_t SciRcvBufPutIndex = 0; /* array index to put in next char */ + +static uint8_t SciRcvBufGetIndex = 0; /* array index to take out next char */ + +static uint16_t SciRcvBufCount = 0; /* how many bytes are in the buffer */ + + + +/***************************************************************************** + Section H - RTEMS termios callbacks for the interrupt version of the driver +*****************************************************************************/ + +static const rtems_termios_callbacks SciInterruptCallbacks = +{ + SciInterruptOpen, /* first open */ + SciInterruptClose, /* last close */ + NULL, /* polled read (not required) */ + SciInterruptWrite, /* write */ + SciSetAttributes, /* set attributes */ + NULL, /* stop remote xmit */ + NULL, /* start remote xmit */ + TRUE /* output uses interrupts */ +}; + +/***************************************************************************** + Section I - RTEMS termios callbacks for the polled version of the driver +*****************************************************************************/ + +static const rtems_termios_callbacks SciPolledCallbacks = +{ + SciPolledOpen, /* first open */ + SciPolledClose, /* last close */ + SciPolledRead, /* polled read */ + SciPolledWrite, /* write */ + SciSetAttributes, /* set attributes */ + NULL, /* stop remote xmit */ + NULL, /* start remote xmit */ + FALSE /* output uses interrupts */ +}; + + +/* + * SECTION 0 + * MISCELLANEOUS ROUTINES + */ + +/**************************************************************************** + * Func: SCI_output_char + * Desc: used by rtems printk function to send a char to the uart + * Inputs: the character to transmit + * Outputs: none + * Errors: none + * Scope: public + ****************************************************************************/ + +void SCI_output_char(char c) +{ +/* ( minor device number, pointer to the character, length ) */ + + SciPolledWrite( SCI_MINOR, &c, 1); + + return; +} + + +/**************************************************************************** +* Func: SciGetTermiosHandlers +* Desc: returns a pointer to the table of serial io functions +* this is called from console_open with polled set to false +* Inputs: flag indicating whether we want polled or interrupt driven io +* Outputs: pointer to function table +* Errors: none +* Scope: public +****************************************************************************/ + +const rtems_termios_callbacks * SciGetTermiosHandlers( int32_t polled ) +{ + if ( polled ) + { + return &SciPolledCallbacks; /* polling based */ + } + else + { + return &SciInterruptCallbacks; /* interrupt driven */ + } +} + + +/**************************************************************************** +* Func: SciIsr +* Desc: interrupt handler for serial communications interface +* Inputs: vector number - unused +* Outputs: none +* Errors: none +* Scope: public API +****************************************************************************/ + +rtems_isr SciIsr( rtems_vector_number vector ) +{ + uint8_t ch; + + if ( (*SCSR) & SCI_ERROR_PARITY ) SciErrorsParity ++; + if ( (*SCSR) & SCI_ERROR_FRAMING ) SciErrorsFraming ++; + if ( (*SCSR) & SCI_ERROR_NOISE ) SciErrorsNoise ++; + if ( (*SCSR) & SCI_ERROR_OVERRUN ) SciErrorsOverrun ++; + + /* see if it was a transmit interrupt */ + /* data reg empty, xmt complete */ + if ( ( *SCCR1 & SCI_ENABLE_INT_TX ) && ( (*SCSR) & SCI_XMTR_AVAILABLE ) ) + { + SciDisableTransmitInterrupts(); + + /* tell termios module that the charcter was sent */ + /* he will call us later to transmit more if there are any */ + + if (rtems_termios_dequeue_characters( SciTermioTty, 1 )) + { + /* there are more bytes to transmit so enable TX interrupt */ + + SciEnableTransmitInterrupts(); + } + } + + /* see if it was a receive interrupt */ + /* on the sci uart we just get one character per interrupt */ + + while ( SciCharAvailable() ) /* char in data register? */ + { + ch = SciReadCharNoWait(); /* get the char from the uart */ + + /* IMPORTANT!!! */ + /* either send it to the termios module or keep it locally */ + + if ( SciOpened == DRIVER_OPENED ) /* the driver is open */ + { + SciRcvBufPutChar(ch); /* keep it locally */ + } + else /* put in termios buffer */ + { + char c = (char) ch; + rtems_termios_enqueue_raw_characters( SciTermioTty, &c, 1 ); + } + + *SCSR &= SCI_CLEAR_RX_INT; /* clear the interrupt */ + } +} + + +/* + * SECTION 1 + * ROUTINES TO MANIPULATE THE CIRCULAR BUFFER + */ + +/**************************************************************************** +* Func: SciRcvBufGetChar +* Desc: read a character from the circular buffer +* make sure there is data before you call this! +* Inputs: none +* Outputs: the character or -1 +* Errors: none +* Scope: private +****************************************************************************/ + +static int8_t SciRcvBufGetChar(void) +{ + rtems_interrupt_level level; + uint8_t ch; + + if ( SciRcvBufCount == 0 ) + { + rtems_fatal_error_occurred(0xDEAD); /* check the count first! */ + } + + rtems_interrupt_disable( level ); /* disable interrupts */ + + ch = SciRcvBuffer[SciRcvBufGetIndex]; /* get next byte */ + + SciRcvBufGetIndex++; /* bump the index */ + + SciRcvBufGetIndex &= SCI_RCV_BUF_SIZE - 1; /* and wrap it */ + + SciRcvBufCount--; /* decrement counter */ + + rtems_interrupt_enable( level ); /* restore interrupts */ + + return ch; /* return the char */ +} + + +/**************************************************************************** +* Func: SciRcvBufPutChar +* Desc: put a character into the rcv data circular buffer +* Inputs: the character +* Outputs: none +* Errors: none +* Scope: private +****************************************************************************/ + +static void SciRcvBufPutChar( uint8_t ch ) +{ + rtems_interrupt_level level; + + if ( SciRcvBufCount == SCI_RCV_BUF_SIZE ) /* is there room? */ + { + return; /* no, throw it away */ + } + + rtems_interrupt_disable( level ); /* disable interrupts */ + + SciRcvBuffer[SciRcvBufPutIndex] = ch; /* put it in the buf */ + + SciRcvBufPutIndex++; /* bump the index */ + + SciRcvBufPutIndex &= SCI_RCV_BUF_SIZE - 1; /* and wrap it */ + + SciRcvBufCount++; /* increment counter */ + + rtems_interrupt_enable( level ); /* restore interrupts */ + + return; /* return */ +} + + +/**************************************************************************** +* Func: SciRcvBufFlush +* Desc: completely reset and clear the rcv buffer +* Inputs: none +* Outputs: none +* Errors: none +* Scope: private +****************************************************************************/ + +#if 0 /* prevents compiler warning */ +static void SciRcvBufFlush( void ) +{ + rtems_interrupt_level level; + + rtems_interrupt_disable( level ); /* disable interrupts */ + + memset( SciRcvBuffer, 0, sizeof(SciRcvBuffer) ); + + SciRcvBufPutIndex = 0; /* clear */ + + SciRcvBufGetIndex = 0; /* clear */ + + SciRcvBufCount = 0; /* clear */ + + rtems_interrupt_enable( level ); /* restore interrupts */ + + return; /* return */ +} +#endif + + +/* + * + * SECTION 2 + * INTERRUPT BASED ENTRY POINTS FOR THE TERMIOS MODULE + */ + +/**************************************************************************** +* Func: SciInterruptOpen +* Desc: open routine for the interrupt based device driver +* Default state is 9600 baud, 8 bits, No parity, and 1 stop bit. ?? +**CHANGED** Default baud rate is now 19200, 8N1 +* called from rtems_termios_open which is called from console_open +* Inputs: major - device number +* minor - device number +* args - points to terminal info +* Outputs: success/fail +* Errors: none +* Scope: public API +****************************************************************************/ + +int SciInterruptOpen( + int major, + int minor, + void *arg +) +{ + rtems_libio_open_close_args_t * args = arg; + rtems_isr_entry old_vector; + + if ( minor != SCI_MINOR ) /* check minor device num */ + { + return -1; + } + + if ( !args ) /* must have args */ + { + return -1; + } + + SciTermioTty = args->iop->data1; /* save address of struct */ + + SciDisableAllInterrupts(); /* turn off sci interrupts */ + + /* THIS IS ACTUALLY A BAD THING - SETTING LINE PARAMETERS HERE */ + /* IT SHOULD BE DONE THROUGH TCSETATTR() WHEN THE CONSOLE IS OPENED!!! */ + +/* SciSetBaud(115200); set the baud rate */ +/* SciSetBaud( 57600); set the baud rate */ +/* SciSetBaud( 38400); set the baud rate */ +/* SciSetBaud( 19200); set the baud rate */ + SciSetBaud( 9600); /* set the baud rate */ + + SciSetParity(SCI_PARITY_NONE); /* set parity to none */ + + SciSetDataBits(SCI_8_DATA_BITS); /* set data bits to 8 */ + + /* Install our interrupt handler into RTEMS. */ + /* 68 is an unused user-defined vector. Note that the vector must be */ + /* even - it sets the low bit for SPI interrupts, and clears it for */ + /* SCI interrupts. Also note that vector 66 is used by CPU32bug on */ + /* the mrm332. */ + + rtems_interrupt_catch( SciIsr, 68, &old_vector ); + + *QSMCR = (*QSMCR & ~IARB) | 1; // Is 1 a good value for qsm iarb? + *QIVR = 68; + *QILR &= 0xf8; + *QILR |= 0x06 & 0x07; + + SciEnableTransmitter(); /* enable the transmitter */ + + SciEnableReceiver(); /* enable the receiver */ + + SciEnableReceiveInterrupts(); /* enable rcv interrupts */ + + return RTEMS_SUCCESSFUL; +} + + +/**************************************************************************** +* Func: SciInterruptClose +* Desc: close routine called by the termios module +* Inputs: major - device number +* minor - device number +* args - unused +* Outputs: success/fail +* Errors: none +* Scope: public - termio entry point +****************************************************************************/ + +int SciInterruptClose( + int major, + int minor, + void *arg +) +{ + SciDisableAllInterrupts(); + + return RTEMS_SUCCESSFUL; +} + + +/**************************************************************************** +* Func: SciInterruptWrite +* Desc: writes data to the uart using transmit interrupts +* Inputs: minor - device number +* buf - points to the data +* len - number of bytes to send +* Outputs: success/fail +* Errors: none +* Scope: public API +****************************************************************************/ + +ssize_t SciInterruptWrite( + int minor, + const char *buf, + size_t len +) +{ + /* We are using interrupt driven output so termios only sends us */ + /* one character at a time. The sci does not have a fifo. */ + + if ( !len ) /* no data? */ + { + return -1; /* return error */ + } + + if ( minor != SCI_MINOR ) /* check the minor dev num */ + { + return -1; /* return error */ + } + + if ( SciOpened == DRIVER_OPENED ) /* is the driver api open? */ + { + return -1; /* yep, throw this away */ + } + + SciWriteCharNoWait(*buf); /* try to send a char */ + + *SCSR &= SCI_CLEAR_TDRE; /* clear tx data reg empty flag */ + + SciEnableTransmitInterrupts(); /* enable the tx interrupt */ + + return 0; /* return success */ +} + + +/**************************************************************************** +* Func: SciSetAttributes +* Desc: setup the uart based on the termios modules requests +* Inputs: minor - device number +* t - pointer to the termios info struct +* Outputs: none +* Errors: none +* Scope: public API +****************************************************************************/ + +int SciSetAttributes( + int minor, + const struct termios *t +) +{ + uint32_t baud_requested; + uint32_t sci_rate = 0; + uint16_t sci_parity = 0; + uint16_t sci_databits = 0; + + if ( minor != SCI_MINOR ) /* check the minor dev num */ + { + return -1; /* return error */ + } + + /* if you look closely you will see this is the only thing we use */ + /* set the baud rate */ + + baud_requested = t->c_ospeed; /* baud rate */ + + if (!baud_requested) + { + baud_requested = B9600; /* default to 9600 baud */ + /* baud_requested = B19200; default to 19200 baud */ + } + + sci_rate = rtems_termios_baud_to_number( baud_requested ); + + /* parity error detection */ + + if (t->c_cflag & PARENB) /* enable parity detection? */ + { + if (t->c_cflag & PARODD) + { + sci_parity = SCI_PARITY_ODD; /* select odd parity */ + } + else + { + sci_parity = SCI_PARITY_EVEN; /* select even parity */ + } + } + else + { + sci_parity = SCI_PARITY_NONE; /* no parity, most common */ + } + + /* set the number of data bits, 8 is most common */ + + if (t->c_cflag & CSIZE) /* was it specified? */ + { + switch (t->c_cflag & CSIZE) + { + case CS8: sci_databits = SCI_8_DATA_BITS; break; + default : sci_databits = SCI_9_DATA_BITS; break; + } + } + else + { + sci_databits = SCI_8_DATA_BITS; /* default to 8 data bits */ + } + + /* the number of stop bits; always 1 for SCI */ + + if (t->c_cflag & CSTOPB) + { + /* do nothing */ + } + + /* setup the hardware with these serial port parameters */ + + SciSetBaud(sci_rate); /* set the baud rate */ + SciSetParity(sci_parity); /* set the parity type */ + SciSetDataBits(sci_databits); /* set the data bits */ + + return RTEMS_SUCCESSFUL; +} + + +/* + * + * SECTION 3 + * POLLING BASED ENTRY POINTS FOR THE TERMIOS MODULE + */ + +/**************************************************************************** +* Func: SciPolledOpen +* Desc: open routine for the polled i/o version of the driver +* called from rtems_termios_open which is called from console_open +* Inputs: major - device number +* minor - device number +* args - points to terminal info struct +* Outputs: success/fail +* Errors: none +* Scope: public - termios entry point +****************************************************************************/ + +int SciPolledOpen( + int major, + int minor, + void *arg +) +{ + rtems_libio_open_close_args_t * args = arg; + + if ( minor != SCI_MINOR ) /* check minor device num */ + { + return -1; + } + + if ( !args ) /* must have args */ + { + return -1; + } + + SciTermioTty = args->iop->data1; /* Store tty pointer */ + + SciDisableAllInterrupts(); /* don't generate interrupts */ + + /* THIS IS ACTUALLY A BAD THING - SETTING LINE PARAMETERS HERE */ + /* IT SHOULD BE DONE THROUGH TCSETATTR() WHEN THE CONSOLE IS OPENED!!! */ + +/* SciSetBaud(115200); set the baud rate */ +/* SciSetBaud( 57600); set the baud rate */ +/* SciSetBaud( 38400); set the baud rate */ +/* SciSetBaud( 19200); * set the baud rate */ + SciSetBaud( 9600); /* set the baud rate */ + + SciSetParity(SCI_PARITY_NONE); /* set no parity */ + + SciSetDataBits(SCI_8_DATA_BITS); /* set 8 data bits */ + + SciEnableTransmitter(); /* enable the xmitter */ + + SciEnableReceiver(); /* enable the rcvr */ + + return RTEMS_SUCCESSFUL; +} + + +/**************************************************************************** +* Func: SciPolledClose +* Desc: close routine for the device driver, same for both +* Inputs: major - device number +* minor - device number +* args - unused +* Outputs: success/fail +* Errors: none +* Scope: public termios API +****************************************************************************/ + +int SciPolledClose( + int major, + int minor, + void *arg +) +{ + SciDisableAllInterrupts(); + + return RTEMS_SUCCESSFUL; +} + + +/**************************************************************************** +* Func: SciPolledRead +* Desc: polling based read routine for the uart +* Inputs: minor - device number +* Outputs: error or the character read +* Errors: none +* Scope: public API +****************************************************************************/ + +int SciPolledRead( + int minor +) +{ + if ( minor != SCI_MINOR ) /* check the type-punned dev num */ + { + return -1; /* return error */ + } + + if ( SciCharAvailable() ) /* if a char is available */ + { + return SciReadCharNoWait(); /* read the rx data register */ + } + + return -1; /* return error */ +} + + +/**************************************************************************** +* Func: SciPolledWrite +* Desc: writes out characters in polled mode, waiting for the uart +* check in console_open, but we only seem to use interrupt mode +* Inputs: minor - device number +* buf - points to the data +* len - how many bytes +* Outputs: error or number of bytes written +* Errors: none +* Scope: public termios API +****************************************************************************/ + +ssize_t SciPolledWrite( + int minor, + const char *buf, + size_t len +) +{ + ssize_t written = 0; + + if ( minor != SCI_MINOR ) /* check minor device num */ + { + return -1; + } + + if ( SciOpened == DRIVER_OPENED ) /* is the driver api open? */ + { + return -1; /* toss the data */ + } + + /* send each byte in the string out the port */ + + while ( written < len ) + { + SciWriteCharWait(*buf++); /* send a byte */ + + written++; /* increment counter */ + } + + return written; /* return count */ +} + + +/* + * + * SECTION 4 + * DEVICE DRIVER PUBLIC API ENTRY POINTS + */ + +/**************************************************************************** +* Func: SciInit +* Desc: Initialize the lasers device driver and hardware +* Inputs: major - the major device number which is assigned by rtems +* minor - the minor device number which is undefined at this point +* arg - ????? +* Outputs: RTEMS_SUCCESSFUL +* Errors: None. +* Scope: public API +****************************************************************************/ + +rtems_device_driver SciInitialize ( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ +/* rtems_status_code status; */ + +/*printk("%s\r\n", __FUNCTION__); */ + + /* register the SCI device name for termios console i/o + * this is done over in console.c which doesn't seem exactly right + * but there were problems doing it here... + */ + +/* status = rtems_io_register_name( "/dev/sci", major, 0 ); */ + +/* if (status != RTEMS_SUCCESSFUL) */ +/* rtems_fatal_error_occurred(status); */ + + SciMajor = major; /* save the rtems major number */ + + SciOpened = DRIVER_CLOSED; /* initial state is closed */ + + /* if you have an interrupt handler, install it here */ + + SciInited = 1; /* set the inited flag */ + + return RTEMS_SUCCESSFUL; +} + + +/**************************************************************************** +* Func: SciOpen +* Desc: device driver open routine +* you must open a device before you can anything else +* only one process can have the device opened at a time +* you could look at the task id to restrict access if you want +* Inputs: major - the major device number assigned by rtems +* minor - the minor device number assigned by us +* arg - ????? +* Outputs: see below +* Errors: none +* Scope: public API +****************************************************************************/ + +rtems_device_driver SciOpen ( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ +/*printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor); */ + + if (SciInited == 0) /* must be initialized first! */ + { + return RTEMS_NOT_CONFIGURED; + } + + if (minor != SCI_MINOR) + { + return RTEMS_INVALID_NAME; /* verify minor number */ + } + + if (SciOpened == DRIVER_OPENED) + { + return RTEMS_RESOURCE_IN_USE; /* already opened! */ + } + + SciOpened = DRIVER_OPENED; /* set the opened flag */ + + return RTEMS_SUCCESSFUL; +} + + +/**************************************************************************** +* Func: SciClose +* Desc: device driver close routine +* the device must be opened before you can close it +* the device must be closed before someone (else) can open it +* Inputs: major - the major device number +* minor - the minor device number +* arg - ????? +* Outputs: see below +* Errors: none +* Scope: public API +****************************************************************************/ + +rtems_device_driver SciClose ( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ +/*printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor); */ + + if (minor != SCI_MINOR) + { + return RTEMS_INVALID_NAME; /* check the minor number */ + } + + if (SciOpened != DRIVER_OPENED) + { + return RTEMS_INCORRECT_STATE; /* must be opened first */ + } + + SciOpened = DRIVER_CLOSED; /* set the flag */ + + return RTEMS_SUCCESSFUL; +} + + +/**************************************************************************** +* Func: SciRead +* Desc: device driver read routine +* this function is not meaningful for the laser devices +* Inputs: major - the major device number +* minor - the minor device number +* arg - read/write arguments +* Outputs: see below +* Errors: none +* Scope: public API +****************************************************************************/ + +rtems_device_driver SciRead ( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_libio_rw_args_t *rw_args; /* ptr to argument struct */ + char *buffer; + + rw_args = (rtems_libio_rw_args_t *) arg; /* arguments to read() */ + + if (minor != SCI_MINOR) + { + return RTEMS_INVALID_NAME; /* check the minor number */ + } + + if (SciOpened == DRIVER_CLOSED) + { + return RTEMS_INCORRECT_STATE; /* must be opened first */ + } + + buffer = rw_args->buffer; /* points to user's buffer */ + +/* *buffer = SciReadCharWait(); wait for a character */ + + /* if there isn't a character available, wait until one shows up */ + /* or the timeout period expires, which ever happens first */ + + if ( SciRcvBufCount == 0 ) /* no chars */ + { + /* wait for someone to wake me up... */ + /*rtems_task_wake_after(SciReadTimeout); */ + } + + if ( SciRcvBufCount ) /* any characters locally? */ + { + *buffer = SciRcvBufGetChar(); /* get the character */ + + rw_args->bytes_moved = 1; /* how many we actually read */ + } + + return RTEMS_SUCCESSFUL; +} + + +/**************************************************************************** +* Func: SciWrite +* Desc: device driver write routine +* this function is not meaningful for the laser devices +* Inputs: major - the major device number +* minor - the minor device number +* arg - read/write arguments +* Outputs: see below +* Errors: non3 +* Scope: public API +****************************************************************************/ + +rtems_device_driver SciWrite ( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args; /* ptr to argument struct */ + uint8_t *buffer; + size_t length; + + rw_args = (rtems_libio_rw_args_t *) arg; + + if (minor != SCI_MINOR) + { + return RTEMS_INVALID_NAME; /* check the minor number */ + } + + if (SciOpened == DRIVER_CLOSED) + { + return RTEMS_INCORRECT_STATE; /* must be opened first */ + } + + buffer = (uint8_t*)rw_args->buffer; /* points to data */ + + length = rw_args->count; /* how many bytes */ + + while (length--) + { + SciWriteCharWait(*buffer++); /* send the bytes out */ + } + + rw_args->bytes_moved = rw_args->count; /* how many we wrote */ + + return RTEMS_SUCCESSFUL; +} + + +/**************************************************************************** +* Func: SciControl +* Desc: device driver control routine +* see below for an example of how to use the ioctl interface +* Inputs: major - the major device number +* minor - the minor device number +* arg - io control args +* Outputs: see below +* Errors: none +* Scope: public API +****************************************************************************/ + +rtems_device_driver SciControl ( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_ioctl_args_t *args = arg; /* rtems arg struct */ + uint16_t command; /* the cmd to execute */ + +/*printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor); */ + + /* do some sanity checking */ + + if (minor != SCI_MINOR) + { + return RTEMS_INVALID_NAME; /* check the minor number */ + } + + if (SciOpened == DRIVER_CLOSED) + { + return RTEMS_INCORRECT_STATE; /* must be open first */ + } + + if (args == 0) + { + return RTEMS_INVALID_ADDRESS; /* must have args */ + } + + args->ioctl_return = -1; /* assume an error */ + + command = args->command; /* get the command */ + + if (command == SCI_SEND_BREAK) /* process the command */ + { + SciSendBreak(); /* send break char */ + } + + args->ioctl_return = 0; /* return status */ + + return RTEMS_SUCCESSFUL; +} + + +/* + * + * SECTION 5 + * HARDWARE LEVEL ROUTINES + */ + +/**************************************************************************** +* Func: SciSetBaud +* Desc: setup the uart based on the termios modules requests +* Inputs: baud rate +* Outputs: none +* Errors: none +* Scope: private +****************************************************************************/ + +static void SciSetBaud(uint32_t rate) +{ + uint16_t value; + uint16_t save_sccr1; + +/* when you open the console you need to set the termio struct baud rate */ +/* it has a default value of 9600, when someone calls tcsetattr it reverts! */ + + SciBaud = rate; /* save the rate */ + + /* calculate the register value as a float and convert to an int */ + /* set baud rate - you must define the system clock constant */ + /* see mrm332.h for an example */ + + value = ( (uint16_t) ( SYS_CLOCK / rate / 32.0 + 0.5 ) & 0x1fff ); + + save_sccr1 = *SCCR1; /* save register */ + + /* also turns off the xmtr and rcvr */ + + *SCCR1 &= SCI_DISABLE_INT_ALL; /* disable interrupts */ + + *SCCR0 = value; /* write the register */ + + *SCCR1 = save_sccr1; /* restore register */ + + return; +} + + +/**************************************************************************** +* Func: SciSetParity +* Desc: setup the uart based on the termios modules requests +* Inputs: parity +* Outputs: none +* Errors: none +* Scope: private +****************************************************************************/ + +static void SciSetParity(uint16_t parity) +{ + uint16_t value; + + value = *SCCR1; /* get the register */ + + if (parity == SCI_PARITY_ODD) + { + value |= SCI_PARITY_ENABLE; /* parity enabled */ + value |= SCI_PARITY_ODD; /* parity odd */ + } + + else if (parity == SCI_PARITY_EVEN) + { + value |= SCI_PARITY_ENABLE; /* parity enabled */ + value &= ~SCI_PARITY_ODD; /* parity even */ + } + + else if (parity == SCI_PARITY_NONE) + { + value &= ~SCI_PARITY_ENABLE; /* disabled, most common */ + } + + /* else no changes */ + + *SCCR1 = value; /* write the register */ + + return; +} + + +/**************************************************************************** +* Func: SciSetDataBits +* Desc: setup the uart based on the termios modules requests +* Inputs: data bits +* Outputs: none +* Errors: none +* Scope: private +****************************************************************************/ + +static void SciSetDataBits(uint16_t bits) +{ + uint16_t value; + + value = *SCCR1; /* get the register */ + + /* note - the parity setting affects the number of data bits */ + + if (bits == SCI_9_DATA_BITS) + { + value |= SCI_9_DATA_BITS; /* 9 data bits */ + } + + else if (bits == SCI_8_DATA_BITS) + { + value &= SCI_8_DATA_BITS; /* 8 data bits */ + } + + /* else no changes */ + + *SCCR1 = value; /* write the register */ + + return; +} + + +/**************************************************************************** +* Func: SciDisableAllInterrupts +* Func: SciEnableTransmitInterrupts +* Func: SciEnableReceiveInterrupts +* Desc: handles generation of interrupts by the sci module +* Inputs: none +* Outputs: none +* Errors: none +* Scope: private +****************************************************************************/ + +static void inline SciDisableAllInterrupts( void ) +{ + /* this also turns off the xmtr and rcvr */ + + *SCCR1 &= SCI_DISABLE_INT_ALL; +} + +static void inline SciEnableReceiveInterrupts( void ) +{ + *SCCR1 |= SCI_ENABLE_INT_RX; +} + +static void inline SciDisableReceiveInterrupts( void ) +{ + *SCCR1 &= SCI_DISABLE_INT_RX; +} + +static void inline SciEnableTransmitInterrupts( void ) +{ + *SCCR1 |= SCI_ENABLE_INT_TX; +} + +static void inline SciDisableTransmitInterrupts( void ) +{ + *SCCR1 &= SCI_DISABLE_INT_TX; +} + + +/**************************************************************************** +* Func: SciEnableTransmitter, SciDisableTransmitter +* Func: SciEnableReceiver, SciDisableReceiver +* Desc: turns the transmitter and receiver on and off +* Inputs: none +* Outputs: none +* Errors: none +* Scope: private +****************************************************************************/ + +static void inline SciEnableTransmitter( void ) +{ + *SCCR1 |= SCI_ENABLE_XMTR; +} + +static void inline SciDisableTransmitter( void ) +{ + *SCCR1 &= SCI_DISABLE_XMTR; +} + +static void inline SciEnableReceiver( void ) +{ + *SCCR1 |= SCI_ENABLE_RCVR; +} + +static void inline SciDisableReceiver( void ) +{ + *SCCR1 &= SCI_DISABLE_RCVR; +} + + +/**************************************************************************** +* Func: SciWriteCharWait +* Desc: wait for room in the fifo and then put a char in +* Inputs: a byte to send +* Outputs: none +* Errors: none +* Scope: public +****************************************************************************/ + +void SciWriteCharWait(uint8_t c) +{ + /* poll the fifo, waiting for room for another character */ + + while ( ( *SCSR & SCI_XMTR_AVAILABLE ) != SCI_XMTR_AVAILABLE ) + { + /* Either we are writing to the fifo faster than + * the uart can clock bytes out onto the cable, + * or we are in flow control (actually no, we + * are ignoring flow control from the other end). + * In the first case, higher baud rates will help. + */ + /* relinquish processor while waiting */ + rtems_task_wake_after(RTEMS_YIELD_PROCESSOR); + } + + *SCDR = c; /* send the charcter */ + + SciBytesOut++; /* increment the counter */ + + return; +} + +/**************************************************************************** +* Func: SciWriteCharNoWait +* Desc: if no room in the fifo throw the char on the floor +* Inputs: a byte to send +* Outputs: none +* Errors: none +* Scope: public +****************************************************************************/ + +void SciWriteCharNoWait(uint8_t c) +{ + if ( ( *SCSR & SCI_XMTR_AVAILABLE ) == 0 ) + { + return; /* no room, throw it away */ + } + + *SCDR = c; /* put the char in the fifo */ + + SciBytesOut++; /* increment the counter */ + + return; +} + + +/**************************************************************************** +* Func: SciReadCharWait +* Desc: read a character, waiting for one to show up, if need be +* Inputs: none +* Outputs: a character +* Errors: none +* Scope: public +****************************************************************************/ + +static uint8_t inline SciReadCharWait( void ) +{ + uint8_t ch; + + while ( SciCharAvailable() == 0 ) /* anything there? */ + { + /* relinquish processor while waiting */ + rtems_task_wake_after(RTEMS_YIELD_PROCESSOR); + } + + /* if you have rcv ints enabled, then the isr will probably */ + /* get the character before you will unless you turn off ints */ + /* ie polling and ints don't mix that well */ + + ch = *SCDR; /* get the charcter */ + + SciBytesIn++; /* increment the counter */ + + return ch; /* return the char */ +} + +/**************************************************************************** +* Func: SciReadCharNoWait +* Desc: try to get a char but dont wait for one +* Inputs: none +* Outputs: a character or -1 if none +* Errors: none +* Scope: public +****************************************************************************/ + +static uint8_t inline SciReadCharNoWait( void ) +{ + uint8_t ch; + + if ( SciCharAvailable() == 0 ) /* anything there? */ + return -1; + + ch = *SCDR; /* get the character */ + + SciBytesIn++; /* increment the count */ + + return ch; /* return the char */ +} + + +/**************************************************************************** +* Func: SciCharAvailable +* Desc: is there a receive character in the data register +* Inputs: none +* Outputs: false if no char available, else true +* Errors: none +* Scope: public +****************************************************************************/ + +uint8_t inline SciCharAvailable( void ) +{ + return ( *SCSR & SCI_RCVR_READY ); /* char in data register? */ +} + + +/**************************************************************************** +* Func: SciSendBreak +* Desc: send 1 or tow breaks (all zero bits) +* Inputs: none +* Outputs: none +* Errors: none +* Scope: public +****************************************************************************/ + +void SciSendBreak( void ) +{ + /* From the Motorola QSM reference manual - */ + + /* "if SBK is toggled by writing it first to a one and then immediately */ + /* to a zero (in less than one serial frame interval), the transmitter */ + /* sends only one or two break frames before reverting to mark (idle) */ + /* or before commencing to send more data" */ + + *SCCR1 |= SCI_SEND_BREAK; /* set the bit */ + + *SCCR1 &= ~SCI_SEND_BREAK; /* clear the bit */ + + return; +} + + +/* + * + * SECTION 6 + * TEST CODE + */ + +/**************************************************************************** +* Func: SciUnitTest +* Desc: test the device driver +* Inputs: nothing +* Outputs: nothing +* Scope: public +****************************************************************************/ + +#if 0 +void SciUnitTest() +{ + uint8_t byte; /* a character */ + uint16_t fd; /* file descriptor for device */ + uint16_t result; /* result of ioctl */ + + fd = open("/dev/sci",O_RDWR); /* open the device */ + +printk("SCI open fd=%d\r\n",fd); + + result = write(fd, "abcd\r\n", 6); /* send a string */ + +printk("SCI write result=%d\r\n",result); + + result = read(fd, &byte, 1); /* read a byte */ + +printk("SCI read result=%d,byte=%x\r\n",result,byte); + + return; +} +#endif + + +/**************************************************************************** +* Func: SciPrintStats +* Desc: print out some driver information +* Inputs: nothing +* Outputs: nothing +* Scope: public +****************************************************************************/ + +void SciPrintStats ( void ) +{ + printk("\r\n"); + + printk( "SYS_CLOCK is %2.6f Mhz\r\n\n", SYS_CLOCK / 1000000.0 ); + + printk( "Current baud rate is %d bps or %d cps\r\n\n", SciBaud, SciBaud / 10 ); + + printk( "SCI Uart chars in %8" PRIu32 "\r\n", SciBytesIn ); + printk( "SCI Uart chars out %8" PRIu32 "\r\n", SciBytesOut ); + printk( "SCI Uart framing errors %8" PRIu32 "\r\n", SciErrorsFraming ); + printk( "SCI Uart parity errors %8" PRIu32 "\r\n", SciErrorsParity ); + printk( "SCI Uart overrun errors %8" PRIu32 "\r\n", SciErrorsOverrun ); + printk( "SCI Uart noise errors %8" PRIu32 "\r\n", SciErrorsNoise ); + + return; +} diff --git a/bsps/m68k/mrm332/console/sci.h b/bsps/m68k/mrm332/console/sci.h new file mode 100644 index 0000000000..93893ecbfc --- /dev/null +++ b/bsps/m68k/mrm332/console/sci.h @@ -0,0 +1,233 @@ +/**************************************************************************** +* File: sci.h +* +* Desc: This is the include file for the serial communications interface. +* +* Note: See bsp.h,confdefs.h,system.h for installing drivers into RTEMS. +* +****************************************************************************/ + +#ifndef _sci_h_ +#define _sci_h_ + +/******************************************************************************* + IOCTL commands for the sci driver. + I'm still working on these... +*******************************************************************************/ + +#define SCI_IOCTL_PARITY_NONE 0x00 /* no parity bit after the data bits */ +#define SCI_IOCTL_PARITY_ODD 0x01 /* parity bit added after data bits */ +#define SCI_IOCTL_PARITY_EVEN 0x02 /* parity bit added after data bits */ +#define SCI_IOCTL_PARITY_MARK 0x03 /* parity bit is lo, -12 volts, logical 1 */ +#define SCI_IOCTL_PARITY_SPACE 0x04 /* parity bit is hi, +12 volts, logical 0 */ +#define SCI_IOCTL_PARITY_FORCED_ON 0x03 /* parity bit is forced hi or lo */ +#define SCI_IOCTL_PARITY_FORCED_OFF 0x04 /* parity bit is forced hi or lo */ + +#define SCI_IOCTL_BAUD_RATE 0x20 /* set the baud rate, arg is baud */ + +#define SCI_IOCTL_DATA_BITS 0x30 /* set the data bits, arg is # bits */ + +#define SCI_IOCTL_STOP_BITS_1 0x40 /* 1 stop bit after char frame */ +#define SCI_IOCTL_STOP_BITS_2 0x41 /* 2 stop bit after char frame */ + +#define SCI_IOCTL_MODE_NORMAL 0x50 /* normal operating mode */ +#define SCI_IOCTL_MODE_LOOP 0x51 /* internal loopback mode */ + +#define SCI_IOCTL_FLOW_NONE 0x60 /* no flow control */ +#define SCI_IOCTL_FLOW_RTS_CTS 0x61 /* hardware flow control */ + +#define SCI_IOCTL_SEND_BREAK 0x70 /* send an rs-232 break */ + +#define SCI_IOCTL_MODE_1200 0x80 /* 1200,n,8,1 download mode */ +#define SCI_IOCTL_MODE_9600 0x81 /* 9600,n,8,1 download mode */ +#define SCI_IOCTL_MODE_9_BIT 0x82 /* 9600,forced,8,1 command mode */ + + +/******************************************************************************* + SCI Registers +*******************************************************************************/ + +/* SCI Control Register 0 (SCCR0) $FFFC08 + + 8 4 2 1 - 8 4 2 1 - 8 4 2 1 - 8 4 2 1 + ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ + | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | +----- 0 baud rate divisor + | | | | | | | | | | | | | | +------- 1 baud rate divisor + | | | | | | | | | | | | | +--------- 2 baud rate divisor + | | | | | | | | | | | | +----------- 3 baud rate divisor + | | | | | | | | | | | | + | | | | | | | | | | | +--------------- 4 baud rate divisor + | | | | | | | | | | +----------------- 5 baud rate divisor + | | | | | | | | | +------------------- 6 baud rate divisor + | | | | | | | | +--------------------- 7 baud rate divisor + | | | | | | | | + | | | | | | | +------------------------- 8 baud rate divisor + | | | | | | +--------------------------- 9 baud rate divisor + | | | | | +----------------------------- 10 baud rate divisor + | | | | +------------------------------- 11 baud rate divisor + | | | | + | | | +----------------------------------- 12 baud rate divisor + | | +------------------------------------- 13 unused + | +--------------------------------------- 14 unused + +----------------------------------------- 15 unused + + 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 1 0 0 reset value - (64k baud?) + */ + +#define SCI_BAUD_57_6K 9 +#define SCI_BAUD_38_4K 14 +#define SCI_BAUD_19_2K 27 +#define SCI_BAUD_9600 55 +#define SCI_BAUD_4800 109 +#define SCI_BAUD_2400 218 +#define SCI_BAUD_1200 437 + + +/* SCI Control Register 1 (SCCR1) $FFFC0A + + 8 4 2 1 - 8 4 2 1 - 8 4 2 1 - 8 4 2 1 + ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ + | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | +----- 0 send a break + | | | | | | | | | | | | | | +------- 1 rcvr wakeup mode + | | | | | | | | | | | | | +--------- 2 rcvr enable + | | | | | | | | | | | | +----------- 3 xmtr enable + | | | | | | | | | | | | + | | | | | | | | | | | +--------------- 4 idle line intr enable + | | | | | | | | | | +----------------- 5 rcvr intr enable + | | | | | | | | | +------------------- 6 xmit complete intr enable + | | | | | | | | +--------------------- 7 xmtr intr enable + | | | | | | | | + | | | | | | | +------------------------- 8 wakeup on address mark + | | | | | | +--------------------------- 9 mode 1=9 bits, 0=8 bits + | | | | | +----------------------------- 10 parity enable 1=on, 0=off + | | | | +------------------------------- 11 parity type 1=odd, 0=even + | | | | + | | | +----------------------------------- 12 idle line select + | | +------------------------------------- 13 wired-or mode + | +--------------------------------------- 14 loop mode + +----------------------------------------- 15 unused + + 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 reset value +*/ + +#define SCI_SEND_BREAK 0x0001 /* 0000-0000-0000-0001 */ +#define SCI_RCVR_WAKEUP 0x0002 /* 0000-0000-0000-0010 */ +#define SCI_ENABLE_RCVR 0x0004 /* 0000-0000-0000-0100 */ +#define SCI_ENABLE_XMTR 0x0008 /* 0000-0000-0000-1000 */ + +#define SCI_DISABLE_RCVR 0xFFFB /* 1111-1111-1111-1011 */ +#define SCI_DISABLE_XMTR 0xFFF7 /* 1111-1111-1111-0111 */ + +#define SCI_ENABLE_INT_IDLE 0x0010 /* 0000-0000-0001-0000 */ +#define SCI_ENABLE_INT_RX 0x0020 /* 0000-0000-0010-0000 */ +#define SCI_ENABLE_INT_TX_DONE 0x0040 /* 0000-0000-0100-0000 */ +#define SCI_ENABLE_INT_TX 0x0080 /* 0000-0000-1000-0000 */ + +#define SCI_DISABLE_INT_ALL 0xFF00 /* 1111-1111-0000-0000 ??? */ + +#define SCI_DISABLE_INT_RX 0xFFDF /* 1111-1111-1101-1111 */ +#define SCI_CLEAR_RX_INT 0xFFBF /* 1111-1111-1011-1111 */ +#define SCI_DISABLE_INT_TX 0xFF7F /* 1111-1111-0111-1111 */ +#define SCI_CLEAR_TDRE 0xFEFF /* 1111-1110-1111-1111 */ + +#define SCI_RCVR_WAKE_ON_MARK 0x0100 /* 0000-0001-0000-0000 */ +#define SCI_9_DATA_BITS 0x0200 /* 0000-0010-0000-0000 */ +#define SCI_PARITY_ENABLE 0x0400 /* 0000-0100-0000-0000 */ +#define SCI_PARITY_ODD 0x0800 /* 0000-1000-0000-0000 */ + +#define SCI_RCVR_WAKE_ON_IDLE 0xFEFF /* 1111-1110-1111-1111 */ +#define SCI_8_DATA_BITS 0xFDFF /* 1111-1101-1111-1111 */ +#define SCI_PARITY_DISABLE 0xFBFF /* 1111-1011-1111-1111 */ +#define SCI_PARITY_EVEN 0xF7FF /* 1111-0111-1111-1111 */ + +#define SCI_PARITY_NONE 0xF3FF /* 1111-0011-1111-1111 */ + +#define SCI_IDLE_LINE_LONG 0x1000 /* 0001-0000-0000-0000 */ +#define SCI_TXD_OPEN_DRAIN 0x2000 /* 0010-0000-0000-0000 */ +#define SCI_LOOPBACK_MODE 0x4000 /* 0100-0000-0000-0000 */ +#define SCI_SCCR1_UNUSED 0x8000 /* 1000-0000-0000-0000 */ + + +/* SCI Status Register (SCSR) $FFFC0C + + 8 4 2 1 - 8 4 2 1 - 8 4 2 1 - 8 4 2 1 + ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ + | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | | | +----- 0 PF - parity error + | | | | | | | | | | | | | | +------- 1 FE - framing error + | | | | | | | | | | | | | +--------- 2 NF - noise flag + | | | | | | | | | | | | +----------- 3 OR - overrun flag + | | | | | | | | | | | | + | | | | | | | | | | | +--------------- 4 IDLE - idle line detected + | | | | | | | | | | +----------------- 5 RAF - rcvr active flag + | | | | | | | | | +------------------- 6 RDRF - rcv data reg full + | | | | | | | | +--------------------- 7 TC - xmt complete flag + | | | | | | | | + | | | | | | | +------------------------- 8 TDRE - xmt data reg empty + | | | | | | +--------------------------- 9 always zero + | | | | | +----------------------------- 10 always zero + | | | | +------------------------------- 11 always zero + | | | | + | | | +----------------------------------- 12 always zero + | | +------------------------------------- 13 always zero + | +--------------------------------------- 14 always zero + +----------------------------------------- 15 always zero + + 0 0 0 0 - 0 0 0 1 - 1 0 0 0 - 0 0 0 0 reset value +*/ + +#define SCI_ERROR_PARITY 0x0001 /* 0000-0000-0000-0001 */ +#define SCI_ERROR_FRAMING 0x0002 /* 0000-0000-0000-0010 */ +#define SCI_ERROR_NOISE 0x0004 /* 0000-0000-0000-0100 */ +#define SCI_ERROR_OVERRUN 0x0008 /* 0000-0000-0000-1000 */ + +#define SCI_IDLE_LINE 0x0010 /* 0000-0000-0001-0000 */ +#define SCI_RCVR_ACTIVE 0x0020 /* 0000-0000-0010-0000 */ +#define SCI_RCVR_READY 0x0040 /* 0000-0000-0100-0000 */ +#define SCI_XMTR_IDLE 0x0080 /* 0000-0000-1000-0000 */ + +#define SCI_CLEAR_RX_INT 0xFFBF /* 1111-1111-1011-1111 */ + +#define SCI_XMTR_READY 0x0100 /* 0000-0001-0000-0000 */ + +#define SCI_CLEAR_TDRE 0xFEFF /* 1111-1110-1111-1111 */ + +#define SCI_XMTR_AVAILABLE 0x0180 /* 0000-0001-1000-0000 */ + + + +/******************************************************************************* + Function prototypes +*******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* look at console_open to see how this is called */ + +const rtems_termios_callbacks * SciGetTermiosHandlers( int32_t polled ); + +/* SCI interrupt */ + +/*rtems_isr SciIsr( rtems_vector_number vector ); */ + +/*int32_t SciOpenPolled ( int32_t major, int32_t minor, void *arg ); */ +/*int32_t SciOpenInterrupt ( int32_t major, int32_t minor, void *arg ); */ + +/*int32_t SciClose ( int32_t major, int32_t minor, void *arg ); */ + +/*int32_t SciWritePolled ( int32_t minor, const char *buf, int32_t len ); */ +/*int32_t SciWriteInterrupt( int32_t minor, const char *buf, int32_t len ); */ + +/*int32_t SciReadPolled ( int32_t minor ); */ + +/*int32_t SciSetAttributes ( int32_t minor, const struct termios *t ); */ + +#ifdef __cplusplus +} +#endif + +#endif /* _sci_h_ */ diff --git a/bsps/m68k/mvme147/console/console.c b/bsps/m68k/mvme147/console/console.c new file mode 100644 index 0000000000..f26ca6485a --- /dev/null +++ b/bsps/m68k/mvme147/console/console.c @@ -0,0 +1,203 @@ +/* + * This file contains the MVME147 console IO package. + */ + +/* + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + * MVME147 port for TNI - Telecom Bretagne + * by Dominique LE CAMPION (Dominique.LECAMPION@enst-bretagne.fr) + * May 1996 + * + * This file was taken from the DMV152 bsp + */ + +#define M147_INIT + +#include +#include +#include +#include +#include + +/* console_initialize + * + * This routine initializes the console IO driver. + */ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + + status = rtems_io_register_name( + "/dev/console", + major, + (rtems_device_minor_number) 0 + ); + + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + return RTEMS_SUCCESSFUL; +} + +/* inbyte + * + * This routine reads a character from the SCC. + */ +static char inbyte( void ) +{ + uint8_t rr_0; + char ch; + + for ( ; ; ) { + Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); + if ( (rr_0 & RR_0_RX_DATA_AVAILABLE) != 0 ) + break; + } + + Z8x30_READ_DATA( CONSOLE_DATA, ch ); + return ( ch ); +} + +/* outbyte + * + * This routine transmits a character out the SCC. It supports + * XON/XOFF flow control. + */ +static void outbyte( + char ch +) +{ + uint8_t rr_0; + char flow_control; + + for ( ; ; ) { + Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); + if ( (rr_0 & RR_0_TX_BUFFER_EMPTY) != 0 ) + break; + } + + for ( ; ; ) { + Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); + if ( (rr_0 & RR_0_RX_DATA_AVAILABLE) == 0 ) + break; + + Z8x30_READ_DATA( CONSOLE_DATA, flow_control ); + + if ( flow_control == XOFF ) + do { + do { + Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); + } while ( (rr_0 & RR_0_RX_DATA_AVAILABLE) == 0 ); + Z8x30_READ_DATA( CONSOLE_DATA, flow_control ); + } while ( flow_control != XON ); + } + + Z8x30_WRITE_DATA( CONSOLE_DATA, ch ); +} + +/* + * Open entry point + */ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * Close entry point + */ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * read bytes from the serial port. We only have stdin. + */ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args; + char *buffer; + int maximum; + int count = 0; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + buffer[ count ] = inbyte(); + if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { + buffer[ count++ ] = '\n'; + break; + } + } + + rw_args->bytes_moved = count; + return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; +} + +/* + * write bytes to the serial port. Stdout and stderr are the same. + */ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + int count; + int maximum; + rtems_libio_rw_args_t *rw_args; + char *buffer; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + if ( buffer[ count ] == '\n') { + outbyte('\r'); + } + outbyte( buffer[ count ] ); + } + + rw_args->bytes_moved = maximum; + return 0; +} + +/* + * IO Control entry point + */ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} diff --git a/bsps/m68k/mvme162/console/console.c b/bsps/m68k/mvme162/console/console.c new file mode 100644 index 0000000000..985254d483 --- /dev/null +++ b/bsps/m68k/mvme162/console/console.c @@ -0,0 +1,277 @@ +/* + * This file contains the MVME162 console IO package. + */ + +/* + * COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + * Modifications of respective RTEMS file: COPYRIGHT (c) 1994. + * EISCAT Scientific Association. M.Savitski + * + * This material is a part of the MVME162 Board Support Package + * for the RTEMS executive. Its licensing policies are those of the + * RTEMS above. + */ + +#define M162_INIT + +#include +#include +#include +#include +#include + +Ring_buffer_t Console_Buffer[2]; + +/* + * Interrupt handler for receiver interrupts + */ +static rtems_isr C_Receive_ISR(rtems_vector_number vector) +{ + register int ipend, port; + + ZWRITE0(1, 0x38); /* reset highest IUS */ + + ipend = ZREAD(1, 3); /* read int pending from A side */ + + if (ipend == 0x04) port = 0; /* channel B intr pending */ + else if (ipend == 0x20) port = 1; /* channel A intr pending */ + else return; + + Ring_buffer_Add_character(&Console_Buffer[port], ZREADD(port)); + + if (ZREAD(port, 1) & 0x70) { /* check error stat */ + ZWRITE0(port, 0x30); /* reset error */ + } +} + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + int i; + rtems_status_code status; + + /* + * Initialise receiver interrupts on both ports + */ + for (i = 0; i <= 1; i++) { + Ring_buffer_Initialize( &Console_Buffer[i] ); + ZWRITE(i, 2, SCC_VECTOR); + ZWRITE(i, 10, 0); + ZWRITE(i, 1, 0x10); /* int on all Rx chars or special condition */ + ZWRITE(i, 9, 8); /* master interrupt enable */ + } + + set_vector(C_Receive_ISR, SCC_VECTOR, 1); /* install ISR for ports A and B */ + + mcchip->vector_base = 0; + mcchip->gen_control = 2; /* MIEN */ + mcchip->SCC_int_ctl = 0x13; /* SCC IEN, IPL3 */ + + status = rtems_io_register_name( + "/dev/console", + major, + (rtems_device_minor_number) 1 + ); + + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + status = rtems_io_register_name( + "/dev/tty00", + major, + (rtems_device_minor_number) 0 + ); + + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + status = rtems_io_register_name( + "/dev/tty01", + major, + (rtems_device_minor_number) 1 + ); + + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + return RTEMS_SUCCESSFUL; +} + +/* + * Non-blocking char input + */ +bool char_ready(int port, char *ch) +{ + if ( Ring_buffer_Is_empty( &Console_Buffer[port] ) ) + return false; + + Ring_buffer_Remove_character( &Console_Buffer[port], *ch ); + + return true; +} + +/* + * Block on char input + */ +static char inbyte(int port) +{ + char tmp_char; + + while ( !char_ready(port, &tmp_char) ); + return tmp_char; +} + +/* + * This routine transmits a character out the SCC. It no longer supports + * XON/XOFF flow control. + */ +static void outbyte(char ch, int port) +{ + while (1) { + if (ZREAD0(port) & TX_BUFFER_EMPTY) break; + } + ZWRITED(port, ch); +} + +/* + * Open entry point + */ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * Close entry point + */ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * read bytes from the serial port. We only have stdin. + */ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args; + char *buffer; + int maximum; + int count = 0; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + if ( minor > 1 ) + return RTEMS_INVALID_NUMBER; + + for (count = 0; count < maximum; count++) { + buffer[ count ] = inbyte( minor ); + if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { + buffer[ count++ ] = '\n'; + break; + } + } + + rw_args->bytes_moved = count; + return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; +} + +/* + * write bytes to the serial port. Stdout and stderr are the same. + */ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + int count; + int maximum; + rtems_libio_rw_args_t *rw_args; + char *buffer; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + if ( minor > 1 ) + return RTEMS_INVALID_NUMBER; + + for (count = 0; count < maximum; count++) { + if ( buffer[ count ] == '\n') { + outbyte('\r', minor ); + } + outbyte( buffer[ count ], minor ); + } + + rw_args->bytes_moved = maximum; + return 0; +} + +/* + * IO Control entry point + */ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * _162Bug_output_char + * + * Output a single character using the 162Bug functions. The character + * will be written to the default output port. + */ +static void _162Bug_output_char( char c ) +{ + asm volatile( "moveb %0, -(%%sp)\n\t" /* char to output */ + "trap #15\n\t" /* Trap to 162Bug */ + ".short 0x20" /* Code for .OUTCHR */ + :: "d" (c) ); +} + +/* + * _BSP_output_char + * + * printk() function prototyped in bspIo.h. Does not use termios. + * + * If we have initialized the console device then use it, otherwise + * use the 162Bug routines to send it to the default output port. + */ +static void _BSP_output_char(char c) +{ + _162Bug_output_char(c); +} + +/* Printk function */ +BSP_output_char_function_type BSP_output_char = _BSP_output_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/m68k/mvme167/console/console-recording.h b/bsps/m68k/mvme167/console/console-recording.h new file mode 100644 index 0000000000..4d8d3fc66c --- /dev/null +++ b/bsps/m68k/mvme167/console/console-recording.h @@ -0,0 +1,572 @@ +/* + * Copyright (c) 2000, National Research Council of Canada + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +/* CD2401 CONSOLE DRIVER DEBUG INFO RECORDING */ + +#ifdef CD2401_RECORD_DEBUG_INFO + +/* Control individual recording here. That way, we don't clutter console.c */ +#define CD2401_RECORD_WRITE +#define CD2401_RECORD_TX_ISR +#define CD2401_RECORD_RX_ISR +#define CD2401_RECORD_RE_ISR +#define CD2401_RECORD_MODEM_ISR +#define CD2401_RECORD_SET_ATTRIBUTE +#define CD2401_RECORD_FIRST_OPEN +#define CD2401_RECORD_LAST_CLOSE +#define CD2401_RECORD_START_REMOTE_TX +#define CD2401_RECORD_STOP_REMOTE_TX +#define CD2401_RECORD_DRAIN_OUTPUT +#define CD2401_RECORD_DELAY + +/* Call the data recording functions */ +#ifdef CD2401_RECORD_WRITE +#define CD2401_RECORD_WRITE_INFO( args ) cd2401_record_write_info args +#else +#define CD2401_RECORD_WRITE_INFO( args ) +#endif + +#ifdef CD2401_RECORD_TX_ISR +#define CD2401_RECORD_TX_ISR_INFO( args ) cd2401_record_tx_isr_info args +#define CD2401_RECORD_TX_ISR_SPURIOUS_INFO( args ) cd2401_record_tx_isr_spurious_info args +#define CD2401_RECORD_TX_ISR_BUSERR_INFO( args ) cd2401_record_tx_isr_buserr_info args +#else +#define CD2401_RECORD_TX_ISR_INFO( args ) +#define CD2401_RECORD_TX_ISR_SPURIOUS_INFO( args ) +#define CD2401_RECORD_TX_ISR_BUSERR_INFO( args ) +#endif + +#ifdef CD2401_RECORD_RX_ISR +#define CD2401_RECORD_RX_ISR_INFO( args ) cd2401_record_rx_isr_info args +#define CD2401_RECORD_RX_ISR_SPURIOUS_INFO( args ) cd2401_record_rx_isr_spurious_info args +#else +#define CD2401_RECORD_RX_ISR_INFO( args ) +#define CD2401_RECORD_RX_ISR_SPURIOUS_INFO( args ) +#endif + +#ifdef CD2401_RECORD_RE_ISR +#define CD2401_RECORD_RE_ISR_SPURIOUS_INFO( args ) cd2401_record_re_isr_spurious_info args +#else +#define CD2401_RECORD_RE_ISR_SPURIOUS_INFO( args ) +#endif + +#ifdef CD2401_RECORD_MODEM_ISR +#define CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO( args ) cd2401_record_modem_isr_spurious_info args +#else +#define CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO( args ) +#endif + +#ifdef CD2401_RECORD_SET_ATTRIBUTES +#define CD2401_RECORD_SET_ATTRIBUTES_INFO( args ) cd2401_record_set_attributes_info args +#else +#define CD2401_RECORD_SET_ATTRIBUTES_INFO( args ) +#endif + +#ifdef CD2401_RECORD_FIRST_OPEN +#define CD2401_RECORD_FIRST_OPEN_INFO( args ) cd2401_record_first_open_info args +#else +#define CD2401_RECORD_FIRST_OPEN_INFO( args ) +#endif + +#ifdef CD2401_RECORD_LAST_CLOSE +#define CD2401_RECORD_LAST_CLOSE_INFO( args ) cd2401_record_last_close_info args +#else +#define CD2401_RECORD_LAST_CLOSE_INFO( args ) +#endif + +#ifdef CD2401_RECORD_START_REMOTE_TX +#define CD2401_RECORD_START_REMOTE_TX_INFO( args ) cd2401_record_start_remote_tx_info args +#else +#define CD2401_RECORD_START_REMOTE_TX_INFO( args ) +#endif + +#ifdef CD2401_RECORD_STOP_REMOTE_TX +#define CD2401_RECORD_STOP_REMOTE_TX_INFO( args ) cd2401_record_stop_remote_tx_info args +#else +#define CD2401_RECORD_STOP_REMOTE_TX_INFO( args ) +#endif + +#ifdef CD2401_RECORD_DRAIN_OUTPUT +#define CD2401_RECORD_DRAIN_OUTPUT_INFO( args ) cd2401_record_drain_output_info args +#else +#define CD2401_RECORD_DRAIN_OUTPUT_INFO( args ) +#endif + +#ifdef CD2401_RECORD_DELAY +#define CD2401_RECORD_DELAY_INFO( args ) cd2401_record_delay_info args +#else +#define CD2401_RECORD_DELAY_INFO( args ) +#endif + +/* Define the data and the recording functions */ +#define CD2401_DEBUG_BUFFER_SIZE 256 +#define CD2401_DEBUG_CHAR_BUFSIZE 64 +#define CD2401_WRITE_INFO 1 +#define CD2401_TX_ISR_INFO 2 +#define CD2401_TX_ISR_SPURIOUS_INFO 3 +#define CD2401_TX_ISR_BUSERR_INFO 4 +#define CD2401_RX_ISR_INFO 5 +#define CD2401_RX_ISR_SPURIOUS_INFO 6 +#define CD2401_RE_ISR_SPURIOUS_INFO 7 +#define CD2401_MODEM_ISR_SPURIOUS_INFO 8 +#define CD2401_FIRST_OPEN_INFO 9 +#define CD2401_LAST_CLOSE_INFO 10 +#define CD2401_START_REMOTE_TX_INFO 11 +#define CD2401_STOP_REMOTE_TX_INFO 12 +#define CD2401_SET_ATTRIBUTE_INFO 13 +#define CD2401_DRAIN_OUTPUT_INFO 14 +#define CD2401_DELAY_INFO 15 + +struct cd2401_debug_info { + short discriminant; + short record_size; + union { + struct cd2401_write_info { + int length; + char buffer[CD2401_DEBUG_CHAR_BUFSIZE]; + char dmabuf; + } write_info; + struct cd2401_tx_isr_info { + unsigned char channel; + unsigned char status; + unsigned char initial_ier; + unsigned char final_ier; + uint8_t txEmpty; + } tx_isr_info; + struct cd2401_tx_isr_spurious_info { + unsigned char channel; + unsigned char status; + unsigned char initial_ier; + unsigned char final_ier; + unsigned long spurdev; + unsigned long spurcount; + } tx_isr_spurious_info; + struct cd2401_tx_isr_buserr_info { + unsigned char channel; + unsigned char status; + unsigned char initial_ier; + unsigned char buserr; + unsigned long type; + unsigned long addr; + } tx_isr_buserr_info; + struct cd2401_rx_isr_info { + unsigned char channel; + int length; + char buffer[CD2401_DEBUG_CHAR_BUFSIZE]; + } rx_isr_info; + struct cd2401_rx_isr_spurious_info { + unsigned char channel; + unsigned char status; + unsigned long spurdev; + unsigned long spurcount; + } rx_isr_spurious_info; + struct cd2401_re_isr_spurious_info { + unsigned char channel; + unsigned long spurdev; + unsigned long spurcount; + } re_isr_spurious_info; + struct cd2401_modem_isr_spurious_info { + unsigned char channel; + unsigned long spurdev; + unsigned long spurcount; + } modem_isr_spurious_info; + struct cd2401_first_open_info { + unsigned char channel; + uint8_t init_count; + } first_open_info; + struct cd2401_last_close_info { + unsigned char channel; + uint8_t init_count; + } last_close_info; + struct cd2401_start_remote_tx_info { + unsigned char channel; + } start_remote_tx_info; + struct cd2401_stop_remote_tx_info { + unsigned char channel; + } stop_remote_tx_info; + struct cd2401_set_attribute_info { + int minor; + uint8_t need_reinit; + uint8_t txEmpty; + uint8_t csize; + uint8_t cstopb; + uint8_t parodd; + uint8_t parenb; + uint8_t ignpar; + uint8_t inpck; + uint8_t hw_flow_ctl; + uint8_t sw_flow_ctl; + uint8_t extra_flow_ctl; + uint8_t icrnl; + uint8_t igncr; + uint8_t inlcr; + uint8_t brkint; + uint8_t ignbrk; + uint8_t parmrk; + uint8_t istrip; + uint16_t tx_period; + uint16_t rx_period; + uint32_t out_baud; + uint32_t in_baud; + } set_attribute_info; + struct cd2401_drain_output_info { + uint8_t txEmpty; + uint8_t own_buf_A; + uint8_t own_buf_B; + } drain_output_info; + struct cd2401_delay_info { + rtems_interval start; + rtems_interval end; + rtems_interval current; + unsigned long loop_count; + } delay_info; + } u; +}; + +struct cd2401_debug_info cd2401_debug_buffer[CD2401_DEBUG_BUFFER_SIZE]; +int cd2401_debug_index = 0; + +#include + +int cd2401_get_record_size( + int size +) +{ + /* Not the best way to do this */ + return size + 4; +} + +void cd2401_record_write_info( + int len, + const char * buf, + char dmabuf +) +{ + int max_length; + + max_length = (len < CD2401_DEBUG_CHAR_BUFSIZE ) ? len : CD2401_DEBUG_CHAR_BUFSIZE; + + memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); + cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_WRITE_INFO; + cd2401_debug_buffer[cd2401_debug_index].record_size = + cd2401_get_record_size( sizeof( struct cd2401_write_info ) ); + cd2401_debug_buffer[cd2401_debug_index].u.write_info.length = len; + memcpy ( &(cd2401_debug_buffer[cd2401_debug_index].u.write_info.buffer), buf, max_length ); + cd2401_debug_buffer[cd2401_debug_index].u.write_info.dmabuf = dmabuf; + + cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; +} + +void cd2401_record_tx_isr_info( + unsigned char ch, + unsigned char status, + unsigned char initial_ier, + unsigned char final_ier, + uint8_t txEmpty +) +{ + memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); + cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_TX_ISR_INFO; + cd2401_debug_buffer[cd2401_debug_index].record_size = + cd2401_get_record_size( sizeof( struct cd2401_tx_isr_info ) ); + cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.channel = ch; + cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.status = status; + cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.initial_ier = initial_ier; + cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.final_ier = final_ier; + cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.txEmpty = txEmpty; + + cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; +} + +void cd2401_record_tx_isr_spurious_info( + unsigned char ch, + unsigned char status, + unsigned char initial_ier, + unsigned char final_ier, + unsigned char spur_dev, + unsigned char spur_cnt +) +{ + memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); + cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_TX_ISR_SPURIOUS_INFO; + cd2401_debug_buffer[cd2401_debug_index].record_size = + cd2401_get_record_size( sizeof( struct cd2401_tx_isr_spurious_info ) ); + cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.channel = ch; + cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.status = status; + cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.initial_ier = initial_ier; + cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.final_ier = final_ier; + cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.spurdev = spur_dev; + cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.spurcount = spur_cnt; + + cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; +} + +void cd2401_record_tx_isr_buserr_info( + unsigned char ch, + unsigned char status, + unsigned char initial_ier, + unsigned char buserr, + unsigned long buserr_type, + unsigned long buserr_addr +) +{ + memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); + cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_TX_ISR_BUSERR_INFO; + cd2401_debug_buffer[cd2401_debug_index].record_size = + cd2401_get_record_size( sizeof( struct cd2401_tx_isr_buserr_info ) ); + cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.channel = ch; + cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.status = status; + cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.initial_ier = initial_ier; + cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.buserr = buserr; + cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.type = buserr_type; + cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.addr = buserr_addr; + + cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; +} + +void cd2401_record_rx_isr_info( + unsigned char ch, + unsigned char total, + char * buffer +) +{ + int max_length; + + max_length = (total < CD2401_DEBUG_CHAR_BUFSIZE ) ? total : CD2401_DEBUG_CHAR_BUFSIZE; + + memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); + cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_RX_ISR_INFO; + cd2401_debug_buffer[cd2401_debug_index].record_size = + cd2401_get_record_size( sizeof( struct cd2401_rx_isr_info ) ); + cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_info.length = max_length; + memcpy ( &(cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_info.buffer), buffer, max_length ); + + cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; +} + +void cd2401_record_rx_isr_spurious_info( + unsigned char ch, + unsigned char status, + uint32_t spur_dev, + uint32_t spur_cnt +) +{ + memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); + cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_RX_ISR_SPURIOUS_INFO; + cd2401_debug_buffer[cd2401_debug_index].record_size = + cd2401_get_record_size( sizeof( struct cd2401_rx_isr_spurious_info ) ); + cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.channel = ch; + cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.status = status; + cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.spurdev = spur_dev; + cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.spurcount = spur_cnt; + + cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; +} + +void cd2401_record_re_isr_spurious_info( + unsigned char ch, + uint32_t spur_dev, + uint32_t spur_cnt +) +{ + memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); + cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_RE_ISR_SPURIOUS_INFO; + cd2401_debug_buffer[cd2401_debug_index].record_size = + cd2401_get_record_size( sizeof( struct cd2401_re_isr_spurious_info ) ); + cd2401_debug_buffer[cd2401_debug_index].u.re_isr_spurious_info.channel = ch; + cd2401_debug_buffer[cd2401_debug_index].u.re_isr_spurious_info.spurdev = spur_dev; + cd2401_debug_buffer[cd2401_debug_index].u.re_isr_spurious_info.spurcount = spur_cnt; + + cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; +} + +void cd2401_record_modem_isr_spurious_info( + unsigned char ch, + uint32_t spur_dev, + uint32_t spur_cnt +) +{ + memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); + cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_MODEM_ISR_SPURIOUS_INFO; + cd2401_debug_buffer[cd2401_debug_index].record_size = + cd2401_get_record_size( sizeof( struct cd2401_modem_isr_spurious_info ) ); + cd2401_debug_buffer[cd2401_debug_index].u.modem_isr_spurious_info.channel = ch; + cd2401_debug_buffer[cd2401_debug_index].u.modem_isr_spurious_info.spurdev = spur_dev; + cd2401_debug_buffer[cd2401_debug_index].u.modem_isr_spurious_info.spurcount = spur_cnt; + + cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; +} + +void cd2401_record_first_open_info( + unsigned char ch, + uint8_t init_count +) +{ + memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); + cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_FIRST_OPEN_INFO; + cd2401_debug_buffer[cd2401_debug_index].record_size = + cd2401_get_record_size( sizeof( struct cd2401_first_open_info ) ); + cd2401_debug_buffer[cd2401_debug_index].u.first_open_info.channel = ch; + cd2401_debug_buffer[cd2401_debug_index].u.first_open_info.init_count = init_count; + + cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; +} + +void cd2401_record_last_close_info( + unsigned char ch, + uint8_t init_count +) +{ + memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); + cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_LAST_CLOSE_INFO; + cd2401_debug_buffer[cd2401_debug_index].record_size = + cd2401_get_record_size( sizeof( struct cd2401_last_close_info ) ); + cd2401_debug_buffer[cd2401_debug_index].u.last_close_info.channel = ch; + cd2401_debug_buffer[cd2401_debug_index].u.last_close_info.init_count = init_count; + + cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; +} + +void cd2401_record_start_remote_tx_info( + unsigned char ch +) +{ + memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); + cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_START_REMOTE_TX_INFO; + cd2401_debug_buffer[cd2401_debug_index].record_size = + cd2401_get_record_size( sizeof( struct cd2401_start_remote_tx_info ) ); + cd2401_debug_buffer[cd2401_debug_index].u.start_remote_tx_info.channel = ch; + + cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; +} + +void cd2401_record_stop_remote_tx_info( + unsigned char ch +) +{ + memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); + cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_STOP_REMOTE_TX_INFO; + cd2401_debug_buffer[cd2401_debug_index].record_size = + cd2401_get_record_size( sizeof( struct cd2401_stop_remote_tx_info ) ); + cd2401_debug_buffer[cd2401_debug_index].u.stop_remote_tx_info.channel = ch; + + cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; +} + +void cd2401_record_set_attributes_info( + int minor, + uint8_t need_reinit, + uint8_t csize, + uint8_t cstopb, + uint8_t parodd, + uint8_t parenb, + uint8_t ignpar, + uint8_t inpck, + uint8_t hw_flow_ctl, + uint8_t sw_flow_ctl, + uint8_t extra_flow_ctl, + uint8_t icrnl, + uint8_t igncr, + uint8_t inlcr, + uint8_t brkint, + uint8_t ignbrk, + uint8_t parmrk, + uint8_t istrip, + uint16_t tx_period, + uint16_t rx_period, + uint32_t out_baud, + uint32_t in_baud +) +{ + memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); + cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_SET_ATTRIBUTE_INFO; + cd2401_debug_buffer[cd2401_debug_index].record_size = + cd2401_get_record_size( sizeof( struct cd2401_set_attribute_info ) ); + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.minor = minor; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.need_reinit = need_reinit; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.txEmpty = CD2401_Channel_Info[minor].txEmpty; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.csize = csize; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.cstopb = cstopb; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.parodd = parodd; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.parenb = parenb; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.ignpar = ignpar; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.inpck = inpck; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.hw_flow_ctl = hw_flow_ctl; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.sw_flow_ctl = sw_flow_ctl; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.extra_flow_ctl = extra_flow_ctl; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.icrnl = icrnl; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.igncr = igncr; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.inlcr = inlcr; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.brkint = brkint; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.ignbrk = ignbrk; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.parmrk = parmrk; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.istrip = istrip; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.tx_period = tx_period; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.rx_period = rx_period; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.out_baud = out_baud; + cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.in_baud = in_baud; + + cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; +} + +void cd2401_record_drain_output_info( + uint8_t txEmpty, + uint8_t own_buf_A, + uint8_t own_buf_B +) +{ + memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); + cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_DRAIN_OUTPUT_INFO; + cd2401_debug_buffer[cd2401_debug_index].record_size = + cd2401_get_record_size( sizeof( struct cd2401_drain_output_info ) ); + cd2401_debug_buffer[cd2401_debug_index].u.drain_output_info.txEmpty = txEmpty; + cd2401_debug_buffer[cd2401_debug_index].u.drain_output_info.own_buf_A = own_buf_A; + cd2401_debug_buffer[cd2401_debug_index].u.drain_output_info.own_buf_B = own_buf_B; + + cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; +} + +void cd2401_record_delay_info( + rtems_interval start, + rtems_interval end, + rtems_interval current, + unsigned long loop_count +) +{ + memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); + cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_DELAY_INFO; + cd2401_debug_buffer[cd2401_debug_index].record_size = + cd2401_get_record_size( sizeof( struct cd2401_delay_info ) ); + cd2401_debug_buffer[cd2401_debug_index].u.delay_info.start = start; + cd2401_debug_buffer[cd2401_debug_index].u.delay_info.end = end; + cd2401_debug_buffer[cd2401_debug_index].u.delay_info.current = current; + cd2401_debug_buffer[cd2401_debug_index].u.delay_info.loop_count = loop_count; + + cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; +} + +#else + +/* Do not call the data recording functions */ +#define CD2401_RECORD_WRITE_INFO( args ) +#define CD2401_RECORD_TX_ISR_INFO( args ) +#define CD2401_RECORD_TX_ISR_SPURIOUS_INFO( args ) +#define CD2401_RECORD_TX_ISR_BUSERR_INFO( args ) +#define CD2401_RECORD_RX_ISR_INFO( args ) +#define CD2401_RECORD_RX_ISR_SPURIOUS_INFO( args ) +#define CD2401_RECORD_RE_ISR_SPURIOUS_INFO( args ) +#define CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO( args ) +#define CD2401_RECORD_FIRST_OPEN_INFO( args ) +#define CD2401_RECORD_LAST_CLOSE_INFO( args ) +#define CD2401_RECORD_START_REMOTE_TX_INFO( args ) +#define CD2401_RECORD_STOP_REMOTE_TX_INFO( args ) +#define CD2401_RECORD_SET_ATTRIBUTES_INFO( args ) +#define CD2401_RECORD_DRAIN_OUTPUT_INFO( args ) +#define CD2401_RECORD_DELAY_INFO( args ) + +#endif diff --git a/bsps/m68k/mvme167/console/console.c b/bsps/m68k/mvme167/console/console.c new file mode 100644 index 0000000000..0499ac46b3 --- /dev/null +++ b/bsps/m68k/mvme167/console/console.c @@ -0,0 +1,1676 @@ +/* + * This file contains the MVME167 termios console package. Only asynchronous + * I/O is supported. + * + * /dev/tty0 is channel 0, Serial Port 1/Console on the MVME712M. + * /dev/tty1 is channel 1, Serial Port 2/TTY01 on the MVME712M. + * /dev/tty2 is channel 2, Serial Port 3 on the MVME712M. + * /dev/tty3 is channel 3, Serial Port 4 on the MVME712M. + * + * Normal I/O uses DMA for output, interrupts for input. /dev/console is + * fixed to be /dev/tty01, Serial Port 2. Very limited support is provided + * for polled I/O. Polled I/O is intended only for running the RTEMS test + * suites. In all cases, Serial Port 1/Console is allocated to 167Bug and + * is the dedicated debugger port. We configure GDB to use 167Bug for + * debugging. When debugging with GDB or 167Bug, do not open /dev/tty00. + * + * Modern I/O chips often contain a number of I/O devices that can operate + * almost independently of each other. Typically, in RTEMS, all devices in + * an I/O chip are handled by a single device driver, but that need not be + * always the case. Each device driver must supply six entry points in the + * Device Driver Table: a device initialization function, as well as an open, + * close, read, write and a control function. RTEMS assigns a device major + * number to each device driver. This major device number is the index of the + * device driver entries in the Device Driver Table, and it used to identify + * a particular device driver. To distinguish multiple I/O sub-devices within + * an I/O chip, RTEMS supports device minor numbers. When a I/O device is + * initialized, the major number is supplied to the initialization function. + * That function must register each sub-device with a separate name and minor + * number (as well as the supplied major number). When an application opens a + * device by name, the corresponding major and minor numbers are returned to + * the caller to be used in subsequent I/O operations (although these details + * are typically hidden within the library functions). + * + * Such a scheme recognizes that the initialization of the individual + * sub-devices is generally not completely independent. For example, the + * four serial ports of the CD2401 can be configured almost independently + * from each other. One port could be configured to operate in asynchronous + * mode with interrupt-driven I/O, while another port could be configured to + * operate in HDLC mode with DMA I/O. However, a device reset command will + * reset all four channels, and the width of DMA transfers and the number of + * retries following bus errors selected applies to all four channels. + * Consequently, when initializing one channel, one must be careful not to + * destroy the configuration of other channels that are already configured. + * + * One problem with the RTEMS I/O initialization model is that no information + * other than a device major number is passed to the initialization function. + * Consequently, the sub-devices must be initialized with some pre-determined + * configuration. To change the configuration of a sub-device, it is + * necessary to either rewrite the initialization function, or to make a + * series of rtems_io_control() calls after initialization. The first + * approach is not very elegant. The second approach is acceptable if an + * application is simply changing baud rates, parity or other such + * asynchronous parameters (as supplied by the termios package). But what if + * an application requires one channel to run in HDLC or Bisync mode and + * another in async mode? With a single driver per I/O chip approach, the + * device driver must support multiple protocols. This is feasible, but it + * often means that an application that only does asynchronous I/O now links + * in code for other unused protocols, thus wasting precious ROM space. + * Worse, it requires that the sub-devices be initialized in some + * configuration, and that configuration then changed through a series of + * device driver control calls. There is no standard API in RTEMS to switch + * a serial line to some synchronous protocol. + * + * A better approach is to treat each channel as a separate device, each with + * its own device device driver. The application then supplies its own device + * driver table with only the required protocols (drivers) on each line. The + * problem with this approach is that the device drivers are not really + * independent, given that the I/O sub-devices within a common chip are not + * independent themselves. Consequently, the related device drivers must + * share some information. In RTEMS, there is no standard location in which + * to share information. + * + * This driver handles all four channels, i.e. it distinguishes the + * sub-devices using minor device numbers. Only asynchronous I/O is + * supported. The console is currently fixed to be channel 1 on the CD2401, + * which corresponds to the TTY01 port (Serial Port 2) on the MVME712M + * Transition Module. + * + * The CD2401 does either interrupt-driven or DMA I/O; it does not support + * polling. In interrupt-driven or DMA I/O modes, interrupts from the CD2401 + * are routed to the MC68040, and the processor generates an interrupt + * acknowledge cycle directly to the CD2401 to obtain an interrupt vector. + * The PCCchip2 supports a pseudo-polling mode in which interrupts from the + * CD2401 are not routed to the MC68040, but can be detected by the processor + * by reading the appropriate CD2401 registers. In this mode, interrupt + * acknowledge cycles must be generated to the CD2401 by reading the + * appropriate PCCchip2 registers. + * + * Interrupts from the four channels cannot be routed independently; either + * all channels are used in the pseudo-polling mode, or all channels are used + * in interrupt-driven/DMA mode. There is no advantage in using the speudo- + * polling mode. Consenquently, this driver performs DMA input and output. + * Output is performed directly from the termios raw output buffer, while + * input is accumulated into a separate buffer. + * + * THIS MODULE IS NOT RE-ENTRANT! Simultaneous access to a device from + * multiple tasks is likely to cause significant problems! Concurrency + * control is implemented in the termios package. + * + * THE INTERRUPT LEVEL IS SET TO 1 FOR ALL CHANNELS. + * If the CD2401 is to be used for high speed synchronous serial I/O, the + * interrupt priority might need to be increased. + * + * ALL INTERRUPT HANDLERS ARE SHARED. + * When adding extra device drivers, either rewrite the interrupt handlers + * to demultiplex the interrupts, or install separate vectors. Common vectors + * are currently used to catch spurious interrupts. We could already have + * installed separate vectors for each channel and used the spurious + * interrupt handler defined in some other BSPs, but handling spurious + * interrupts from the CD2401 in this device driver allows us to record more + * information on the source of the interrupts. Furthermore, we have observed + * the occasional spurious interrupt from channel 0. We definitely do not + * to call a debugger for those. + * + * All page references are to the MVME166/MVME167/MVME187 Single Board + * Computer Programmer's Reference Guide (MVME187PG/D2) with the April + * 1993 supplements/addenda (MVME187PG/D2A1). + */ + +/* + * Copyright (c) 1998, National Research Council of Canada + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#define M167_INIT + +#include +#include +#include + +#include +#include +#include +#include /* Must be before libio.h */ + +/* Utility functions */ +void cd2401_udelay( unsigned long delay ); +void cd2401_chan_cmd( uint8_t channel, uint8_t cmd, uint8_t wait ); +uint16_t cd2401_bitrate_divisor( uint32_t clkrate, uint32_t * bitrate ); +void cd2401_initialize( void ); +void cd2401_interrupts_initialize( bool enable ); + +/* ISRs */ +rtems_isr cd2401_modem_isr( rtems_vector_number vector ); +rtems_isr cd2401_re_isr( rtems_vector_number vector ); +rtems_isr cd2401_rx_isr( rtems_vector_number vector ); +rtems_isr cd2401_tx_isr( rtems_vector_number vector ); + +/* Termios callbacks */ +int cd2401_firstOpen( int major, int minor, void *arg ); +int cd2401_lastClose( int major, int minor, void *arg ); +int cd2401_setAttributes( int minor, const struct termios *t ); +int cd2401_startRemoteTx( int minor ); +int cd2401_stopRemoteTx( int minor ); +ssize_t cd2401_write( int minor, const char *buf, size_t len ); +int cd2401_drainOutput( int minor ); +int _167Bug_pollRead( int minor ); +ssize_t _167Bug_pollWrite( int minor, const char *buf, size_t len ); + +/* Printk function */ +static void _BSP_output_char( char c ); +BSP_output_char_function_type BSP_output_char = _BSP_output_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; + +/* '\r' character in memory. This used to live on + * the stack but storing the '\r' character is + * optimized away by gcc-4.3.2 (since it seems to + * be unused [only referenced from inline assembly + * code in _167Bug_pollWrite()]). + * Hence we make it a global constant. + */ +static const char cr_char = '\r'; + +/* Channel info */ +/* static */ volatile struct { + void *tty; /* Really a struct rtems_termios_tty * */ + int len; /* Record nb of chars being TX'ed */ + const char *buf; /* Record where DMA is coming from */ + uint32_t spur_cnt; /* Nb of spurious ints so far */ + uint32_t spur_dev; /* Indo on last spurious int */ + uint32_t buserr_addr; /* Faulting address */ + uint32_t buserr_type; /* Reason of bus error during DMA */ + uint8_t own_buf_A; /* If true, buffer A belongs to the driver */ + uint8_t own_buf_B; /* If true, buffer B belongs to the driver */ + uint8_t txEmpty; /* If true, the output FIFO should be empty */ +} CD2401_Channel_Info[4]; + +/* + * The number of channels already opened. If zero, enable the interrupts. The + * initial value must be 0. If initialized explicitly, the variable ends up + * in the .data section. Its value is not re-initialized on system restart. + * Furthermore, because the variable is changed, the .data section would not + * be ROMable. We thus leave the variable uninitialized, which causes it to + * be allocated in the .bss section, and rely on RTEMS to zero the .bss + * section on every startup. + */ +uint8_t Init_count; + +/* Record previous handlers */ +rtems_isr_entry Prev_re_isr; /* Previous rx exception isr */ +rtems_isr_entry Prev_rx_isr; /* Previous rx isr */ +rtems_isr_entry Prev_tx_isr; /* Previous tx isr */ +rtems_isr_entry Prev_modem_isr; /* Previous modem/timer isr */ + +/* Define the following symbol to trace the calls to this driver */ +/* #define CD2401_RECORD_DEBUG_INFO */ +#include "console-recording.h" + +/* + * Utility functions. + */ + +/* + * Assumes that clock ticks 1 million times per second. + * + * MAXIMUM DELAY IS ABOUT 20 ms + * + * Input parameters: + * delay: Number of microseconds to delay. + * + * Output parameters: NONE + * + * Return values: NONE + */ + void cd2401_udelay +( + unsigned long delay +) +{ + unsigned long i = 20000; /* In case clock is off */ + rtems_interval start_ticks, end_ticks, current_ticks; + + start_ticks = rtems_clock_get_ticks_since_boot(); + end_ticks = start_ticks + delay; + + do { + current_ticks = rtems_clock_get_ticks_since_boot(); + } while ( --i && (current_ticks <= end_ticks) ); + + CD2401_RECORD_DELAY_INFO(( start_ticks, end_ticks, current_ticks, i )); +} + +/* + * cd2401_chan_cmd + * + * Sends a CCR command to the specified channel. Waits for any unfinished + * previous command to complete, then sends the specified command. Optionally + * wait for the current command to finish before returning. + * + * Input parameters: + * channel - CD2401 channel number + * cmd - command byte + * wait - if non-zero, wait for specified command to complete before + * returning. + * + * Output parameters: NONE + * + * Return values: NONE + */ +void cd2401_chan_cmd( + uint8_t channel, + uint8_t cmd, + uint8_t wait +) +{ + if ( channel < 4 ) { + cd2401->car = channel; /* Select channel */ + + while ( cd2401->ccr != 0 ); /* Wait for completion of previous command */ + cd2401->ccr = cmd; /* Send command */ + if ( wait ) + while( cd2401->ccr != 0 );/* Wait for completion */ + } + else { + /* This may not be the best error message */ + rtems_fatal_error_occurred( RTEMS_INVALID_NUMBER ); + } +} + +/* + * cd2401_bitrate_divisor + * + * Compute the divisor and clock source to use to obtain the desired bitrate. + * + * Input parameters: + * clkrate - system clock rate (CLK input frequency) + * bitrate - the desired bitrate + * + * Output parameters: + * bitrate - The actual bitrate achievable, to the nearest bps. + * + * Return values: + * Returns divisor in lower byte and clock source in upper byte for the + * specified bitrate. + */ +uint16_t cd2401_bitrate_divisor( + uint32_t clkrate, + uint32_t * bitrate +) +{ + uint32_t divisor; + uint16_t clksource; + + divisor = *bitrate << 3; /* temporary; multiply by 8 for CLK/8 */ + divisor = (clkrate + (divisor>>1)) / divisor; /* divisor for clk0 (CLK/8) */ + + /* Use highest speed clock source for best precision - try clk0 to clk4 */ + for( clksource = 0; clksource < 0x0400 && divisor > 0x100; clksource += 0x0100 ) + divisor >>= 2; + divisor--; /* adjustment, see specs */ + if( divisor < 1 ) + divisor = 1; + else if( divisor > 0xFF ) + divisor = 0xFF; + *bitrate = clkrate / (1 << ((clksource >> 7)+3)) / (divisor+1); + return( clksource | divisor ); +} + +/* + * cd2401_initialize + * + * Initializes the CD2401 device. Individual channels on the chip are left in + * their default reset state, and should be subsequently configured. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: NONE + */ +void cd2401_initialize( void ) +{ + int i; + + for ( i = 3; i >= 0; i-- ) { + CD2401_Channel_Info[i].tty = NULL; + CD2401_Channel_Info[i].len = 0; + CD2401_Channel_Info[i].buf = NULL; + CD2401_Channel_Info[i].spur_cnt = 0; + CD2401_Channel_Info[i].spur_dev = 0; + CD2401_Channel_Info[i].buserr_type = 0; + CD2401_Channel_Info[i].buserr_addr = 0; + CD2401_Channel_Info[i].own_buf_A = TRUE; + CD2401_Channel_Info[i].own_buf_B = TRUE; + CD2401_Channel_Info[i].txEmpty = TRUE; + } + + /* + * Normally, do a device reset here. If we do it, we will most likely clober + * the port settings for 167Bug on channel 0. So we just shut up all the + * ports by disabling their interrupts. + */ +#if 0 + cd2401->gfrcr = 0; /* So we can detect that device init is done */ + cd2401_chan_cmd( 0x10, 0); /* Reset all */ + while(cd2401->gfrcr == 0); /* Wait for reset all */ +#endif + + /* + * The CL-CD2400/2401 manual (part no 542400-003) states on page 87 that + * the LICR "contains the number of the interrupting channel being served. + * The channel number is always that of the current acknowledged interrupt." + * THE USER MUST PROGRAM CHANNEL NUMBER IN LICR! It is not set automatically + * by the hardware, as suggested by the manual. + * + * The updated manual (part no 542400-007) has the story straight. The + * CD2401 automatically initializes the LICR to contain the channel number + * in bits 2 and 3. However, these bits are not preserved when the user + * defined bits are written. + * + * The same vector number is used for all four channels. Different vector + * numbers could be programmed for each channel, thus avoiding the need to + * demultiplex the interrupts in the ISR. + */ + for ( i = 0; i < 4; i++ ) { + cd2401->car = i; /* Select channel */ + cd2401->livr = 0x5C; /* Motorola suggested value p. 3-15 */ + cd2401->licr = i << 2; /* Don't rely on reset value */ + cd2401->ier = 0; /* Disable all interrupts */ + } + + /* + * The content of the CD2401 xpilr registers must match the A7-A0 addresses + * generated by the PCCchip2 during interrupt acknowledge cycles in order + * for the CD2401 to recognize the IACK cycle and clear its interrupt + * request. + */ + cd2401->mpilr = 0x01; /* Match pccchip2->modem_piack p. 3-27 */ + cd2401->tpilr = 0x02; /* Match pccchip2->tx_piack p. 3-28 */ + cd2401->rpilr = 0x03; /* Match pccchip2->rx_piack p. 3-29 */ + + /* Global CD2401 registers */ + cd2401->dmr = 0; /* 16-bit DMA transfers when possible */ + cd2401->bercnt = 0; /* Do not retry DMA upon bus errors */ + + /* + * Setup timer prescaler period, which clocks timers 1 and 2 (or rx timeout + * and tx delay). The prescaler is clocked by the system clock) / 2048. The + * register must be in the range 0x0A..0xFF, ie. a rescaler period range of + * about 1ms..26ms for a nominal system clock rate of 20MHz. + */ + cd2401->tpr = 0x0A; /* Same value as 167Bug */ +} + +/* + * cd2401_interrupts_initialize + * + * This routine enables or disables the CD2401 interrupts to the MC68040. + * Interrupts cannot be enabled/disabled on a per-channel basis. + * + * Input parameters: + * enable - if true, enable the interrupts, else disable them. + * + * Output parameters: NONE + * + * Return values: NONE + * + * THE FIRST CD2401 CHANNEL OPENED SHOULD ENABLE INTERRUPTS. + * THE LAST CD2401 CHANNEL CLOSED SHOULD DISABLE INTERRUPTS. + */ +void cd2401_interrupts_initialize( + bool enable +) +{ + if ( enable ) { + /* + * Enable interrupts from the CD2401 in the PCCchip2. + * During DMA transfers, the MC68040 supplies dirty data during read cycles + * from the CD2401 and leaves the data dirty in its data cache if there is + * a cache hit. The MC68040 updates the data cache during write cycles from + * the CD2401 if there is a cache hit. + */ + pccchip2->SCC_error = 0x01; + pccchip2->SCC_modem_int_ctl = 0x10 | CD2401_INT_LEVEL; + pccchip2->SCC_tx_int_ctl = 0x10 | CD2401_INT_LEVEL; + pccchip2->SCC_rx_int_ctl = 0x50 | CD2401_INT_LEVEL; + + pccchip2->gen_control |= 0x02; /* Enable pccchip2 interrupts */ + } + else { + /* Disable interrupts */ + pccchip2->SCC_modem_int_ctl &= 0xEF; + pccchip2->SCC_tx_int_ctl &= 0xEF; + pccchip2->SCC_rx_int_ctl &= 0xEF; + } +} + +/* ISRs */ + +/* + * cd2401_modem_isr + * + * Modem/timer interrupt (group 1) from CD2401. These are not used, and not + * expected. Record as spurious and clear. + * + * Input parameters: + * vector - vector number + * + * Output parameters: NONE + * + * Return values: NONE + */ +rtems_isr cd2401_modem_isr( + rtems_vector_number vector +) +{ + uint8_t ch; + + /* Get interrupting channel ID */ + ch = cd2401->licr >> 2; + + /* Record interrupt info for debugging */ + CD2401_Channel_Info[ch].spur_dev = + (vector << 24) | (cd2401->stk << 16) | (cd2401->mir << 8) | cd2401->misr; + CD2401_Channel_Info[ch].spur_cnt++; + + cd2401->meoir = 0; /* EOI */ + CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO(( ch, + CD2401_Channel_Info[ch].spur_dev, + CD2401_Channel_Info[ch].spur_cnt )); +} + +/* + * cd2401_re_isr + * + * RX exception interrupt (group 3, receiver exception) from CD2401. These are + * not used, and not expected. Record as spurious and clear. + * + * FIX THIS ISR TO DETECT BREAK CONDITIONS AND RAISE SIGINT + * + * Input parameters: + * vector - vector number + * + * Output parameters: NONE + * + * Return values: NONE + */ +rtems_isr cd2401_re_isr( + rtems_vector_number vector +) +{ + uint8_t ch; + + /* Get interrupting channel ID */ + ch = cd2401->licr >> 2; + + /* Record interrupt info for debugging */ + CD2401_Channel_Info[ch].spur_dev = + (vector << 24) | (cd2401->stk << 16) | (cd2401->rir << 8) | cd2401->u5.b.risrl; + CD2401_Channel_Info[ch].spur_cnt++; + + if ( cd2401->u5.b.risrl & 0x80 ) /* Timeout interrupt? */ + cd2401->ier &= 0xDF; /* Disable rx timeout interrupt */ + cd2401->reoir = 0x08; /* EOI; exception char not read */ + CD2401_RECORD_RE_ISR_SPURIOUS_INFO(( ch, + CD2401_Channel_Info[ch].spur_dev, + CD2401_Channel_Info[ch].spur_cnt )); +} + +/* + * cd2401_rx_isr + * + * RX interrupt (group 3, receiver data) from CD2401. + * + * Input parameters: + * vector - vector number + * + * Output parameters: NONE + * + * Return values: NONE + */ +rtems_isr cd2401_rx_isr( + rtems_vector_number vector +) +{ + char c; + uint8_t ch, status, nchars, total; + #ifdef CD2401_RECORD_DEBUG_INFO + uint8_t i = 0; + char buffer[256]; + #endif + + (void) total; /* avoid set but not used warnings when not recording info */ + + status = cd2401->u5.b.risrl; + ch = cd2401->licr >> 2; + + /* Has this channel been initialized or is it a condition we ignore? */ + if ( CD2401_Channel_Info[ch].tty && !status ) { + /* Normal Rx Int, read chars, enqueue them, and issue EOI */ + total = nchars = cd2401->rfoc; /* Nb of chars to retrieve from rx FIFO */ + while ( nchars-- > 0 ) { + c = (char)cd2401->dr; /* Next char in rx FIFO */ + rtems_termios_enqueue_raw_characters( CD2401_Channel_Info[ch].tty ,&c, 1 ); + #ifdef CD2401_RECORD_DEBUG_INFO + buffer[i++] = c; + #endif + } + cd2401->reoir = 0; /* EOI */ + CD2401_RECORD_RX_ISR_INFO(( ch, total, buffer )); + } else { + /* No, record as spurious interrupt */ + CD2401_Channel_Info[ch].spur_dev = + (vector << 24) | (cd2401->stk << 16) | (cd2401->rir << 8) | cd2401->u5.b.risrl; + CD2401_Channel_Info[ch].spur_cnt++; + cd2401->reoir = 0x04; /* EOI - character not read */ + CD2401_RECORD_RX_ISR_SPURIOUS_INFO(( ch, status, + CD2401_Channel_Info[ch].spur_dev, + CD2401_Channel_Info[ch].spur_cnt )); + } +} + +/* + * cd2401_tx_isr + * + * TX interrupt (group 2) from CD2401. + * + * Input parameters: + * vector - vector number + * + * Output parameters: NONE + * + * Return values: NONE + */ +rtems_isr cd2401_tx_isr( + rtems_vector_number vector +) +{ + uint8_t ch, status, buserr, initial_ier, final_ier; + + status = cd2401->tisr; + ch = cd2401->licr >> 2; + initial_ier = cd2401->ier; + + #ifndef CD2401_RECORD_DEBUG_INFO + /* + * When the debug is disabled, these variables are really not read. + * But when debug is enabled, they are. + */ + (void) initial_ier; /* avoid set but not used warning */ + (void) final_ier; /* avoid set but not used warning */ + #endif + + /* Has this channel been initialized? */ + if ( !CD2401_Channel_Info[ch].tty ) { + /* No, record as spurious interrupt */ + CD2401_Channel_Info[ch].spur_dev = + (vector << 24) | (cd2401->stk << 16) | (cd2401->tir << 8) | cd2401->tisr; + CD2401_Channel_Info[ch].spur_cnt++; + final_ier = cd2401->ier &= 0xFC;/* Shut up, whoever you are */ + + cd2401->teoir = 0x88; /* EOI - Terminate buffer and no transfer */ + CD2401_RECORD_TX_ISR_SPURIOUS_INFO(( ch, status, initial_ier, final_ier, + CD2401_Channel_Info[ch].spur_dev, + CD2401_Channel_Info[ch].spur_cnt )); + return; + } + + if ( status & 0x80 ) { + /* + * Bus error occurred during DMA transfer. For now, just record. + * Get reason for DMA bus error and clear the report for the next + * occurrence + */ + buserr = pccchip2->SCC_error; + pccchip2->SCC_error = 0x01; + CD2401_Channel_Info[ch].buserr_type = + (vector << 24) | (buserr << 16) | (cd2401->tir << 8) | cd2401->tisr; + CD2401_Channel_Info[ch].buserr_addr = + (((uint32_t)cd2401->tcbadru) << 16) | cd2401->tcbadrl; + + cd2401->teoir = 0x80; /* EOI - terminate bad buffer */ + CD2401_RECORD_TX_ISR_BUSERR_INFO(( ch, status, initial_ier, buserr, + CD2401_Channel_Info[ch].buserr_type, + CD2401_Channel_Info[ch].buserr_addr )); + return; + } + + if ( status & 0x20 ) { + /* DMA done -- Turn off TxD int, turn on TxMpty */ + final_ier = cd2401->ier = (cd2401->ier & 0xFE) | 0x02; + if( status & 0x08 ) { + /* Transmit buffer B was released */ + CD2401_Channel_Info[ch].own_buf_B = TRUE; + } + else { + /* Transmit buffer A was released */ + CD2401_Channel_Info[ch].own_buf_A = TRUE; + } + CD2401_RECORD_TX_ISR_INFO(( ch, status, initial_ier, final_ier, + CD2401_Channel_Info[ch].txEmpty )); + + /* This call can result in a call to cd2401_write() */ + rtems_termios_dequeue_characters ( + CD2401_Channel_Info[ch].tty, + CD2401_Channel_Info[ch].len ); + cd2401->teoir = 0x08; /* EOI - no data transfered */ + } + else if ( status & 0x02 ) { + /* TxEmpty */ + CD2401_Channel_Info[ch].txEmpty = TRUE; + final_ier = cd2401->ier &= 0xFD;/* Shut up the interrupts */ + cd2401->teoir = 0x08; /* EOI - no data transfered */ + CD2401_RECORD_TX_ISR_INFO(( ch, status, initial_ier, final_ier, + CD2401_Channel_Info[ch].txEmpty )); + } + else { + /* Why did we get a Tx interrupt? */ + CD2401_Channel_Info[ch].spur_dev = + (vector << 24) | (cd2401->stk << 16) | (cd2401->tir << 8) | cd2401->tisr; + CD2401_Channel_Info[ch].spur_cnt++; + cd2401->teoir = 0x08; /* EOI - no data transfered */ + CD2401_RECORD_TX_ISR_SPURIOUS_INFO(( ch, status, initial_ier, 0xFF, + CD2401_Channel_Info[ch].spur_dev, + CD2401_Channel_Info[ch].spur_cnt )); + } +} + +/* + * termios callbacks + */ + +/* + * cd2401_firstOpen + * + * This is the first time that this minor device (channel) is opened. + * Complete the asynchronous initialization. + * + * Input parameters: + * major - device major number + * minor - channel number + * arg - pointer to a struct rtems_libio_open_close_args_t + * + * Output parameters: NONE + * + * Return value: IGNORED + */ +int cd2401_firstOpen( + int major, + int minor, + void *arg +) +{ + rtems_libio_open_close_args_t *args = arg; + rtems_libio_ioctl_args_t newarg; + struct termios termios; + rtems_status_code sc; + rtems_interrupt_level level; + + rtems_interrupt_disable (level); + + /* + * Set up the line with the specified parameters. The difficulty is that + * the line parameters are stored in the struct termios field of a + * struct rtems_termios_tty that is not defined in a public header file. + * Therefore, we do not have direct access to the termios passed in with + * arg. So we make a rtems_termios_ioctl() call to get a pointer to the + * termios structure. + * + * THIS KLUDGE MAY BREAK IN THE FUTURE! + * + * We could have made a tcgetattr() call if we had our fd. + */ + newarg.iop = args->iop; + newarg.command = TIOCGETA; + newarg.buffer = &termios; + sc = rtems_termios_ioctl (&newarg); + if (sc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (sc); + + /* + * Turn off hardware flow control. It is a pain with 3-wire cables. + * The rtems_termios_ioctl() call below results in a call to + * cd2401_setAttributes to initialize the line. The caller will "wait" + * on the ttyMutex that it already owns; this is safe in RTEMS. + */ + termios.c_cflag |= CLOCAL; /* Ignore modem status lines */ + newarg.command = TIOCGETA; + sc = rtems_termios_ioctl (&newarg); + if (sc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (sc); + + /* Mark that the channel as initialized */ + CD2401_Channel_Info[minor].tty = args->iop->data1; + + /* If the first of the four channels to open, set up the interrupts */ + if ( !Init_count++ ) { + /* Install the interrupt handlers */ + Prev_re_isr = (rtems_isr_entry) set_vector( cd2401_re_isr, 0x5C, 1 ); + Prev_modem_isr = (rtems_isr_entry) set_vector( cd2401_modem_isr, 0x5D, 1 ); + Prev_tx_isr = (rtems_isr_entry) set_vector( cd2401_tx_isr, 0x5E, 1 ); + Prev_rx_isr = (rtems_isr_entry) set_vector( cd2401_rx_isr, 0x5F, 1 ); + + cd2401_interrupts_initialize( TRUE ); + } + + CD2401_RECORD_FIRST_OPEN_INFO(( minor, Init_count )); + + rtems_interrupt_enable (level); + + /* Return something */ + return RTEMS_SUCCESSFUL; +} + +/* + * cd2401_lastClose + * + * There are no more opened file descriptors to this device. Close it down. + * + * Input parameters: + * major - device major number + * minor - channel number + * arg - pointer to a struct rtems_libio_open_close_args_t + */ +int cd2401_lastClose( + int major, + int minor, + void *arg +) +{ + rtems_interrupt_level level; + + rtems_interrupt_disable (level); + + /* Mark that the channel is no longer is use */ + CD2401_Channel_Info[minor].tty = NULL; + + /* If the last of the four channels to close, disable the interrupts */ + if ( !--Init_count ) { + cd2401_interrupts_initialize( FALSE ); + + /* De-install the interrupt handlers */ + set_vector( Prev_re_isr, 0x5C, 1 ); + set_vector( Prev_modem_isr, 0x5D, 1 ); + set_vector( Prev_tx_isr, 0x5E, 1 ); + set_vector( Prev_rx_isr, 0x5F, 1 ); + } + + CD2401_RECORD_LAST_CLOSE_INFO(( minor, Init_count )); + + rtems_interrupt_enable (level); + + /* return something */ + return RTEMS_SUCCESSFUL; +} + +/* + * cd2401_setAttributes + * + * Set up the selected channel of the CD2401 chip for doing asynchronous + * I/O with DMA. + * + * The chip must already have been initialized by cd2401_initialize(). + * + * This code was written for clarity. The code space it occupies could be + * reduced. The code could also be compiled with aggressive optimization + * turned on. + * + * Input parameters: + * minor - the selected channel + * t - the termios parameters + * + * Output parameters: NONE + * + * Return value: IGNORED + */ +int cd2401_setAttributes( + int minor, + const struct termios *t +) +{ + uint8_t csize, cstopb, parodd, parenb, ignpar, inpck; + uint8_t hw_flow_ctl, sw_flow_ctl, extra_flow_ctl; + uint8_t icrnl, igncr, inlcr, brkint, ignbrk, parmrk, istrip; + uint8_t need_reinitialization = FALSE; + uint8_t read_enabled; + uint16_t tx_period, rx_period; + uint32_t out_baud, in_baud; + rtems_interrupt_level level; + + /* Determine what the line parameters should be */ + + /* baud rates */ + out_baud = rtems_termios_baud_to_number(t->c_ospeed); + in_baud = rtems_termios_baud_to_number(t->c_ispeed); + + /* Number of bits per char */ + csize = 0x07; /* to avoid a warning */ + switch ( t->c_cflag & CSIZE ) { + case CS5: csize = 0x04; break; + case CS6: csize = 0x05; break; + case CS7: csize = 0x06; break; + case CS8: csize = 0x07; break; + } + + /* Parity */ + if ( t->c_cflag & PARODD ) + parodd = 0x80; /* Odd parity */ + else + parodd = 0; + + if ( t->c_cflag & PARENB ) + parenb = 0x40; /* Parity enabled on Tx and Rx */ + else + parenb = 0x00; /* No parity on Tx and Rx */ + + /* CD2401 IGNPAR and INPCK bits are inverted wrt POSIX standard? */ + if ( t->c_iflag & INPCK ) + ignpar = 0; /* Check parity on input */ + else + ignpar = 0x10; /* Do not check parity on input */ + if ( t->c_iflag & IGNPAR ) { + inpck = 0x03; /* Discard error character */ + parmrk = 0; + } else { + if ( t->c_iflag & PARMRK ) { + inpck = 0x01; /* Translate to 0xFF 0x00 */ + parmrk = 0x04; + } else { + inpck = 0x01; /* Translate to 0x00 */ + parmrk = 0; + } + } + + /* Stop bits */ + if ( t->c_cflag & CSTOPB ) + cstopb = 0x04; /* Two stop bits */ + else + cstopb = 0x02; /* One stop bit */ + + /* Modem flow control */ + if ( t->c_cflag & CLOCAL ) + hw_flow_ctl = 0x04; /* Always assert RTS before Tx */ + else + hw_flow_ctl = 0x07; /* Always assert RTS before Tx, + wait for CTS and DSR */ + + /* XON/XOFF Tx flow control */ + if ( t->c_iflag & IXON ) { + sw_flow_ctl = 0x40; /* Tx in-band flow ctl enabled, wait for XON */ + extra_flow_ctl = 0x30; /* Eat XON/XOFF, XON/XOFF in SCHR1, SCHR2 */ + } + else { + sw_flow_ctl = 0; /* Tx in-band flow ctl disabled */ + extra_flow_ctl = 0; /* Pass on XON/XOFF */ + } + + /* CL/LF translation */ + if ( t->c_iflag & ICRNL ) + icrnl = 0x40; /* Map CR to NL on input */ + else + icrnl = 0; /* Pass on CR */ + if ( t->c_iflag & INLCR ) + inlcr = 0x20; /* Map NL to CR on input */ + else + inlcr = 0; /* Pass on NL */ + if ( t->c_iflag & IGNCR ) + igncr = 0x80; /* CR discarded on input */ + else + igncr = 0; + + /* Break handling */ + if ( t->c_iflag & IGNBRK ) { + ignbrk = 0x10; /* Ignore break on input */ + brkint = 0x08; + } else { + if ( t->c_iflag & BRKINT ) { + ignbrk = 0; /* Generate SIGINT (interrupt ) */ + brkint = 0; + } else { + ignbrk = 0; /* Convert to 0x00 */ + brkint = 0x08; + } + } + + /* Stripping */ + if ( t->c_iflag & ISTRIP ) + istrip = 0x80; /* Strip to 7 bits */ + else + istrip = 0; /* Leave as 8 bits */ + + rx_period = cd2401_bitrate_divisor( 20000000Ul, &in_baud ); + tx_period = cd2401_bitrate_divisor( 20000000Ul, &out_baud ); + + /* + * If this is the first time that the line characteristics are set up, then + * the device must be re-initialized. + * Also check if we need to change anything. It is preferable to not touch + * the device if nothing changes. As soon as we touch it, it tends to + * glitch. If anything changes, we reprogram all registers. This is + * harmless. + */ + if ( ( CD2401_Channel_Info[minor].tty == 0 ) || + ( cd2401->cor1 != (parodd | parenb | ignpar | csize) ) || + ( cd2401->cor2 != (sw_flow_ctl | hw_flow_ctl) ) || + ( cd2401->cor3 != (extra_flow_ctl | cstopb) ) || + ( cd2401->cor6 != (igncr | icrnl | inlcr | ignbrk | brkint | parmrk | inpck) ) || + ( cd2401->cor7 != istrip ) || + ( cd2401->u1.async.schr1 != t->c_cc[VSTART] ) || + ( cd2401->u1.async.schr2 != t->c_cc[VSTOP] ) || + ( cd2401->rbpr != (unsigned char)rx_period ) || + ( cd2401->rcor != (unsigned char)(rx_period >> 8) ) || + ( cd2401->tbpr != (unsigned char)tx_period ) || + ( cd2401->tcor != ( (tx_period >> 3) & 0xE0 ) ) ) + need_reinitialization = TRUE; + + /* Write to the ports */ + rtems_interrupt_disable (level); + + cd2401->car = minor; /* Select channel */ + read_enabled = cd2401->csr & 0x80 ? TRUE : FALSE; + + if ( (t->c_cflag & CREAD ? TRUE : FALSE ) != read_enabled ) { + /* Read enable status is changing */ + need_reinitialization = TRUE; + } + + if ( need_reinitialization ) { + /* + * Could not find a way to test whether the CD2401 was done transmitting. + * The TxEmpty interrupt does not seem to indicate that the FIFO is empty + * in DMA mode. So, just wait a while for output to drain. May not be + * enough, but it will have to do (should be long enough for 1 char at + * 9600 bsp)... + */ + cd2401_udelay( 2000L ); + + /* Clear channel */ + cd2401_chan_cmd (minor, 0x40, 1); + + cd2401->car = minor; /* Select channel */ + cd2401->cmr = 0x42; /* Interrupt Rx, DMA Tx, async mode */ + cd2401->cor1 = parodd | parenb | ignpar | csize; + cd2401->cor2 = sw_flow_ctl | hw_flow_ctl; + cd2401->cor3 = extra_flow_ctl | cstopb; + cd2401->cor4 = 0x0A; /* No DSR/DCD/CTS detect; FIFO threshold of 10 */ + cd2401->cor5 = 0x0A; /* No DSR/DCD/CTS detect; DTR threshold of 10 */ + cd2401->cor6 = igncr | icrnl | inlcr | ignbrk | brkint | parmrk | inpck; + cd2401->cor7 = istrip; /* No LNext; ignore XON/XOFF if frame error; no tx translations */ + /* Special char 1: XON character */ + cd2401->u1.async.schr1 = t->c_cc[VSTART]; + /* special char 2: XOFF character */ + cd2401->u1.async.schr2 = t->c_cc[VSTOP]; + + /* + * Special chars 3 and 4, char range, LNext, RFAR[1..4] and CRC + * are unused, left as is. + */ + + /* Set baudrates for receiver and transmitter */ + cd2401->rbpr = (unsigned char)rx_period; + cd2401->rcor = (unsigned char)(rx_period >> 8); /* no DPLL */ + cd2401->tbpr = (unsigned char)tx_period; + cd2401->tcor = (tx_period >> 3) & 0xE0; /* no x1 ext clk, no loopback */ + + /* Timeout for 4 chars at 9600, 8 bits per char, 1 stop bit */ + cd2401->u2.w.rtpr = 0x04; /* NEED TO LOOK AT THIS LINE! */ + + if ( t->c_cflag & CREAD ) { + /* Re-initialize channel, enable rx and tx */ + cd2401_chan_cmd (minor, 0x2A, 1); + /* Enable rx data ints */ + cd2401->ier = 0x08; + } else { + /* Re-initialize channel, enable tx, disable rx */ + cd2401_chan_cmd (minor, 0x29, 1); + } + } + + CD2401_RECORD_SET_ATTRIBUTES_INFO(( minor, need_reinitialization, csize, + cstopb, parodd, parenb, ignpar, inpck, + hw_flow_ctl, sw_flow_ctl, extra_flow_ctl, + icrnl, igncr, inlcr, brkint, ignbrk, + parmrk, istrip, tx_period, rx_period, + out_baud, in_baud )); + + rtems_interrupt_enable (level); + + /* + * Looks like the CD2401 needs time to settle after initialization. Give it + * 10 ms. I don't really believe it, but if output resumes to quickly after + * this call, the first few characters are not right. + */ + if ( need_reinitialization ) + cd2401_udelay( 10000L ); + + /* Return something */ + return RTEMS_SUCCESSFUL; +} + +/* + * cd2401_startRemoreTx + * + * Defined as a callback, but it would appear that it is never called. The + * POSIX standard states that when the tcflow() function is called with the + * TCION action, the system wall transmit a START character. Presumably, + * tcflow() is called internally when IXOFF is set in the termios c_iflag + * field when the input buffer can accomodate enough characters. It should + * probably be called from fillBufferQueue(). Clearly, the function is also + * explicitly callable by user code. The action is clearly to send the START + * character, regardless of whether START/STOP flow control is in effect. + * + * Input parameters: + * minor - selected channel + * + * Output parameters: NONE + * + * Return value: IGNORED + * + * PROPER START CHARACTER MUST BE PROGRAMMED IN SCHR1. + */ +int cd2401_startRemoteTx( + int minor +) +{ + rtems_interrupt_level level; + + rtems_interrupt_disable (level); + + cd2401->car = minor; /* Select channel */ + cd2401->stcr = 0x01; /* Send SCHR1 ahead of chars in FIFO */ + + CD2401_RECORD_START_REMOTE_TX_INFO(( minor )); + + rtems_interrupt_enable (level); + + /* Return something */ + return RTEMS_SUCCESSFUL; +} + +/* + * cd2401_stopRemoteTx + * + * Defined as a callback, but it would appear that it is never called. The + * POSIX standard states that when the tcflow() function is called with the + * TCIOFF function, the system wall transmit a STOP character. Presumably, + * tcflow() is called internally when IXOFF is set in the termios c_iflag + * field as the input buffer is about to overflow. It should probably be + * called from rtems_termios_enqueue_raw_characters(). Clearly, the function + * is also explicitly callable by user code. The action is clearly to send + * the STOP character, regardless of whether START/STOP flow control is in + * effect. + * + * Input parameters: + * minor - selected channel + * + * Output parameters: NONE + * + * Return value: IGNORED + * + * PROPER STOP CHARACTER MUST BE PROGRAMMED IN SCHR2. + */ +int cd2401_stopRemoteTx( + int minor +) +{ + rtems_interrupt_level level; + + rtems_interrupt_disable (level); + + cd2401->car = minor; /* Select channel */ + cd2401->stcr = 0x02; /* Send SCHR2 ahead of chars in FIFO */ + + CD2401_RECORD_STOP_REMOTE_TX_INFO(( minor )); + + rtems_interrupt_enable (level); + + /* Return something */ + return RTEMS_SUCCESSFUL; +} + +/* + * cd2401_write + * + * Initiate DMA output. Termios guarantees that the buffer does not wrap + * around, so we can do DMA strait from the supplied buffer. + * + * Input parameters: + * minor - selected channel + * buf - output buffer + * len - number of chars to output + * + * Output parameters: NONE + * + * Return value: IGNORED + * + * MUST BE EXECUTED WITH THE CD2401 INTERRUPTS DISABLED! + * The processor is placed at interrupt level CD2401_INT_LEVEL explicitly in + * console_write(). The processor is necessarily at interrupt level 1 in + * cd2401_tx_isr(). + */ +ssize_t cd2401_write( + int minor, + const char *buf, + size_t len +) +{ + if (len > 0) { + cd2401->car = minor; /* Select channel */ + + if ( (cd2401->dmabsts & 0x08) == 0 ) { + /* Next buffer is A. Wait for it to be ours. */ + while ( cd2401->atbsts & 0x01 ); + + CD2401_Channel_Info[minor].own_buf_A = FALSE; + CD2401_Channel_Info[minor].len = len; + CD2401_Channel_Info[minor].buf = buf; + cd2401->atbadru = (uint16_t)( ( (uint32_t) buf ) >> 16 ); + cd2401->atbadrl = (uint16_t)( (uint32_t) buf ); + cd2401->atbcnt = len; + CD2401_RECORD_WRITE_INFO(( len, buf, 'A' )); + cd2401->atbsts = 0x03; /* CD2401 owns buffer, int when empty */ + } + else { + /* Next buffer is B. Wait for it to be ours. */ + while ( cd2401->btbsts & 0x01 ); + + CD2401_Channel_Info[minor].own_buf_B = FALSE; + CD2401_Channel_Info[minor].len = len; + CD2401_Channel_Info[minor].buf = buf; + cd2401->btbadru = (uint16_t)( ( (uint32_t) buf ) >> 16 ); + cd2401->btbadrl = (uint16_t)( (uint32_t) buf ); + cd2401->btbcnt = len; + CD2401_RECORD_WRITE_INFO(( len, buf, 'B' )); + cd2401->btbsts = 0x03; /* CD2401 owns buffer, int when empty */ + } + /* Nuts -- Need TxD ints */ + CD2401_Channel_Info[minor].txEmpty = FALSE; + cd2401->ier |= 0x01; + } + + /* Return something */ + return len; +} + +#if 0 +/* + * cd2401_drainOutput + * + * Wait for the txEmpty indication on the specified channel. + * + * Input parameters: + * minor - selected channel + * + * Output parameters: NONE + * + * Return value: IGNORED + * + * MUST NOT BE EXECUTED WITH THE CD2401 INTERRUPTS DISABLED! + * The txEmpty flag is set by the tx ISR. + * + * DOES NOT WORK! DO NOT ENABLE THIS CODE. THE CD2401 DOES NOT COOPERATE! + * The code is here to document that the output FIFO is NOT empty when + * the CD2401 reports that the Tx buffer is empty. + */ +int cd2401_drainOutput( + int minor +) +{ + CD2401_RECORD_DRAIN_OUTPUT_INFO(( CD2401_Channel_Info[minor].txEmpty, + CD2401_Channel_Info[minor].own_buf_A, + CD2401_Channel_Info[minor].own_buf_B )); + + while( ! (CD2401_Channel_Info[minor].txEmpty && + CD2401_Channel_Info[minor].own_buf_A && + CD2401_Channel_Info[minor].own_buf_B) ); + + /* Return something */ + return RTEMS_SUCCESSFUL; +} +#endif + +/* + * _167Bug_pollRead + * + * Read a character from the 167Bug console, and return it. Return -1 + * if there is no character in the input FIFO. + * + * Input parameters: + * minor - selected channel + * + * Output parameters: NONE + * + * Return value: char returned as positive signed int + * -1 if no character is present in the input FIFO. + * + * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! + */ +int _167Bug_pollRead( + int minor +) +{ + int char_not_available; + unsigned char c; + rtems_interrupt_level previous_level; + + /* + * Redirection of .INSTAT does not work: 167-Bug crashes. + * Switch the input stream to the specified port. + * Make sure this is atomic code. + */ + rtems_interrupt_disable( previous_level ); + + __asm__ volatile( "movew %1, -(%%sp)\n\t"/* Channel */ + "trap #15\n\t" /* Trap to 167Bug */ + ".short 0x61\n\t" /* Code for .REDIR_I */ + "trap #15\n\t" /* Trap to 167Bug */ + ".short 0x01\n\t" /* Code for .INSTAT */ + "move %%cc, %0\n\t" /* Get condition codes */ + "andil #4, %0" /* Keep the Zero bit */ + : "=d" (char_not_available) : "d" (minor): "%%cc" ); + + if (char_not_available) { + rtems_interrupt_enable( previous_level ); + return -1; + } + + /* Read the char and return it */ + __asm__ volatile( "subq.l #2,%%a7\n\t" /* Space for result */ + "trap #15\n\t" /* Trap to 167 Bug */ + ".short 0x00\n\t" /* Code for .INCHR */ + "moveb (%%a7)+, %0" /* Pop char into c */ + : "=d" (c) : ); + + rtems_interrupt_enable( previous_level ); + + return (int)c; +} + +/* + * _167Bug_pollWrite + * + * Output buffer through 167Bug. Returns only once every character has been + * sent (polled output). + * + * Input parameters: + * minor - selected channel + * buf - output buffer + * len - number of chars to output + * + * Output parameters: NONE + * + * Return value: IGNORED + * + * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! + */ +ssize_t _167Bug_pollWrite( + int minor, + const char *buf, + size_t len +) +{ + const char *endbuf = buf + len; + + __asm__ volatile( "pea (%0)\n\t" /* endbuf */ + "pea (%1)\n\t" /* buf */ + "movew #0x21, -(%%sp)\n\t" /* Code for .OUTSTR */ + "movew %2, -(%%sp)\n\t" /* Channel */ + "trap #15\n\t" /* Trap to 167Bug */ + ".short 0x60" /* Code for .REDIR */ + :: "a" (endbuf), "a" (buf), "d" (minor) ); + + /* Return something */ + return len; +} + +/* + * do_poll_read + * + * Input characters through 167Bug. Returns has soon as a character has been + * received. Otherwise, if we wait for the number of requested characters, we + * could be here forever! + * + * CR is converted to LF on input. The terminal should not send a CR/LF pair + * when the return or enter key is pressed. + * + * Input parameters: + * major - ignored. Should be the major number for this driver. + * minor - selected channel. + * arg->buffer - where to put the received characters. + * arg->count - number of characters to receive before returning--Ignored. + * + * Output parameters: + * arg->bytes_moved - the number of characters read. Always 1. + * + * Return value: RTEMS_SUCCESSFUL + * + * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! + */ +static rtems_status_code do_poll_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args = arg; + int c; + + while( (c = _167Bug_pollRead (minor)) == -1 ); + rw_args->buffer[0] = (uint8_t)c; + if( rw_args->buffer[0] == '\r' ) + rw_args->buffer[0] = '\n'; + rw_args->bytes_moved = 1; + return RTEMS_SUCCESSFUL; +} + +/* + * do_poll_write + * + * Output characters through 167Bug. Returns only once every character has + * been sent. + * + * CR is transmitted AFTER a LF on output. + * + * Input parameters: + * major - ignored. Should be the major number for this driver. + * minor - selected channel + * arg->buffer - where to get the characters to transmit. + * arg->count - the number of characters to transmit before returning. + * + * Output parameters: + * arg->bytes_moved - the number of characters read + * + * Return value: RTEMS_SUCCESSFUL + * + * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! + */ +static rtems_status_code do_poll_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args = arg; + uint32_t i; + + for( i = 0; i < rw_args->count; i++ ) { + _167Bug_pollWrite(minor, &(rw_args->buffer[i]), 1); + if ( rw_args->buffer[i] == '\n' ) + _167Bug_pollWrite(minor, &cr_char, 1); + } + rw_args->bytes_moved = i; + return RTEMS_SUCCESSFUL; +} + +/* + * _BSP_output_char + * + * printk() function prototyped in bspIo.h. Does not use termios. + */ +void _BSP_output_char(char c) +{ + rtems_device_minor_number printk_minor; + + /* + * Can't rely on console_initialize having been called before this function + * is used. + */ + if ( NVRAM_CONFIGURE ) + /* J1-4 is on, use NVRAM info for configuration */ + printk_minor = (nvram->console_printk_port & 0x30) >> 4; + else + printk_minor = PRINTK_MINOR; + + _167Bug_pollWrite(printk_minor, &c, 1); +} + +/* + *************** + * BOILERPLATE * + *************** + * + * All these functions are prototyped in rtems/c/src/lib/include/console.h. + */ + +/* + * Initialize and register the device + */ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + rtems_device_minor_number console_minor; + + /* + * Set up TERMIOS if needed + */ + if ( NVRAM_CONFIGURE ) { + /* J1-4 is on, use NVRAM info for configuration */ + console_minor = nvram->console_printk_port & 0x03; + + if ( nvram->console_mode & 0x01 ) + /* termios */ + rtems_termios_initialize (); + } + else { + console_minor = CONSOLE_MINOR; +#if CD2401_USE_TERMIOS == 1 + rtems_termios_initialize (); +#endif + } + + /* + * Do device-specific initialization + * Does not affect 167-Bug. + */ + cd2401_initialize (); + + /* + * Register the devices + */ + status = rtems_io_register_name ("/dev/tty0", major, 0); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + + status = rtems_io_register_name ("/dev/tty1", major, 1); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + + status = rtems_io_register_name ("/dev/console", major, console_minor); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + + status = rtems_io_register_name ("/dev/tty2", major, 2); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + + status = rtems_io_register_name ("/dev/tty3", major, 3); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + + return RTEMS_SUCCESSFUL; +} + +/* + * Open the device + */ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + static const rtems_termios_callbacks pollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + _167Bug_pollRead, /* pollRead */ + _167Bug_pollWrite, /* write */ + NULL, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + 0 /* outputUsesInterrupts */ + }; + + static const rtems_termios_callbacks intrCallbacks = { + cd2401_firstOpen, /* firstOpen */ + cd2401_lastClose, /* lastClose */ + NULL, /* pollRead */ + cd2401_write, /* write */ + cd2401_setAttributes, /* setAttributes */ + cd2401_stopRemoteTx, /* stopRemoteTx */ + cd2401_startRemoteTx, /* startRemoteTx */ + 1 /* outputUsesInterrupts */ + }; + + if ( NVRAM_CONFIGURE ) + /* J1-4 is on, use NVRAM info for configuration */ + if ( nvram->console_mode & 0x01 ) + /* termios */ + if ( nvram->console_mode & 0x02 ) + /* interrupt-driven I/O */ + return rtems_termios_open (major, minor, arg, &intrCallbacks); + else + /* polled I/O */ + return rtems_termios_open (major, minor, arg, &pollCallbacks); + else + /* no termios -- default to polled I/O */ + return RTEMS_SUCCESSFUL; +#if CD2401_USE_TERMIOS == 1 +#if CD2401_IO_MODE != 1 + else + /* termios & polled I/O*/ + return rtems_termios_open (major, minor, arg, &pollCallbacks); +#else + else + /* termios & interrupt-driven I/O*/ + return rtems_termios_open (major, minor, arg, &intrCallbacks); +#endif +#else + else + /* no termios -- default to polled I/O */ + return RTEMS_SUCCESSFUL; +#endif +} + +/* + * Close the device + */ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + if ( NVRAM_CONFIGURE ) { + /* J1-4 is on, use NVRAM info for configuration */ + if ( nvram->console_mode & 0x01 ) + /* termios */ + return rtems_termios_close (arg); + else + /* no termios */ + return RTEMS_SUCCESSFUL; + } +#if CD2401_USE_TERMIOS == 1 + else + /* termios */ + return rtems_termios_close (arg); +#else + else + /* no termios */ + return RTEMS_SUCCESSFUL; +#endif +} + +/* + * Read from the device + */ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + if ( NVRAM_CONFIGURE ) { + /* J1-4 is on, use NVRAM info for configuration */ + if ( nvram->console_mode & 0x01 ) + /* termios */ + return rtems_termios_read (arg); + else + /* no termios -- default to polled */ + return do_poll_read (major, minor, arg); + } +#if CD2401_USE_TERMIOS == 1 + else + /* termios */ + return rtems_termios_read (arg); +#else + else + /* no termios -- default to polled */ + return do_poll_read (major, minor, arg); +#endif +} + +/* + * Write to the device + */ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + if ( NVRAM_CONFIGURE ) { + /* J1-4 is on, use NVRAM info for configuration */ + if ( nvram->console_mode & 0x01 ) + /* termios */ + return rtems_termios_write (arg); + else + /* no termios -- default to polled */ + return do_poll_write (major, minor, arg); + } +#if CD2401_USE_TERMIOS == 1 + else + /* termios */ + return rtems_termios_write (arg); +#else + else + /* no termios -- default to polled */ + return do_poll_write (major, minor, arg); +#endif +} + +/* + * Handle ioctl request. + */ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + if ( NVRAM_CONFIGURE ) { + /* J1-4 is on, use NVRAM info for configuration */ + if ( nvram->console_mode & 0x01 ) + /* termios */ + return rtems_termios_ioctl (arg); + else + /* no termios -- default to polled */ + return RTEMS_SUCCESSFUL; + } +#if CD2401_USE_TERMIOS == 1 + else + /* termios */ + return rtems_termios_ioctl (arg); +#else + else + /* no termios -- default to polled */ + return RTEMS_SUCCESSFUL; +#endif +} diff --git a/bsps/m68k/uC5282/console/console.c b/bsps/m68k/uC5282/console/console.c new file mode 100644 index 0000000000..276d0c6f18 --- /dev/null +++ b/bsps/m68k/uC5282/console/console.c @@ -0,0 +1,774 @@ +/* + * Multi UART console serial I/O. + * + * TO DO: Add DMA input/output + * + * Author: W. Eric Norum + * + * COPYRIGHT (c) 2005. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x)) + +#define MCF5282_UART_USR_ERROR ( MCF5282_UART_USR_RB | \ + MCF5282_UART_USR_FE | \ + MCF5282_UART_USR_PE | \ + MCF5282_UART_USR_OE ) + +static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); +static ssize_t IntUartInterruptWrite (int minor, const char *buf, size_t len); + +static void +_BSP_null_char( char c ) +{ + int level; + + rtems_interrupt_disable(level); + while ( (MCF5282_UART_USR(CONSOLE_PORT) & MCF5282_UART_USR_TXRDY) == 0 ) + continue; + MCF5282_UART_UTB(CONSOLE_PORT) = c; + while ( (MCF5282_UART_USR(CONSOLE_PORT) & MCF5282_UART_USR_TXRDY) == 0 ) + continue; + rtems_interrupt_enable(level); +} + +BSP_polling_getchar_function_type BSP_poll_char = NULL; +BSP_output_char_function_type BSP_output_char = _BSP_null_char; + +/* + * The MCF5282 has three UARTs. Enable all them here. I/O pin selection + * is assumed to have been done elsewher. + */ +#define MAX_UART_INFO 3 +#define RX_BUFFER_SIZE 512 + +struct IntUartInfoStruct +{ + int iomode; + volatile int uimr; + int baud; + int databits; + int parity; + int stopbits; + int hwflow; + int rx_in; + int rx_out; + char rx_buffer[RX_BUFFER_SIZE]; + void *ttyp; +}; + +struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; + +/*************************************************************************** + Function : IntUartSet + + Description : This updates the hardware UART settings. + ***************************************************************************/ +static void +IntUartSet(int minor, int baud, int databits, int parity, int stopbits, int hwflow) +{ + int divisor; + uint32_t clock_speed; + uint8_t umr1 = 0; + uint8_t umr2 = 0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + int level; + + rtems_interrupt_disable(level); + + + /* disable interrupts, clear RTS line, and disable the UARTS */ + MCF5282_UART_UIMR(minor) = 0; + MCF5282_UART_UOP0(minor) = 1; + MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_DISABLED | MCF5282_UART_UCR_RX_DISABLED); + + /* save the current values */ + info->uimr = 0; + info->baud = baud; + info->databits = databits; + info->parity = parity; + info->stopbits = stopbits; + info->hwflow = hwflow; + + clock_speed = bsp_get_CPU_clock_speed(); + /* determine the baud divisor value */ + divisor = (clock_speed / ( 32 * baud )); + if ( divisor < 2 ) { + divisor = 2; + } + + /* check to see if doing hardware flow control */ + if ( hwflow ) + { + /* set hardware flow options */ + umr1 |= MCF5282_UART_UMR1_RXRTS; + umr2 |= MCF5282_UART_UMR2_TXCTS; + } + + /* determine the new umr values */ + umr1 |= (parity | databits); + umr2 |= (stopbits); + + /* reset the uart */ + MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_ERROR; + MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_RX; + MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_TX; + + /* reset the uart mode register and update values */ + MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_MR; + MCF5282_UART_UMR(minor) = umr1; + MCF5282_UART_UMR(minor) = umr2; + + /* set the baud rate values */ + MCF5282_UART_UCSR(minor) = (MCF5282_UART_UCSR_RCS_SYS_CLK | MCF5282_UART_UCSR_TCS_SYS_CLK); + MCF5282_UART_UBG1(minor) = (divisor & 0xff00) >> 8; + MCF5282_UART_UBG2(minor) = (divisor & 0x00ff); + + /* enable the uart */ + MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_ENABLED | MCF5282_UART_UCR_RX_ENABLED); + + /* check to see if interrupts need to be enabled */ + if ( info->iomode != TERMIOS_POLLED ) + { + /* enable rx interrupts */ + info->uimr |= MCF5282_UART_UIMR_FFULL; + MCF5282_UART_UIMR(minor) = info->uimr; + } + + /* check to see if doing hardware flow control */ + if ( hwflow ) + { + /* assert the RTS line */ + MCF5282_UART_UOP1(minor) = 1; + } + + rtems_interrupt_enable(level); + +} + + +/*************************************************************************** + Function : IntUartSetAttributes + + Description : This provides the hardware-dependent portion of tcsetattr(). + value and sets it. At the moment this just sets the baud rate. + + Note: The highest baudrate is 115200 as this stays within + an error of +/- 5% at 25MHz processor clock + ***************************************************************************/ +static int +IntUartSetAttributes(int minor, const struct termios *t) +{ + /* set default index values */ + int baud = (int)9600; + int databits = (int)MCF5282_UART_UMR1_BC_8; + int parity = (int)MCF5282_UART_UMR1_PM_NONE; + int stopbits = (int)MCF5282_UART_UMR2_STOP_BITS_1; + int hwflow = (int)0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* check to see if input is valid */ + if ( t != (const struct termios *)0 ) + { + /* determine baud rate index */ + baud = rtems_termios_baud_to_number(t->c_ospeed); + + /* determine data bits */ + switch ( t->c_cflag & CSIZE ) + { + case CS5: + databits = (int)MCF5282_UART_UMR1_BC_5; + break; + case CS6: + databits = (int)MCF5282_UART_UMR1_BC_6; + break; + case CS7: + databits = (int)MCF5282_UART_UMR1_BC_7; + break; + case CS8: + databits = (int)MCF5282_UART_UMR1_BC_8; + break; + } + + /* determine if parity is enabled */ + if ( t->c_cflag & PARENB ) + { + if ( t->c_cflag & PARODD ) + { + /* odd parity */ + parity = (int)MCF5282_UART_UMR1_PM_ODD; + } + else + { + /* even parity */ + parity = (int)MCF5282_UART_UMR1_PM_EVEN; + } + } + + /* determine stop bits */ + if ( t->c_cflag & CSTOPB ) + { + /* two stop bits */ + stopbits = (int)MCF5282_UART_UMR2_STOP_BITS_2; + } + + /* check to see if hardware flow control */ + if ( t->c_cflag & CRTSCTS ) + { + hwflow = 1; + } + } + + /* check to see if values have changed */ + if ( ( baud != info->baud ) || + ( databits != info->databits ) || + ( parity != info->parity ) || + ( stopbits != info->stopbits ) || + ( hwflow != info->hwflow ) ) + { + + /* call function to set values */ + IntUartSet(minor, baud, databits, parity, stopbits, hwflow); + } + + return( RTEMS_SUCCESSFUL ); + +} + +/*************************************************************************** + Function : IntUartInterruptHandler + + Description : This is the interrupt handler for the internal uart. It + determines which channel caused the interrupt before queueing any received + chars and dequeueing chars waiting for transmission. + ***************************************************************************/ +static rtems_isr +IntUartInterruptHandler(rtems_vector_number v) +{ + unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); + struct IntUartInfoStruct *info = &IntUartInfo[chan]; + + /* check to see if received data */ + if ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_RXRDY ) + { + /* read data and put into the receive buffer */ + while ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_RXRDY ) + { + + if ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_ERROR ) + { + /* clear the error */ + MCF5282_UART_UCR(chan) = MCF5282_UART_UCR_RESET_ERROR; + } + /* put data in rx buffer and check for errors */ + info->rx_buffer[info->rx_in] = MCF5282_UART_URB(chan); + + /* update buffer values */ + info->rx_in++; + + if ( info->rx_in >= RX_BUFFER_SIZE ) + { + info->rx_in = 0; + } + } + /* Make sure the port has been opened */ + if ( info->ttyp ) + { + + /* check to see if task driven */ + if ( info->iomode == TERMIOS_TASK_DRIVEN ) + { + /* notify rx task that rx buffer has data */ + rtems_termios_rxirq_occured(info->ttyp); + } + else + { + /* Push up the received data */ + rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, info->rx_in); + info->rx_in = 0; + } + } + } + + /* check to see if data needs to be transmitted */ + if ( ( info->uimr & MCF5282_UART_UIMR_TXRDY ) && + ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_TXRDY ) ) + { + + /* disable tx interrupts */ + info->uimr &= ~MCF5282_UART_UIMR_TXRDY; + MCF5282_UART_UIMR(chan) = info->uimr; + + /* tell upper level that character has been sent */ + if ( info->ttyp ) + rtems_termios_dequeue_characters(info->ttyp, 1); + } +} + + + +/*************************************************************************** + Function : IntUartInitialize + + Description : This initialises the internal uart hardware for all + internal uarts. If the internal uart is to be interrupt driven then the + interrupt vectors are hooked. + ***************************************************************************/ +static void +IntUartInitialize(void) +{ + unsigned int chan; + struct IntUartInfoStruct *info; + rtems_isr_entry old_handler; + int level; + + for ( chan = 0; chan < MAX_UART_INFO; chan++ ) + { + info = &IntUartInfo[chan]; + + info->ttyp = NULL; + info->rx_in = 0; + info->rx_out = 0; + info->baud = -1; + info->databits = -1; + info->parity = -1; + info->stopbits = -1; + info->hwflow = -1; + + MCF5282_UART_UACR(chan) = 0; + MCF5282_UART_UIMR(chan) = 0; + if ( info->iomode != TERMIOS_POLLED ) + { + rtems_interrupt_catch (IntUartInterruptHandler, + UART_INTC0_IRQ_VECTOR(chan), + &old_handler); + } + + /* set uart default values */ + IntUartSetAttributes(chan, NULL); + + /* unmask interrupt */ + rtems_interrupt_disable(level); + switch(chan) { + case 0: + bsp_allocate_interrupt(UART0_IRQ_LEVEL, UART0_IRQ_PRIORITY); + MCF5282_INTC0_ICR13 = MCF5282_INTC_ICR_IL(UART0_IRQ_LEVEL) | + MCF5282_INTC_ICR_IP(UART0_IRQ_PRIORITY); + MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT13 | + MCF5282_INTC_IMRL_MASKALL); + break; + + case 1: + bsp_allocate_interrupt(UART1_IRQ_LEVEL, UART1_IRQ_PRIORITY); + MCF5282_INTC0_ICR14 = MCF5282_INTC_ICR_IL(UART1_IRQ_LEVEL) | + MCF5282_INTC_ICR_IP(UART1_IRQ_PRIORITY); + MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT14 | + MCF5282_INTC_IMRL_MASKALL); + break; + + case 2: + bsp_allocate_interrupt(UART2_IRQ_LEVEL, UART2_IRQ_PRIORITY); + MCF5282_INTC0_ICR15 = MCF5282_INTC_ICR_IL(UART2_IRQ_LEVEL) | + MCF5282_INTC_ICR_IP(UART2_IRQ_PRIORITY); + MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT15 | + MCF5282_INTC_IMRL_MASKALL); + break; + } + rtems_interrupt_enable(level); + + } /* of chan loop */ + + +} /* IntUartInitialise */ + + +/*************************************************************************** + Function : IntUartInterruptWrite + + Description : This writes a single character to the appropriate uart + channel. This is either called during an interrupt or in the user's task + to initiate a transmit sequence. Calling this routine enables Tx + interrupts. + ***************************************************************************/ +static ssize_t +IntUartInterruptWrite (int minor, const char *buf, size_t len) +{ + if (len > 0) { + /* write out character */ + MCF5282_UART_UTB(minor) = *buf; + + /* enable tx interrupt */ + IntUartInfo[minor].uimr |= MCF5282_UART_UIMR_TXRDY; + MCF5282_UART_UIMR(minor) = IntUartInfo[minor].uimr; + } + + return 0; +} + +/*************************************************************************** + Function : IntUartInterruptOpen + + Description : This enables interrupts when the tty is opened. + ***************************************************************************/ +static int +IntUartInterruptOpen(int major, int minor, void *arg) +{ + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + int level; + + /* + * Enable serial I/O pin assignments + */ + rtems_interrupt_disable(level); + switch(minor) { + case 0: + MCF5282_GPIO_PUAPAR |= MCF5282_GPIO_PUAPAR_PUAPA1|MCF5282_GPIO_PUAPAR_PUAPA0; + break; + case 1: + MCF5282_GPIO_PUAPAR |= MCF5282_GPIO_PUAPAR_PUAPA3|MCF5282_GPIO_PUAPAR_PUAPA2; + break; + case 2: + MCF5282_GPIO_PASPAR = + (MCF5282_GPIO_PASPAR + & ~(MCF5282_GPIO_PASPAR_PASPA3(3)|MCF5282_GPIO_PASPAR_PASPA2(3))) + | (MCF5282_GPIO_PASPAR_PASPA3(2)|MCF5282_GPIO_PASPAR_PASPA2(2)); + break; + } + rtems_interrupt_enable(level); + /* enable the uart */ + MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_ENABLED | MCF5282_UART_UCR_RX_ENABLED); + + /* check to see if interrupts need to be enabled */ + if ( info->iomode != TERMIOS_POLLED ) + { + /* enable rx interrupts */ + info->uimr |= MCF5282_UART_UIMR_FFULL; + MCF5282_UART_UIMR(minor) = info->uimr; + } + + /* check to see if doing hardware flow control */ + if ( info->hwflow ) + { + /* assert the RTS line */ + MCF5282_UART_UOP1(minor) = 1; + } + + return( 0 ); +} + + + +/*************************************************************************** + Function : IntUartInterruptClose + + Description : This disables interrupts when the tty is closed. + ***************************************************************************/ +static int +IntUartInterruptClose(int major, int minor, void *arg) +{ + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* disable the interrupts and the uart */ + MCF5282_UART_UIMR(minor) = 0; + MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_DISABLED | MCF5282_UART_UCR_RX_DISABLED); + + /* reset values */ + info->ttyp = NULL; + info->uimr = 0; + info->rx_in = 0; + info->rx_out = 0; + + return( 0 ); +} + +/*************************************************************************** + Function : IntUartTaskRead + + Description : This reads all available characters from the internal uart + and places them into the termios buffer. The rx interrupts will be + re-enabled after all data has been read. + ***************************************************************************/ +static int +IntUartTaskRead(int minor) +{ + char buffer[RX_BUFFER_SIZE]; + int count; + int rx_in; + int index = 0; + struct IntUartInfoStruct *info = &IntUartInfo[minor]; + + /* determine number of values to copy out */ + rx_in = info->rx_in; + if ( info->rx_out <= rx_in ) + { + count = rx_in - info->rx_out; + } + else + { + count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; + } + + /* copy data into local buffer from rx buffer */ + while ( ( index < count ) && ( index < RX_BUFFER_SIZE ) ) + { + /* copy data byte */ + buffer[index] = info->rx_buffer[info->rx_out]; + index++; + + /* increment rx buffer values */ + info->rx_out++; + if ( info->rx_out >= RX_BUFFER_SIZE ) + { + info->rx_out = 0; + } + } + + /* check to see if buffer is not empty */ + if ( count > 0 ) + { + /* set characters into termios buffer */ + rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); + } + + return( EOF ); +} + + + +/*************************************************************************** + Function : IntUartPollRead + + Description : This reads a character from the internal uart. It returns + to the caller without blocking if not character is waiting. + ***************************************************************************/ +static int +IntUartPollRead (int minor) +{ + if ( (MCF5282_UART_USR(minor) & MCF5282_UART_USR_RXRDY) == 0 ) + return(-1); + + return(MCF5282_UART_URB(minor)); +} + + +/*************************************************************************** + Function : IntUartPollWrite + + Description : This writes out each character in the buffer to the + appropriate internal uart channel waiting till each one is sucessfully + transmitted. + ***************************************************************************/ +static ssize_t +IntUartPollWrite (int minor, const char *buf, size_t len) +{ + size_t retval = len; + /* loop over buffer */ + while ( len-- ) + { + /* block until we can transmit */ + while ( (MCF5282_UART_USR(minor) & MCF5282_UART_USR_TXRDY) == 0 ) + continue; + /* transmit data byte */ + MCF5282_UART_UTB(minor) = *buf++; + } + return retval; +} + +/*************************************************************************** + Function : console_initialize + + Description : This initialises termios, all uart hardware before + registering /dev/tty devices for each channel and the system /dev/console. + ***************************************************************************/ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg ) +{ + rtems_status_code status; + int chan; + + /* Set up TERMIOS */ + rtems_termios_initialize (); + + /* set io modes for the different channels and initialize device */ + for ( chan = 0; chan < MAX_UART_INFO; chan++ ) + IntUartInfo[chan].iomode = TERMIOS_IRQ_DRIVEN; + IntUartInitialize(); + + /* Register the console port */ + status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT); + if ( status != RTEMS_SUCCESSFUL ) + { + rtems_fatal_error_occurred (status); + } + + /* Register the other ports */ + if ( CONSOLE_PORT != 0 ) + { + status = rtems_io_register_name ("/dev/tty00", major, 0); + if ( status != RTEMS_SUCCESSFUL ) + { + rtems_fatal_error_occurred (status); + } + } + if ( CONSOLE_PORT != 1 ) + { + status = rtems_io_register_name ("/dev/tty01", major, 1); + if ( status != RTEMS_SUCCESSFUL ) + { + rtems_fatal_error_occurred (status); + } + } + status = rtems_io_register_name ("/dev/tty02", major, 2); + if ( status != RTEMS_SUCCESSFUL ) + { + rtems_fatal_error_occurred (status); + } + + return(RTEMS_SUCCESSFUL); +} + +/*************************************************************************** + Function : console_open + + Description : This actually opens the device depending on the minor + number set during initialisation. The device specific access routines are + passed to termios when the devices is opened depending on whether it is + polled or not. + ***************************************************************************/ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + rtems_status_code status = RTEMS_INVALID_NUMBER; + rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *)arg; + struct IntUartInfoStruct *info; + + static const rtems_termios_callbacks IntUartPollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + IntUartPollRead, /* pollRead */ + IntUartPollWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_POLLED /* mode */ + }; + static const rtems_termios_callbacks IntUartIntrCallbacks = { + IntUartInterruptOpen, /* firstOpen */ + IntUartInterruptClose, /* lastClose */ + NULL, /* pollRead */ + IntUartInterruptWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_IRQ_DRIVEN /* mode */ + }; + + static const rtems_termios_callbacks IntUartTaskCallbacks = { + IntUartInterruptOpen, /* firstOpen */ + IntUartInterruptClose, /* lastClose */ + IntUartTaskRead, /* pollRead */ + IntUartInterruptWrite, /* write */ + IntUartSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_TASK_DRIVEN /* mode */ + }; + + /* open the port depending on the minor device number */ + if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) ) + { + info = &IntUartInfo[minor]; + switch ( info->iomode ) + { + case TERMIOS_POLLED: + status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); + break; + case TERMIOS_IRQ_DRIVEN: + status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); + info->ttyp = args->iop->data1; + break; + case TERMIOS_TASK_DRIVEN: + status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); + info->ttyp = args->iop->data1; + break; + } + } + + return( status ); +} + +/*************************************************************************** + Function : console_close + + Description : This closes the device via termios + ***************************************************************************/ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return(rtems_termios_close (arg)); +} + +/****************** +********************************************************* + Function : console_read + + Description : Read from the device via termios + ***************************************************************************/ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return(rtems_termios_read (arg)); +} + +/*************************************************************************** + Function : console_write + + Description : Write to the device via termios + ***************************************************************************/ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return(rtems_termios_write (arg)); +} + +/*************************************************************************** + Function : console_ioctl + + Description : Pass the IOCtl call to termios + ***************************************************************************/ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg) +{ + return( rtems_termios_ioctl (arg) ); +} + diff --git a/bsps/mips/csb350/console/console-io.c b/bsps/mips/csb350/console/console-io.c new file mode 100644 index 0000000000..e1beff8460 --- /dev/null +++ b/bsps/mips/csb350/console/console-io.c @@ -0,0 +1,85 @@ +/* + * This file contains the hardware specific portions of the TTY driver + * for the serial ports on the csb350. + */ + +/* + * COPYRIGHT (c) 1989-2000. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include + +/* + * console_initialize_hardware + * + * This routine initializes the console hardware. + * + */ +void console_initialize_hardware(void) +{ + uart0->fifoctrl = 0xf1; /* enable fifo, max sizes */ + au_sync(); +} + + +/* + * console_outbyte_polled + * + * This routine transmits a character using polling. + */ +void console_outbyte_polled( + int port, + char ch +) +{ + /* wait for the fifo to make room */ + while ((uart0->linestat & 0x20) == 0) { + continue; + } + + uart0->txdata = ch; + au_sync(); +} +/* + * console_inbyte_nonblocking + * + * This routine polls for a character. + */ + +int console_inbyte_nonblocking( + int port +) +{ + unsigned char c; + + if (uart0->linestat & 1) { + c = (char)uart0->rxdata; + return c; + } else { + return -1; + } +} + +#include + +static void csb250_output_char(char c) +{ + console_outbyte_polled( 0, c ); +} + +static int csb250_get_char(void) +{ + return console_inbyte_nonblocking(0); +} + +BSP_output_char_function_type BSP_output_char = csb250_output_char; +BSP_polling_getchar_function_type BSP_poll_char = csb250_get_char; + diff --git a/bsps/mips/hurricane/console/console.c b/bsps/mips/hurricane/console/console.c new file mode 100644 index 0000000000..219cc964c0 --- /dev/null +++ b/bsps/mips/hurricane/console/console.c @@ -0,0 +1,212 @@ +/* + * This file contains the IDT 4650 console IO package. + */ + +/* + * Author: Craig Lebakken + * + * COPYRIGHT (c) 1996 by Transition Networks Inc. + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Transition Networks not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * Transition Networks makes no representations about the suitability + * of this software for any purpose. + * + * Derived from c/src/lib/libbsp/no_cpu/no_bsp/console/console.c: + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include +#include +#include + +/* PMON entry points */ +int mon_read(int fd, char *buf, int cnt); /* stdin is fd=0 */ +int mon_write(int fd, char *buf, int cnt); /* stdout is fd=1 */ + +/* console_initialize + * + * This routine initializes the console IO driver. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + + status = rtems_io_register_name( + "/dev/console", + major, + (rtems_device_minor_number) 0 + ); + + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + return RTEMS_SUCCESSFUL; +} + +/* inbyte + * + * This routine reads a character from the SOURCE. + */ +static char inbyte( void ) +{ + char buf[10]; + + /* + * If polling, wait until a character is available. + */ + mon_read(0, buf, 1); /* stdin is fd=0, read 1 byte */ + + return (buf[0]); +} + +/* outbyte + * + * This routine transmits a character out the SOURCE. It may support + * XON/XOFF flow control. + */ +static void outbyte( + char ch +) +{ + char buf[10]; + /* + * If polling, wait for the transmitter to be ready. + * Check for flow control requests and process. + * Then output the character. + */ + buf[0] = ch; + + mon_write( 1, buf, 1 ); /* stdout is fd=1, write 1 byte */ +} + +/* + * Open entry point + */ + +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * Close entry point + */ + +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * read bytes from the serial port. We only have stdin. + */ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args; + char *buffer; + int maximum; + int count = 0; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + buffer[ count ] = inbyte(); + if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { + buffer[ count++ ] = '\n'; + break; + } + } + + rw_args->bytes_moved = count; + return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; +} + +/* + * write bytes to the serial port. Stdout and stderr are the same. + */ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + int count; + int maximum; + rtems_libio_rw_args_t *rw_args; + char *buffer; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + if ( buffer[ count ] == '\n') { + outbyte('\r'); + } + outbyte( buffer[ count ] ); + } + + rw_args->bytes_moved = maximum; + return 0; +} + +/* + * IO Control entry point + */ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +#include + +static void hurricane_output_char(char c) { outbyte( c ); } + +BSP_output_char_function_type BSP_output_char = hurricane_output_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; + diff --git a/bsps/mips/jmr3904/console/console-io.c b/bsps/mips/jmr3904/console/console-io.c new file mode 100644 index 0000000000..a7f3204d25 --- /dev/null +++ b/bsps/mips/jmr3904/console/console-io.c @@ -0,0 +1,123 @@ +/* + * This file contains the hardware specific portions of the TTY driver + * for the serial ports on the jmr3904. + * + * Logic based on the jmr3904-io.c file in newlib 1.8.2 + */ + +/* + * COPYRIGHT (c) 1989-2000. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include + +/* external prototypes for monitor interface routines */ + +#define READ_UINT8( _register_, _value_ ) \ + ((_value_) = *((volatile unsigned char *)(_register_))) + +#define WRITE_UINT8( _register_, _value_ ) \ + (*((volatile unsigned char *)(_register_)) = (_value_)) + +#define READ_UINT16( _register_, _value_ ) \ + ((_value_) = *((volatile unsigned short *)(_register_))) + +#define WRITE_UINT16( _register_, _value_ ) \ + (*((volatile unsigned short *)(_register_)) = (_value_)) + + /* - Board specific addresses for serial chip */ +#define DIAG_BASE 0xfffff300 +#define DIAG_SLCR (DIAG_BASE+0x00) +#define DIAG_SLSR (DIAG_BASE+0x04) +#define DIAG_SLDICR (DIAG_BASE+0x08) +#define DIAG_SLDISR (DIAG_BASE+0x0C) +#define DIAG_SFCR (DIAG_BASE+0x10) +#define DIAG_SBRG (DIAG_BASE+0x14) +#define DIAG_TFIFO (DIAG_BASE+0x20) +#define DIAG_RFIFO (DIAG_BASE+0x30) + +#define BRG_T0 0x0000 +#define BRG_T2 0x0100 +#define BRG_T4 0x0200 +#define BRG_T5 0x0300 + +/* + * Eventually console-polled.c should hook to this better. + */ + +/* + * console_initialize_hardware + * + * This routine initializes the console hardware. + * + */ + +void console_initialize_hardware(void) +{ + WRITE_UINT16 (DIAG_SLCR, 0x0020); + WRITE_UINT16 (DIAG_SLDICR, 0x0000); + WRITE_UINT16 (DIAG_SFCR, 0x0000); + WRITE_UINT16 (DIAG_SBRG, BRG_T2 | 5); +} + +/* + * console_outbyte_polled + * + * This routine transmits a character using polling. + */ + +void console_outbyte_polled( + int port, + char ch +) +{ + unsigned short disr; + + for (;;) { + READ_UINT16 (DIAG_SLDISR, disr); + if (disr & 0x0002) + break; + } + disr = disr & ~0x0002; + WRITE_UINT8 (DIAG_TFIFO, (unsigned char) ch); + WRITE_UINT16 (DIAG_SLDISR, disr); +} + +/* + * console_inbyte_nonblocking + * + * This routine polls for a character. + */ + +int console_inbyte_nonblocking( + int port +) +{ + unsigned char c; + unsigned short disr; + + READ_UINT16 (DIAG_SLDISR, disr); + if (disr & 0x0001) { + disr = disr & ~0x0001; + READ_UINT8 (DIAG_RFIFO, c); + WRITE_UINT16 (DIAG_SLDISR, disr); + return (char) c; + } + return -1; +} + +#include + +static void JMR3904_output_char(char c) { console_outbyte_polled( 0, c ); } + +BSP_output_char_function_type BSP_output_char = JMR3904_output_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/mips/malta/console/conscfg.c b/bsps/mips/malta/console/conscfg.c new file mode 100644 index 0000000000..8d84c9321c --- /dev/null +++ b/bsps/mips/malta/console/conscfg.c @@ -0,0 +1,158 @@ +/** + * @file + * + * This file contains the libchip configuration information + * to instantiate the libchip driver for the serial ports. + */ + +/* + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include /* write */ + +#include +#include +#include +#include +#include + +#if 1 +#define COM_CONSOLE_FUNCTIONS &ns16550_fns_polled +#else +#define COM_CONSOLE_FUNCTIONS &ns16550_fns +#endif + +/* + * Base IO for UART + */ +#define COM1_BASE_IO 0x3F8 +#define COM2_BASE_IO 0x3E8 + +// #define CLOCK_RATE 368640 +#define CLOCK_RATE (115200 * 16) + +#define COM_IO_BASE_ADDRESS (0xa0000000UL | 0x18000000UL) + +static uint8_t com_get_register(uintptr_t addr, uint8_t i); +static void com_set_register(uintptr_t addr, uint8_t i, uint8_t val); +static uint8_t tty2_get_register(uintptr_t addr, uint8_t i); +static void tty2_set_register(uintptr_t addr, uint8_t i, uint8_t val); + + +uint8_t com_get_register(uintptr_t addr, uint8_t i) +{ + uint8_t val; + volatile uint8_t *ptr; + ptr = (volatile uint8_t *) COM_IO_BASE_ADDRESS; + ptr += addr; + ptr += i; + val = *ptr; + + return val; +} + +void com_set_register(uintptr_t addr, uint8_t i, uint8_t val) +{ + volatile uint8_t *ptr; + + ptr = (volatile uint8_t *) COM_IO_BASE_ADDRESS; + ptr += addr; + ptr += i; + *ptr = val; +} + +uint8_t tty2_get_register(uintptr_t addr, uint8_t i) +{ + uint8_t val; + volatile uint8_t *ptr; + + ptr = (volatile uint8_t *) COM_IO_BASE_ADDRESS; + ptr += addr; + ptr += (i * 8); + val = *ptr; + + return val; +} + +void tty2_set_register(uintptr_t addr, uint8_t i, uint8_t val) +{ + volatile uint8_t *ptr; + + ptr = (volatile uint8_t *) COM_IO_BASE_ADDRESS; + ptr += addr; + ptr += (i * 8); + *ptr = val; +} + +console_tbl Console_Configuration_Ports[] = { + { + "/dev/tty0", /* sDeviceName */ + SERIAL_NS16550, /* deviceType */ + COM_CONSOLE_FUNCTIONS, /* pDeviceFns */ + NULL, /* deviceProbe, assume it is there */ + NULL, /* pDeviceFlow */ + 16, /* ulMargin */ + 8, /* ulHysteresis */ + (void *) 9600, /* Baud Rate */ /* pDeviceParams */ + COM1_BASE_IO, /* ulCtrlPort1 */ + 0x00000000, /* ulCtrlPort2 */ + COM1_BASE_IO, /* ulDataPort */ + com_get_register, /* getRegister */ + com_set_register, /* setRegister */ + NULL,/* unused */ /* getData */ + NULL,/* unused */ /* setData */ + CLOCK_RATE, /* ulClock */ + MALTA_IRQ_TTY0 /* ulIntVector -- base for port */ + }, + { + "/dev/tty1", /* sDeviceName */ + SERIAL_NS16550, /* deviceType */ + COM_CONSOLE_FUNCTIONS, /* pDeviceFns */ + NULL, /* deviceProbe, assume it is there */ + NULL, /* pDeviceFlow */ + 16, /* ulMargin */ + 8, /* ulHysteresis */ + (void *) 9600, /* Baud Rate */ /* pDeviceParams */ + COM2_BASE_IO, /* ulCtrlPort1 */ + 0x00000000, /* ulCtrlPort2 */ + COM2_BASE_IO, /* ulDataPort */ + com_get_register, /* getRegister */ + com_set_register, /* setRegister */ + NULL,/* unused */ /* getData */ + NULL,/* unused */ /* setData */ + CLOCK_RATE, /* ulClock */ + MALTA_IRQ_TTY1 /* ulIntVector -- base for port */ + }, + { + "/dev/tty2", /* sDeviceName */ + SERIAL_NS16550, /* deviceType */ + COM_CONSOLE_FUNCTIONS, /* pDeviceFns */ + NULL, /* deviceProbe, assume it is there */ + NULL, /* pDeviceFlow */ + 16, /* ulMargin */ + 8, /* ulHysteresis */ + (void *) 9600, /* Baud Rate */ /* pDeviceParams */ + 0, /* IGNORED */ /* ulCtrlPort1 */ + 0, /* IGNORED */ /* ulCtrlPort2 */ + 0, /* IGNORED */ /* ulDataPort */ + tty2_get_register, /* getRegister */ + tty2_set_register, /* setRegister */ + NULL,/* unused */ /* getData */ + NULL,/* unused */ /* setData */ + CLOCK_RATE, /* ulClock */ + MALTA_CPU_INT2 /* ulIntVector -- base for port */ + }, +}; + +/* + * Define a variable that contains the number of statically configured + * console devices. + */ +unsigned long Console_Configuration_Count = \ + (sizeof(Console_Configuration_Ports)/sizeof(console_tbl)); diff --git a/bsps/mips/malta/console/printk_support.c b/bsps/mips/malta/console/printk_support.c new file mode 100644 index 0000000000..e548485222 --- /dev/null +++ b/bsps/mips/malta/console/printk_support.c @@ -0,0 +1,54 @@ +/** + * @file + * + * This file contains a stub for the required printk support. + */ + +/* + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include + +rtems_device_minor_number BSPPrintkPort = 0; + +void BSP_com_outch(char ch); +int BSP_com_inch( void ); + +/* + * Following assume all are ns16650 + */ +void BSP_com_outch(char ch) +{ + console_tbl *cptr; + + cptr = &Console_Configuration_Ports[BSPPrintkPort]; + + return ns16550_outch_polled( cptr, ch ); +} + +int BSP_com_inch( void ) +{ + int result; + console_tbl *cptr; + + cptr = &Console_Configuration_Ports[BSPPrintkPort]; + + do { + result = ns16550_inch_polled( cptr ); + } while (result == -1); + + return result; +} + +BSP_output_char_function_type BSP_output_char = BSP_com_outch; +BSP_polling_getchar_function_type BSP_poll_char = BSP_com_inch; diff --git a/bsps/mips/rbtx4925/console/console-io.c b/bsps/mips/rbtx4925/console/console-io.c new file mode 100644 index 0000000000..75cca1ebbd --- /dev/null +++ b/bsps/mips/rbtx4925/console/console-io.c @@ -0,0 +1,206 @@ +/* + * This file contains the RBTX4925 console IO package. + */ + +/* + * Author: Craig Lebakken + * + * COPYRIGHT (c) 1996 by Transition Networks Inc. + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Transition Networks not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * Transition Networks makes no representations about the suitability + * of this software for any purpose. + * + * Derived from c/src/lib/libbsp/no_cpu/no_bsp/console/console.c: + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include +#include +#include + +/* PMON entry points */ +int mon_read(int fd, char *buf, int cnt); /* stdin is fd=0 */ +int mon_write(int fd, char *buf, int cnt); /* stdout is fd=1 */ + +/* console_initialize + * + * This routine initializes the console IO driver. + */ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + + status = rtems_io_register_name( + "/dev/console", + major, + (rtems_device_minor_number) 0 + ); + + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + return RTEMS_SUCCESSFUL; +} + +/* inbyte + * + * This routine reads a character from the SOURCE. + */ +static char inbyte( void ) +{ + char buf[10]; + + /* + * If polling, wait until a character is available. + */ + + mon_read(0, buf, 1); /* stdin is fd=0, read 1 byte */ + + return (buf[0]); +} + +/* outbyte + * + * This routine transmits a character out the SOURCE. It may support + * XON/XOFF flow control. + */ +static void outbyte( + char ch +) +{ + char buf[10]; + + /* + * If polling, wait for the transmitter to be ready. + * Check for flow control requests and process. + * Then output the character. + */ + buf[0] = ch; + + mon_write( 1, buf, 1 ); /* stdout is fd=1, write 1 byte */ +} + +/* + * Open entry point + */ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * Close entry point + */ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * read bytes from the serial port. We only have stdin. + */ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args; + char *buffer; + int maximum; + int count = 0; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + buffer[ count ] = inbyte(); + if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { + buffer[ count++ ] = '\n'; + break; + } + } + + rw_args->bytes_moved = count; + return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; +} + +/* + * write bytes to the serial port. Stdout and stderr are the same. + */ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + int count; + int maximum; + rtems_libio_rw_args_t *rw_args; + char *buffer; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + if ( buffer[ count ] == '\n') { + outbyte('\r'); + } + outbyte( buffer[ count ] ); + } + + rw_args->bytes_moved = maximum; + return 0; +} + +/* + * IO Control entry point + */ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +#include + +static void RBTX4925_output_char(char c) { outbyte( c ); } + +BSP_output_char_function_type BSP_output_char = RBTX4925_output_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; + diff --git a/bsps/mips/rbtx4938/console/console-io.c b/bsps/mips/rbtx4938/console/console-io.c new file mode 100644 index 0000000000..b0dbc3b365 --- /dev/null +++ b/bsps/mips/rbtx4938/console/console-io.c @@ -0,0 +1,209 @@ +/* + * This file contains the RBTX4938 console IO package. + */ + +/* + * Author: Craig Lebakken + * + * COPYRIGHT (c) 1996 by Transition Networks Inc. + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Transition Networks not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * Transition Networks makes no representations about the suitability + * of this software for any purpose. + * + * Derived from c/src/lib/libbsp/no_cpu/no_bsp/console/console.c: + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include +#include +#include + +#include "yamon_api.h" + +/* PMON entry points */ +int mon_read(int fd, char *buf, int cnt); /* stdin is fd=0 */ +int mon_write(int fd, char *buf, int cnt); /* stdout is fd=1 */ + + +/* console_initialize + * + * This routine initializes the console IO driver. + */ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + + status = rtems_io_register_name( + "/dev/console", + major, + (rtems_device_minor_number) 0 + ); + + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + return RTEMS_SUCCESSFUL; +} + +/* inbyte + * + * This routine reads a character from the SOURCE. + */ +static char inbyte( void ) +{ + char buf[10]; + + /* + * If polling, wait until a character is available. + */ + while (YAMON_FUNC_GETCHAR(buf) == YAMON_FALSE); + + return (buf[0]); +} + +/* outbyte + * + * This routine transmits a character out the SOURCE. It may support + * XON/XOFF flow control. + */ +static void outbyte( + char ch +) +{ + char buf[10]; + + /* + * If polling, wait for the transmitter to be ready. + * Check for flow control requests and process. + * Then output the character. + */ + buf[0] = ch; + + YAMON_FUNC_PRINT_COUNT(buf,1); +} + +/* + * Open entry point + */ + +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * Close entry point + */ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * read bytes from the serial port. We only have stdin. + */ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args; + char *buffer; + int maximum; + int count = 0; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + buffer[ count ] = inbyte(); + if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { + buffer[ count++ ] = '\n'; + break; + } + } + + rw_args->bytes_moved = count; + return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; +} + +/* + * write bytes to the serial port. Stdout and stderr are the same. + */ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + int count; + int maximum; + rtems_libio_rw_args_t *rw_args; + char *buffer; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + if ( buffer[ count ] == '\n') { + outbyte('\r'); + } + outbyte( buffer[ count ] ); + } + + rw_args->bytes_moved = maximum; + return 0; +} + +/* + * IO Control entry point + */ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +#include + +static void RBTX4938_output_char(char c) { outbyte( c ); } + +BSP_output_char_function_type BSP_output_char = RBTX4938_output_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; + diff --git a/bsps/mips/rbtx4938/console/yamon_api.h b/bsps/mips/rbtx4938/console/yamon_api.h new file mode 100644 index 0000000000..529cf16a3f --- /dev/null +++ b/bsps/mips/rbtx4938/console/yamon_api.h @@ -0,0 +1,631 @@ +/************************************************************************ + * + * yamon_api.h + * + * YAMON interface definitions + * + * ###################################################################### + * + * mips_start_of_legal_notice + * + * Copyright (c) 2003 MIPS Technologies, Inc. All rights reserved. + * + * + * Unpublished rights (if any) reserved under the copyright laws of the + * United States of America and other countries. + * + * This code is proprietary to MIPS Technologies, Inc. ("MIPS + * Technologies"). Any copying, reproducing, modifying or use of this code + * (in whole or in part) that is not expressly permitted in writing by MIPS + * Technologies or an authorized third party is strictly prohibited. At a + * minimum, this code is protected under unfair competition and copyright + * laws. Violations thereof may result in criminal penalties and fines. + * + * MIPS Technologies reserves the right to change this code to improve + * function, design or otherwise. MIPS Technologies does not assume any + * liability arising out of the application or use of this code, or of any + * error or omission in such code. Any warranties, whether express, + * statutory, implied or otherwise, including but not limited to the implied + * warranties of merchantability or fitness for a particular purpose, are + * excluded. Except as expressly provided in any written license agreement + * from MIPS Technologies or an authorized third party, the furnishing of + * this code does not give recipient any license to any intellectual + * property rights, including any patent rights, that cover this code. + * + * This code shall not be exported or transferred for the purpose of + * reexporting in violation of any U.S. or non-U.S. regulation, treaty, + * Executive Order, law, statute, amendment or supplement thereto. + * + * This code constitutes one or more of the following: commercial computer + * software, commercial computer software documentation or other commercial + * items. If the user of this code, or any related documentation of any + * kind, including related technical data or manuals, is an agency, + * department, or other entity of the United States government + * ("Government"), the use, duplication, reproduction, release, + * modification, disclosure, or transfer of this code, or any related + * documentation of any kind, is restricted in accordance with Federal + * Acquisition Regulation 12.212 for civilian agencies and Defense Federal + * Acquisition Regulation Supplement 227.7202 for military agencies. The use + * of this code by the Government is further restricted in accordance with + * the terms of the license agreement(s) and/or applicable contract terms + * and conditions covering this code from MIPS Technologies or an authorized + * third party. + * + * + * mips_end_of_legal_notice + * + * + ************************************************************************/ + +#ifndef YAMON_API_H +#define YAMON_API_H + +/************************************************************************ + * Include files + ************************************************************************/ + + +/************************************************************************ + * Definitions +*************************************************************************/ + +/* Basic types */ + +typedef unsigned int t_yamon_uint32; +typedef unsigned short t_yamon_uint16; +typedef unsigned char t_yamon_uint8; +typedef signed int t_yamon_int32; +typedef signed short t_yamon_int16; +typedef signed char t_yamon_int8; + +typedef unsigned char t_yamon_bool; + +#define YAMON_FALSE 0 +#define YAMON_TRUE (!YAMON_FALSE) + +/* YAMON Environment variable */ +typedef struct +{ + char *name; + char *val; +} +t_yamon_env_var; + +/* Format of application function */ +typedef t_yamon_uint32 +(*t_yamon_appl_main)( + t_yamon_uint32 argc, /* Number of tokens in argv array */ + char **argv, /* Array of tokens (first is "go") */ + t_yamon_env_var *env, /* Array of env. variables */ + t_yamon_uint32 memsize ); /* Size of memory (byte count) */ + + +/* ID of YAMON configuration object */ +typedef t_yamon_uint32 t_yamon_syscon_id; + + +/* Number used by the exception registration functions in order to register + * a default ISR/ESR. + */ +#define YAMON_DEFAULT_HANDLER 0xfffffff0 + +/* Number used by the exception registration functions in order to register + * an EJTAG debug exception ESR. + */ +#define YAMON_DEFAULT_EJTAG_ESR 0xfffffff1 + +/* Registered Interrupt Service Routine (ISR) */ +typedef void (*t_yamon_isr)(void *data); + +/* Registered Exception Service Routine (ESR) */ +typedef void (*t_yamon_esr)(void); + +/* Entry point called by ESRs wishing to pass control back to YAMON */ +typedef void (*t_yamon_retfunc)(void); + +/* Handle used for deregistration of ISR/ESR */ +typedef void *t_yamon_ref; + + +/* YAMONE Vector table address */ +#define YAMON_FUNCTION_BASE 0x9fc00500 + +/* YAMON Vector table offsets */ +#define YAMON_FUNC_PRINT_COUNT_OFS 0x04 +#define YAMON_FUNC_EXIT_OFS 0x20 +#define YAMON_FUNC_FLUSH_CACHE_OFS 0x2C +#define YAMON_FUNC_PRINT_OFS 0x34 +#define YAMON_FUNC_REGISTER_CPU_ISR_OFS 0x38 +#define YAMON_FUNC_DEREGISTER_CPU_ISR_OFS 0x3c +#define YAMON_FUNC_REGISTER_IC_ISR_OFS 0x40 +#define YAMON_FUNC_DEREGISTER_IC_ISR_OFS 0x44 +#define YAMON_FUNC_REGISTER_ESR_OFS 0x48 +#define YAMON_FUNC_DEREGISTER_ESR_OFS 0x4c +#define YAMON_FUNC_GETCHAR_OFS 0x50 +#define YAMON_FUNC_SYSCON_READ_OFS 0x54 + +/* Macro for accessing YAMON function */ +#define YAMON_FUNC(ofs)\ + (*(t_yamon_uint32 *)(YAMON_FUNCTION_BASE + (ofs))) + + +/************************************************************************ + * Public variables + ************************************************************************/ + +/************************************************************************ + * Public functions + ************************************************************************/ + + +/************************************************************************ + * + * t_yamon_exit + * Description : + * ------------- + * + * Exit application and return to YAMON. + * + * Parameters : + * ------------ + * + * 'rc' (OUT) : Return code + * + * Return values : + * --------------- + * + * None (never returns) + * + ************************************************************************/ +typedef void +(*t_yamon_exit)( + t_yamon_uint32 rc ); /* Return code */ + +#define YAMON_FUNC_EXIT( rc )\ + ((t_yamon_exit)( YAMON_FUNC(YAMON_FUNC_EXIT_OFS) ))\ + ( rc ) + + +/************************************************************************ + * + * t_yamon_print + * Description : + * ------------- + * + * Print null-terminated string to tty0. + * + * Parameters : + * ------------ + * + * 'port' (OUT) : Ignored, always prints to tty0. Not included in macro. + * 's' (OUT) : String to print. + * + * Return values : + * --------------- + * + * None + * + ************************************************************************/ +typedef void +(*t_yamon_print)( + t_yamon_uint32 port, /* Output port (not used, always tty0) */ + const char *s ); /* String to output */ + +#define YAMON_FUNC_PRINT( s )\ + ((t_yamon_print)( YAMON_FUNC(YAMON_FUNC_PRINT_OFS) ))\ + ( 0, s ) + + +/************************************************************************ + * + * t_yamon_print_count + * Description : + * ------------- + * + * Print specified number of characters to tty0. + * + * Parameters : + * ------------ + * + * 'port' (OUT) : Ignored, always prints to tty0. Not included in macro. + * 's' (OUT) : Array of characters to print. + * 'count' (OUT) : Number of characters to print. + * + * Return values : + * --------------- + * + * None + * + ************************************************************************/ +typedef void +(*t_yamon_print_count)( + t_yamon_uint32 port, /* Output port (not used, always tty0 */ + char *s, /* String to output */ + t_yamon_uint32 count ); /* Number of characters to output */ + +#define YAMON_FUNC_PRINT_COUNT( s, count )\ + ((t_yamon_print_count)( YAMON_FUNC(YAMON_FUNC_PRINT_COUNT_OFS) ))\ + ( 0, s, count ) + + +/************************************************************************ + * + * t_yamon_getchar + * Description : + * ------------- + * + * Get character from tty0 if character is available. Function + * returns immediately if no character is available. + * + * Parameters : + * ------------ + * + * 'port' (OUT) : Ignored, always uses tty0. Not included in macro. + * 'ch' (OUT) : Character read (if available). + * + * Return values : + * --------------- + * + * YAMON_TRUE if character was available, else YAMON_FALSE. + * + ************************************************************************/ +typedef t_yamon_bool +(*t_yamon_getchar)( + t_yamon_uint32 port, /* Output port (not used, always tty0 */ + char *ch ); /* Character to output */ + +#define YAMON_FUNC_GETCHAR( ch )\ + ((t_yamon_getchar)( YAMON_FUNC(YAMON_FUNC_GETCHAR_OFS) ))\ + ( 0, ch ) + + +/************************************************************************ + * + * t_yamon_syscon_read + * Description : + * ------------- + * + * Read the value of system configuration object given by 'id'. + * + * See syscon_api.h in YAMON source distribution for further details + * on object IDs and error codes. + * + * Parameters : + * ------------ + * + * 'id' (IN) : Object id. + * 'param' (INOUT) : Buffer for object value. + * 'size' (IN) : Size of buffer (must match size of object). + * + * Return values : + * --------------- + * + * 0 : Returned parameter is valid. + * Other values indicate error. + * + ************************************************************************/ +typedef t_yamon_int32 +(*t_yamon_syscon_read)( + t_yamon_syscon_id id, /* Object ID */ + void *param, /* Buffer for object value */ + t_yamon_uint32 size); /* Buffer size (bytes) */ + +#define YAMON_FUNC_SYSCON_READ( id, param, size )\ + ((t_yamon_syscon_read)( YAMON_FUNC(YAMON_FUNC_SYSCON_READ_OFS) ))\ + ( id, param, size ) + + +/************************************************************************ + * + * t_yamon_flush_cache + * Description : + * ------------- + * + * Flush I-or D-cache + * + * Function performs "writeback and invalidate" operations on D-cache + * lines and "invalidate" operations on I-cache lines. + * + * Parameters : + * ------------ + * + * 'type' (IN) : Cache to be flushed. + * + * Return values : + * --------------- + * + * None + * + ************************************************************************/ +typedef void +(*t_yamon_flush_cache)( +#define YAMON_FLUSH_ICACHE 0 +#define YAMON_FLUSH_DCACHE 1 + t_yamon_uint32 type ); /* I- or D-cache indication */ + +#define YAMON_FUNC_FLUSH_CACHE( type )\ + ((t_yamon_flush_cache)( YAMON_FUNC(YAMON_FUNC_FLUSH_CACHE_OFS) ))\ + ( type ) + + +/************************************************************************ + * + * t_yamon_register_esr + * Description : + * ------------- + * + * Registers an exception handler, also known as an "Exception Service + * Routine" (ESR) for the specified exception. + * + * Two special exception IDs are defined : + * YAMON_DEFAULT_HANDLER used for a default ESR. + * YAMON_DEFAULT_EJTAG_ESR used for EJTAG exceptions. + * + * The default ESR is called if no other ESR is registered + * for an exception. If no default ESR is registered, a static + * (i.e. not registered) "super default" function is invoked. + * This function prints out the registers and halts. + * + * Deregistration of an ESR may be be done by calling this function + * with 'esr' set to NULL. + * An ESR can also be deregistered using the 'yamon_deregister_esr' + * function. + * + * An ESR may be registered even if a previously registered + * ESR has not been deregistered. In this case the previously + * registered ESR is lost. + * + * The ESR will get called with registers in the state they were + * when the exception occurred. This includes all CP0 registers and + * CPU registers $0..$31, except for k0,k1 ($26,$27). + * + * In case an ESR does not want to handle the exception, it may + * call the return function passed in the 'retfunc' parameter. + * + * Case 1 : 'retfunc' called by ESR registered for the + * INTERRUPT exception. + * + * We assume an application has registered this ESR and wants + * YAMON to process the (remaining) interrupts. + * + * Case 2 : 'retfunc' called by an ESR registered for a specific + * exception (not INTERRUPT). + * + * Default handling will be done. + * + * Case 3 : 'retfunc' is called by the ESR registered as default ESR. + * + * The exception will be handled as though no ESR is registered + * (i.e. the "super default" function is called). + * + * Parameters : + * ------------ + * + * 'exception' (IN) : Exception code + * or YAMON_DEFAULT_HANDLER for a default ESR + * or YAMON_DEFAULT_EJTAG_ESR for ejtag exceptions. + * 'esr' (IN) : Function pointer for ESR. + * 'ref' (OUT) : Handle used for deregistration of ESR. + * 'retfunc' (OUT) : Pointer to function pointer for the return + * function described above. + * + * Return values : + * --------------- + * + * 0 : Registration went well. + * Other values indicate error. + * + ************************************************************************/ +typedef t_yamon_int32 +(*t_yamon_register_esr)( + t_yamon_uint32 exception, /* Exception identification */ + t_yamon_esr esr, /* ESR to be registered */ + t_yamon_ref *ref, /* Handle for deregistration */ + t_yamon_retfunc *retfunc ); /* Return function */ + +#define YAMON_FUNC_REGISTER_ESR( exc, esr, ref, retfunc )\ + ((t_yamon_register_esr)( YAMON_FUNC(YAMON_FUNC_REGISTER_ESR_OFS) ))\ + ( exc, esr, ref, retfunc ) + + +/************************************************************************ + * + * t_yamon_deregister_esr + * Description : + * ------------- + * + * Deregisters ESR.. + * + * Parameters : + * ------------ + * + * 'ref' (IN) : Handle obtained when calling 'yamon_register_esr'. + * + * Return values : + * --------------- + * + * 0 : Deregistration went well. + * Other values indicate error. + * + ************************************************************************/ +typedef t_yamon_int32 +(*t_yamon_deregister_esr)( + t_yamon_ref ref ); /* Handle for deregistration */ + +#define YAMON_FUNC_DEREGISTER_ESR( ref )\ + ((t_yamon_deregister_esr)( YAMON_FUNC(YAMON_FUNC_DEREGISTER_ESR_OFS) ))\ + ( ref ) + + +/************************************************************************ + * + * t_yamon_register_cpu_isr + * Description : + * ------------- + * + * Registers an Interrupt Service Routine (ISR) for the specified + * CPU interrupt. + * The highest service priority is attached to HW-INT5, which is + * connected to the CPU-built-in CP0-timer. SW_INT0 gets the lowest + * service priority. During registration, the interrupt mask field + * in the CPU CP0-status register is updated to enable interrupts + * from the specified interrupt source. + * + * A special ID is defined : + * YAMON_DEFAULT_HANDLER used for a default ISR. + * + * The default ISR is called if no other ISR is registered + * for a CPU interrupt. + * + * Deregistration of the default ISR may be done by calling + * this function with 'isr' set to NULL. + * Also, a new default ISR may be registered even if a + * previously registered ISR has not been deregistered. + * ISRs for specific CPU interrupts must be deregistered using + * 'yamon_deregister_cpu_isr'. + * + * Parameters : + * ------------ + * + * 'cpu_int' (IN) : CPU interrupt (0..7) + * or YAMON_DEFAULT_HANDLER for a default ISR. + * 'isr' (IN) : Function pointer for ISR. + * 'data' (IN) : Data pointer (may be NULL). Will be passed to + * ISR when called. + * 'ref' (OUT) : Handle used for deregistration of ISR. + * + * Return values : + * --------------- + * + * 0 : Registration went well. + * Other values indicate error. + * + ************************************************************************/ +typedef t_yamon_int32 +(*t_yamon_register_cpu_isr)( + t_yamon_uint32 cpu_int, /* CPU interrupt (0..7) */ + t_yamon_isr isr, /* ISR to be registered */ + void *data, /* Data reference to be registered */ + t_yamon_ref *ref ); /* Handle for deregistration */ + +#define YAMON_FUNC_REGISTER_CPU_ISR( cpu_int, isr, data, ref )\ + ((t_yamon_register_cpu_isr)( YAMON_FUNC(YAMON_FUNC_REGISTER_CPU_ISR_OFS) ))\ + ( cpu_int, isr, data, ref ) + + +/************************************************************************ + * + * t_yamon_deregister_cpu_isr + * Description : + * ------------- + * + * Deregisters ISR for CPU interrupt. + * + * Parameters : + * ------------ + * + * 'ref' (IN) : Handle obtained when calling 'yamon_register_cpu_isr'. + * + * Return values : + * --------------- + * + * 0 : Deregistration went well. + * Other values indicate error + * + ************************************************************************/ +typedef t_yamon_int32 +(*t_yamon_deregister_cpu_isr)( + t_yamon_ref ref ); /* Handle for deregistration */ + +#define YAMON_FUNC_DEREGISTER_CPU_ISR( ref )\ + ((t_yamon_deregister_cpu_isr)( YAMON_FUNC(YAMON_FUNC_DEREGISTER_CPU_ISR_OFS) ))\ + ( ref ) + + +/************************************************************************ + * + * t_yamon_register_ic_isr + * Description : + * ------------- + * + * Registers an Interrupt Service Routine (ISR) for the specified + * source in the interrupt controller. + * + * A special ID is defined : + * YAMON_DEFAULT_HANDLER used for a default ISR. + * + * The default ISR is called if no other ISR is registered + * for an interrupt. + * + * Deregistration of the default ISR may be done by calling + * this function with 'isr' set to NULL. + * Also, a new default ISR may be registered even if a + * previously registered ISR has not been deregistered. + * ISRs for specific interrupts must be deregistered using + * 'yamon_deregister_ic_isr'. + * + * Parameters : + * ------------ + * + * 'ic_line' (IN) : Interrupt source line in Int. Controller + * or YAMON_DEFAULT_HANDLER for a default ISR. + * 'isr', (IN) : Function pointer for user defined ISR. + * 'data' (IN) : Data pointer (may be NULL). Will be passed to + * ISR when called. + * 'ref', (OUT) : Handle used for deregistration of ISR. + * + * Return values : + * --------------- + * + * 0 : Registration went well. + * Other values indicate error. + * + ************************************************************************/ +typedef t_yamon_int32 +(*t_yamon_register_ic_isr)( + t_yamon_uint32 ic_line, /* Interrupt controller line */ + t_yamon_isr isr, /* ISR to be registered */ + void *data, /* Data reference to be registered */ + t_yamon_ref *ref ); /* Handle for deregistration */ + +#define YAMON_FUNC_REGISTER_IC_ISR( ic_line, isr, data, ref )\ + ((t_yamon_register_ic_isr)( YAMON_FUNC(YAMON_FUNC_REGISTER_IC_ISR_OFS) ))\ + ( ic_line, isr, data, ref ) + + +/************************************************************************ + * + * t_yamon_deregister_ic_isr + * Description : + * ------------- + * + * Deregisters ISR for source in interrupt controller. + * + * Parameters : + * ------------ + * + * 'ref' (IN) : Handle obtained when calling 'yamon_register_ic_isr'. + * + * Return values : + * --------------- + * + * 0 : Deregistration went well. + * Other values indicate error + * + ************************************************************************/ +typedef t_yamon_int32 +(*t_yamon_deregister_ic_isr)( + t_yamon_ref ref ); /* Handle for deregistration */ + +#define YAMON_FUNC_DEREGISTER_IC_ISR( ref )\ + ((t_yamon_deregister_ic_isr)( YAMON_FUNC(YAMON_FUNC_DEREGISTER_IC_ISR_OFS) ))\ + ( ref ) + + +#endif /* #ifndef YAMON_API_H */ + + + + + + diff --git a/bsps/moxie/moxiesim/console/console-io.c b/bsps/moxie/moxiesim/console/console-io.c new file mode 100644 index 0000000000..de058eba8b --- /dev/null +++ b/bsps/moxie/moxiesim/console/console-io.c @@ -0,0 +1,69 @@ +/* + * This file contains the hardware specific portions of the TTY driver + * for the Moxie GDB simulator. + */ + +/* + * COPYRIGHT (c) 2011. + * Anthony Green. + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + */ + +#include +#include +#include +#include +#include + +/* + * console_initialize_hardware + * + * This routine initializes the console hardware. + * + */ + +void console_initialize_hardware(void) +{ + return; +} + +/* + * console_outbyte_polled + * + * This routine transmits a character using polling. + */ +ssize_t _sys_write(int fd, const void *buf, size_t count); +void console_outbyte_polled( + int port, + char ch +) +{ + _sys_write( 1, &ch, 1 ); +} + +/* + * console_inbyte_nonblocking + * + * This routine polls for a character. + */ + +int console_inbyte_nonblocking( + int port +) +{ + return -1; +} + +#include + +static void moxiesim_output_char(char c) { console_outbyte_polled( 0, c ); } + +BSP_output_char_function_type BSP_output_char = moxiesim_output_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/moxie/moxiesim/console/syscalls.S b/bsps/moxie/moxiesim/console/syscalls.S new file mode 100644 index 0000000000..f9a63a29b5 --- /dev/null +++ b/bsps/moxie/moxiesim/console/syscalls.S @@ -0,0 +1,15 @@ +/* + * System call support for simulator in gdb. + * + * COPYRIGHT (c) 2011 Anthony Green + */ + +#define SYS_write 5 + + .section .text + .align 2 + .global _sys_write +_sys_write: + swi SYS_write + ret + .end diff --git a/bsps/nios2/nios2_iss/console/console.c b/bsps/nios2/nios2_iss/console/console.c new file mode 100644 index 0000000000..9197c6486c --- /dev/null +++ b/bsps/nios2/nios2_iss/console/console.c @@ -0,0 +1,98 @@ +/* + * This file implements simple console IO via JTAG UART. + */ + +/* + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * Altera-specific code is + * COPYRIGHT (c) 2005-2006 Kolja Waschk, rtemsdev/ixo.de + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#define NO_BSP_INIT + +#include +#include +#include + +/* #define JTAG_UART_REGS \ + ((altera_avalon_jtag_uart_regs*)NIOS2_IO_BASE(JTAG_UART_BASE)) */ + +/* is_character_ready + * + * If a character is available, this routine reads it and stores + * it in reads the character and stores + */ +static bool is_character_ready( + char *ch +) +{ + altera_avalon_jtag_uart_regs *ajur = NIOS2_IO_BASE(JTAG_UART_BASE); + unsigned int data = ajur->data; + + if (data & ALTERA_AVALON_JTAG_UART_DATA_RVALID_MSK) { + *ch = (data & ALTERA_AVALON_JTAG_UART_DATA_DATA_MSK) + >> ALTERA_AVALON_JTAG_UART_DATA_DATA_OFST; + return true; + } + + return false; +} + +void console_initialize_hardware(void) +{ +} + +/* + * This routine reads a character from the SOURCE. + */ +int console_inbyte_nonblocking( + int port +) +{ + char ch; + + /* + * Wait until a character is available. + */ + if (is_character_ready(&ch)) + return ch; + return -1; +} + +/* + * This routine transmits a character out the SOURCE. + */ +void console_outbyte_polled( + int port, + char ch +) +{ + altera_avalon_jtag_uart_regs *ajur = NIOS2_IO_BASE(JTAG_UART_BASE); + + /* + * Wait for the transmitter to be ready. + * Check for flow control requests and process. + * Then output the character. + */ + while ((ajur->control & ALTERA_AVALON_JTAG_UART_CONTROL_WSPACE_MSK) == 0); + + ajur->data = ch; +} + +/* + * To support printk + */ + +#include + +static void ISS_output_char(char c) { console_outbyte_polled( 0, c ); } + +BSP_output_char_function_type BSP_output_char = ISS_output_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; + diff --git a/bsps/no_cpu/no_bsp/console/console.c b/bsps/no_cpu/no_bsp/console/console.c new file mode 100644 index 0000000000..41c17c29ef --- /dev/null +++ b/bsps/no_cpu/no_bsp/console/console.c @@ -0,0 +1,217 @@ +/* + * This file contains the template for a console IO package. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#define NO_BSP_INIT + +#include +#include + +/* console_initialize + * + * This routine initializes the console IO driver. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + + status = rtems_io_register_name( + "/dev/console", + major, + (rtems_device_minor_number) 0 + ); + + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + return RTEMS_SUCCESSFUL; +} + +/* is_character_ready + * + * This routine returns TRUE if a character is available. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +bool is_character_ready( + char *ch +) +{ + *ch = '\0'; /* return NULL for no particular reason */ + return true; +} + +/* inbyte + * + * This routine reads a character from the SOURCE. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + * character read from SOURCE + */ + +char inbyte( void ) +{ + /* + * If polling, wait until a character is available. + */ + + return '\0'; +} + +/* outbyte + * + * This routine transmits a character out the SOURCE. It may support + * XON/XOFF flow control. + * + * Input parameters: + * ch - character to be transmitted + * + * Output parameters: NONE + */ + +void outbyte( + char ch +) +{ + /* + * If polling, wait for the transmitter to be ready. + * Check for flow control requests and process. + * Then output the character. + */ + + /* + * Carriage Return/New line translation. + */ + + if ( ch == '\n' ) + outbyte( '\r' ); +} + +/* + * Open entry point + */ + +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * Close entry point + */ + +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * read bytes from the serial port. We only have stdin. + */ + +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args; + char *buffer; + int maximum; + int count = 0; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + buffer[ count ] = inbyte(); + if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { + buffer[ count++ ] = '\n'; + break; + } + } + + rw_args->bytes_moved = count; + return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; +} + +/* + * write bytes to the serial port. Stdout and stderr are the same. + */ + +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + int count; + int maximum; + rtems_libio_rw_args_t *rw_args; + char *buffer; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + if ( buffer[ count ] == '\n') { + outbyte('\r'); + } + outbyte( buffer[ count ] ); + } + + rw_args->bytes_moved = maximum; + return 0; +} + +/* + * IO Control entry point + */ + +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} diff --git a/bsps/or1k/generic_or1k/console/console-config.c b/bsps/or1k/generic_or1k/console/console-config.c new file mode 100644 index 0000000000..5fc75dcf0c --- /dev/null +++ b/bsps/or1k/generic_or1k/console/console-config.c @@ -0,0 +1,55 @@ +/** + * @file + * + * @ingroup generic_or1k_uart + * + * @brief Console Configuration. + */ + +/* + * Copyright (c) 2014-2015 Hesham ALMatary + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE + */ + +#include + +#include + +#include +#include +#include + +console_tbl Console_Configuration_Ports [] = { + { + .sDeviceName = "/dev/ttyS0", + .deviceType = SERIAL_CUSTOM, + .pDeviceFns = &generic_or1k_uart_fns, + .deviceProbe = NULL, + .pDeviceFlow = NULL, + .ulCtrlPort1 = OR1K_BSP_UART_BASE, + .ulCtrlPort2 = 0, + .ulClock = OR1K_UART_DEFAULT_BAUD, + .ulIntVector = OR1K_BSP_UART_IRQ + } +}; + +#define PORT_COUNT \ + (sizeof(Console_Configuration_Ports) \ + / sizeof(Console_Configuration_Ports [0])) + +unsigned long Console_Configuration_Count = PORT_COUNT; + +static void output_char(char c) +{ + const console_fns *con = + Console_Configuration_Ports [Console_Port_Minor].pDeviceFns; + + con->deviceWritePolled((int) Console_Port_Minor, c); +} + +BSP_output_char_function_type BSP_output_char = output_char; + +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/or1k/generic_or1k/console/uart.c b/bsps/or1k/generic_or1k/console/uart.c new file mode 100644 index 0000000000..6f8a49443d --- /dev/null +++ b/bsps/or1k/generic_or1k/console/uart.c @@ -0,0 +1,152 @@ +/** + * @file + * + * @ingroup generic_or1k_uart + * + * @brief UART support. + */ + +/* + * COPYRIGHT (c) 2014-2015 Hesham ALMatary + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE + */ + +#include +#include +#include +#include +#include +#include + +static void uart_initialize(int minor); +static int uart_first_open(int major, int minor, void *arg); +static int uart_last_close(int major, int minor, void *arg); +static int uart_read_polled(int minor); +static ssize_t uart_write(int minor, const char *buf, size_t len); +static void uart_write_polled(int minor, char c); +static int uart_set_attributes(int minor, const struct termios *t); + +#if 0 +/* + * These will be useful when the driver supports interrupt driven IO. + */ +static rtems_vector_number uart_get_irq_number(const console_tbl *ct) +{ + return ct->ulIntVector; +} + +static uint32_t uart_get_baud(const console_tbl *ct) +{ + return ct->ulClock; +} +#endif + +static void uart_set_baud(int baud) +{ + uint16_t divisor = (OR1K_BSP_CLOCK_FREQ) / (16 * baud); + OR1K_REG(OR1K_BSP_UART_REG_LINE_CTRL) = + OR1K_BSP_UART_REG_LINE_CTRL_DLAB; + + OR1K_REG(OR1K_BSP_UART_REG_DEV_LATCH_LOW) = divisor & 0xff; + + OR1K_REG(OR1K_BSP_UART_REG_DEV_LATCH_HIGH) = + (divisor >> 8); +} + +static void uart_initialize(int minor) +{ + /* Set baud rate */ + uart_set_baud(OR1K_UART_DEFAULT_BAUD); + + /* Set data pattern configuration */ + OR1K_REG(OR1K_BSP_UART_REG_LINE_CTRL) = + OR1K_BSP_UART_REG_LINE_CTRL_WLEN8; + + /* Reset receiver and transmitter */ + OR1K_REG(OR1K_BSP_UART_REG_FIFO_CTRL) = + OR1K_BSP_UART_REG_FIFO_CTRL_ENABLE_FIFO | + OR1K_BSP_UART_REG_FIFO_CTRL_CLEAR_RCVR | + OR1K_BSP_UART_REG_FIFO_CTRL_TRIGGER_14; + + /* Disable all interrupts */ + OR1K_REG(OR1K_BSP_UART_REG_INT_ENABLE) = 0x00; + +} + +static int uart_first_open(int major, int minor, void *arg) +{ + rtems_libio_open_close_args_t *oc = (rtems_libio_open_close_args_t *) arg; + struct rtems_termios_tty *tty = (struct rtems_termios_tty *) oc->iop->data1; + const console_tbl *ct = Console_Port_Tbl [minor]; + console_data *cd = &Console_Port_Data [minor]; + + cd->termios_data = tty; + rtems_termios_set_initial_baud(tty, ct->ulClock); + + return 0; +} + +static int uart_last_close(int major, int minor, void *arg) +{ + return 0; +} + +static int uart_read_polled(int minor) +{ + unsigned char lsr; + + /* Get a character when avaiable */ + do { + lsr = OR1K_REG(OR1K_BSP_UART_REG_LINE_STATUS); + } while ((lsr & OR1K_BSP_UART_REG_LINE_STATUS_DR) + != OR1K_BSP_UART_REG_LINE_STATUS_DR); + + return OR1K_REG(OR1K_BSP_UART_REG_RX); +} + +static void uart_write_polled(int minor, char c) +{ + unsigned char lsr; + + /* Wait until there is no pending data in the transmitter FIFO (empty) */ + do { + lsr = OR1K_REG(OR1K_BSP_UART_REG_LINE_STATUS); + } while (!(lsr & OR1K_BSP_UART_REG_LINE_STATUS_THRE)); + + OR1K_REG(OR1K_BSP_UART_REG_TX) = c; +} + +static ssize_t uart_write( + int minor, + const char *s, + size_t n +) +{ + ssize_t i = 0; + + for (i = 0; i < n; ++i){ + uart_write_polled(minor, s [i]); + } + + return n; +} + +static int uart_set_attributes(int minor, const struct termios *term) +{ + return -1; +} + +const console_fns generic_or1k_uart_fns = { + .deviceProbe = libchip_serial_default_probe, + .deviceFirstOpen = uart_first_open, + .deviceLastClose = uart_last_close, + .deviceRead = uart_read_polled, + .deviceWrite = uart_write, + .deviceInitialize = uart_initialize, + .deviceWritePolled = uart_write_polled, + .deviceSetAttributes = uart_set_attributes, + .deviceOutputUsesInterrupts = false +}; diff --git a/bsps/powerpc/gen5200/console/console.c b/bsps/powerpc/gen5200/console/console.c new file mode 100644 index 0000000000..d7325032c4 --- /dev/null +++ b/bsps/powerpc/gen5200/console/console.c @@ -0,0 +1,835 @@ +/*===============================================================*\ +| Project: RTEMS generic MPC5200 BSP | ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2005 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.org/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the console driver functions | +\*===============================================================*/ +/***********************************************************************/ +/* */ +/* Module: console.c */ +/* Date: 07/17/2003 */ +/* Purpose: RTEMS MPC5x00 console driver */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Description: */ +/* */ +/* The PSCs of mpc5200 are assigned as follows */ +/* */ +/* Channel Device Minor Note */ +/* PSC1 /dev/tty0 0 */ +/* PSC2 /dev/tty1 1 */ +/* PSC3 /dev/tty2 2 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Code */ +/* References: Serial driver for MPC8260ads */ +/* Module: console-generic.c */ +/* Project: RTEMS 4.6.0pre1 / MPC8260ads BSP */ +/* Version 1.3 */ +/* Date: 2002/11/04 */ +/* */ +/* Author(s) / Copyright(s): */ +/* */ +/* Author: Jay Monkman (jmonkman@frasca.com) */ +/* Copyright (C) 1998 by Frasca International, Inc. */ +/* */ +/* Derived from c/src/lib/libbsp/m68k/gen360/console/console.c */ +/* written by: */ +/* W. Eric Norum */ +/* Saskatchewan Accelerator Laboratory */ +/* University of Saskatchewan */ +/* Saskatoon, Saskatchewan, CANADA */ +/* eric@skatter.usask.ca */ +/* */ +/* COPYRIGHT (c) 1989-2008. */ +/* On-Line Applications Research Corporation (OAR). */ +/* */ +/* Modifications by Darlene Stewart */ +/* and Charles-Antoine Gauthier */ +/* Copyright (c) 1999, National Research Council of Canada */ +/* */ +/* Modifications by Andy Dachs to add MPC8260 */ +/* support. */ +/* Copyright (c) 2001, Surrey Satellite Technology Ltd */ +/* */ +/* The license and distribution terms for this file may be */ +/* found in the file LICENSE in this distribution or at */ +/* http://www.rtems.org/license/LICENSE. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Partially based on the code references which are named above. */ +/* Adaptions, modifications, enhancements and any recent parts of */ +/* the code are under the right of */ +/* */ +/* IPR Engineering, Dachauer Straße 38, D-80335 München */ +/* Copyright(C) 2003 */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* IPR Engineering makes no representation or warranties with */ +/* respect to the performance of this computer program, and */ +/* specifically disclaims any responsibility for any damages, */ +/* special or consequential, connected with the use of this program. */ +/* */ +/*---------------------------------------------------------------------*/ +/* */ +/* Version history: 1.0 */ +/* */ +/***********************************************************************/ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + + +#define NUM_PORTS MPC5200_PSC_NO + +#define PSC1_MINOR 0 +#define PSC2_MINOR 1 +#define PSC3_MINOR 2 +#define PSC4_MINOR 3 +#define PSC5_MINOR 4 +#define PSC6_MINOR 5 + +uint32_t mpc5200_uart_avail_mask = BSP_UART_AVAIL_MASK; + +#if defined(UARTS_USE_TERMIOS_INT) + uint8_t psc_minor_to_irqname[NUM_PORTS] = { + BSP_SIU_IRQ_PSC1, + BSP_SIU_IRQ_PSC2, + BSP_SIU_IRQ_PSC3, + BSP_SIU_IRQ_PSC4, + BSP_SIU_IRQ_PSC5, + BSP_SIU_IRQ_PSC6 + }; + + static int mpc5200_psc_irqname_to_minor(int name) { + int minor; + uint8_t *chrptr; + + chrptr = memchr(psc_minor_to_irqname, name, sizeof(psc_minor_to_irqname)); + if (chrptr != NULL) { + minor = chrptr - psc_minor_to_irqname; + } else { + minor = -1; + } + return minor; + } +#endif + +static void A_BSP_output_char(char c); +static int A_BSP_get_char(void); +BSP_output_char_function_type BSP_output_char = A_BSP_output_char; + +BSP_polling_getchar_function_type BSP_poll_char = A_BSP_get_char; + +/* Used to handle premature outputs of printk */ +bool console_initialized = false; + +/* per channel info structure */ +struct per_channel_info { + uint16_t shadow_imr; + uint8_t shadow_mode1; + uint8_t shadow_mode2; + int cur_tx_len; + int rx_interrupts; + int tx_interrupts; + int rx_characters; + int tx_characters; + int breaks_detected; + int framing_errors; + int parity_errors; + int overrun_errors; +}; + +/* Used to handle more than one channel */ +struct per_channel_info channel_info[NUM_PORTS]; + +/* + * XXX: there are only 6 PSCs, but PSC6 has an extra register gap + * from PSC5, therefore we instantiate seven(!) PSC register sets + */ +uint8_t psc_minor_to_regset[MPC5200_PSC_NO] = {0,1,2,3,4,6}; + +/* Used to track termios private data for callbacks */ +struct rtems_termios_tty *ttyp[NUM_PORTS]; + +static int mpc5200_psc_setAttributes( + int minor, + const struct termios *t +) +{ + int baud; + uint8_t csize=0, cstopb, parenb, parodd; + struct mpc5200_psc *psc = + (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); + + /* Baud rate */ + baud = rtems_termios_baud_to_number(t->c_ospeed); + if (baud > 0) { + /* + * Calculate baud rate + * round divider to nearest! + */ + baud = (IPB_CLOCK + baud *16) / (baud * 32); + } + + /* Number of data bits */ + switch ( t->c_cflag & CSIZE ) { + case CS5: csize = 0x00; break; + case CS6: csize = 0x01; break; + case CS7: csize = 0x02; break; + case CS8: csize = 0x03; break; + } + + /* Stop bits */ + if(csize == 0) { + if(t->c_cflag & CSTOPB) + cstopb = 0x0F; /* Two stop bits */ + else + cstopb = 0x00; /* One stop bit */ + } else { + if(t->c_cflag & CSTOPB) + cstopb = 0x0F; /* Two stop bits */ + else + cstopb = 0x07; /* One stop bit */ + } + + /* Parity */ + if (t->c_cflag & PARENB) + parenb = 0x00; /* Parity enabled on Tx and Rx */ + else + parenb = 0x10; /* No parity on Tx and Rx */ + + if (t->c_cflag & PARODD) + parodd = 0x04; /* Odd parity */ + else + parodd = 0x00; + + /* + * Set upper timer counter + */ + psc->ctur = (uint8_t) (baud >> 8); + + /* + * Set lower timer counter + */ + psc->ctlr = (uint8_t) baud; + + /* + * Reset mode pointer + */ + psc->cr = ((1 << 4) << 8); + + /* + * Set mode1 register + */ + channel_info[minor].shadow_mode1 &= ~(0x1F); + psc->mr = channel_info[minor].shadow_mode1 | (csize | parenb | parodd); + + /* + * Set mode2 register + */ + channel_info[minor].shadow_mode2 &= ~(0x0F); + psc->mr = channel_info[minor].shadow_mode2 | cstopb; + + return 0; + +} + + +static int mpc5200_uart_setAttributes(int minor, const struct termios *t) +{ + /* + * Check that port number is valid + */ + if( (minor < PSC1_MINOR) || (minor > NUM_PORTS-1) ) + return 0; + + return mpc5200_psc_setAttributes(minor, t); + +} + +#ifdef UARTS_USE_TERMIOS_INT +/* + * Interrupt handlers + */ +static void mpc5200_psc_interrupt_handler(rtems_irq_hdl_param handle) +{ + unsigned char c; + uint16_t isr; + int minor = (int)handle; + struct mpc5200_psc *psc = + (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); + + /* + * get content of psc interrupt status + */ + isr = psc->isr_imr; + + /* + * Character received? + */ + if (isr & ISR_RX_RDY_FULL) { + + channel_info[minor].rx_interrupts++; + + +#ifndef SINGLE_CHAR_MODE + while(psc->rfnum) { +#endif + /* + * get the character + */ + c = (psc->rb_tb >> 24); + + if (ttyp[minor] != NULL) { + rtems_termios_enqueue_raw_characters( + (void *)ttyp[minor], (char *)&c, (int)1); + channel_info[minor].rx_characters++; + } + +#ifndef SINGLE_CHAR_MODE + } +#endif + + } + + /* + * Character transmitted ? + */ + if (isr & ISR_TX_RDY & channel_info[minor].shadow_imr) { + channel_info[minor].tx_interrupts++; + + if (ttyp[minor] != NULL) { + #ifndef SINGLE_CHAR_MODE + rtems_termios_dequeue_characters( + (void *)ttyp[minor], channel_info[minor].cur_tx_len); + channel_info[minor].tx_characters += channel_info[minor].cur_tx_len; + #else + rtems_termios_dequeue_characters((void *)ttyp[minor], (int)1); + channel_info[minor].tx_characters++; + #endif + } + } + + if(isr & ISR_ERROR) { + if(isr & ISR_RB) + channel_info[minor].breaks_detected++; + if(isr & ISR_FE) + channel_info[minor].framing_errors++; + if(isr & ISR_PE) + channel_info[minor].parity_errors++; + if(isr & ISR_OE) + channel_info[minor].overrun_errors++; + + /* + * Reset error status + */ + psc->cr = ((4 << 4) << 8); + } +} + +static void mpc5200_psc_enable( + const rtems_irq_connect_data* ptr +) +{ + struct mpc5200_psc *psc; + int minor = mpc5200_psc_irqname_to_minor(ptr->name); + + if (minor >= 0) { + psc = (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); + psc->isr_imr = channel_info[minor].shadow_imr |= + (IMR_RX_RDY_FULL | IMR_TX_RDY); + } +} + + +static void mpc5200_psc_disable( + const rtems_irq_connect_data* ptr +) +{ + struct mpc5200_psc *psc; + int minor = mpc5200_psc_irqname_to_minor(ptr->name); + + if (minor >= 0) { + psc = (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); + psc->isr_imr = channel_info[minor].shadow_imr &= + ~(IMR_RX_RDY_FULL | IMR_TX_RDY); + } +} + +static int mpc5200_psc_isOn( + const rtems_irq_connect_data* ptr +) +{ + struct mpc5200_psc *psc; + int minor = mpc5200_psc_irqname_to_minor(ptr->name); + + if (minor >= 0) { + psc = (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); + return ((psc->isr_imr & IMR_RX_RDY_FULL) & (psc->isr_imr & IMR_TX_RDY)); + } + return false; +} + + +static rtems_irq_connect_data consoleIrqData; +#endif + +static void mpc5200_uart_psc_initialize( + int minor +) +{ + uint32_t baud_divider; + struct mpc5200_psc *psc = + (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); + + /* + * Check that minor number is valid + */ + if ((minor < PSC1_MINOR) || (minor >= (PSC1_MINOR + NUM_PORTS))) + return; + + /* + * Clear per channel info + */ + memset((void *)&channel_info[minor], 0, sizeof(struct per_channel_info)); + + /* + * Reset receiver and transmitter + */ + psc->cr = ((2 << 4) << 8); + psc->cr = ((3 << 4) << 8); + + /* + * Reset mode pointer + */ + psc->cr = ((1 << 4) << 8); + + /* + * Set clock select register + */ + psc->sr_csr = 0; + + /* + * Set mode1 register + */ + psc->mr = channel_info[minor].shadow_mode1 = 0x33; /* 8Bit / no parity */ + + /* + * Set mode2 register + */ + psc->mr = channel_info[minor].shadow_mode2 = 7; /* 1 stop bit */ + + /* + * Set rx FIFO alarm + */ + psc->rfalarm = RX_FIFO_SIZE - 1; + + /* + * Set tx FIFO alarm + */ + psc->tfalarm = 1; + + baud_divider = + (IPB_CLOCK + GEN5200_CONSOLE_BAUD *16) / (GEN5200_CONSOLE_BAUD * 32); + + /* + * Set upper timer counter + */ + psc->ctur = baud_divider >> 16; + + /* + * Set lower timer counter + */ + + psc->ctlr = baud_divider & 0x0000ffff; + + /* + * Disable Frame mode / set granularity 0 + */ + psc->tfcntl = 0; + +#ifdef UARTS_USE_TERMIOS_INT + /* + * Tie interrupt dependent routines + */ + consoleIrqData.on = mpc5200_psc_enable; + consoleIrqData.off = mpc5200_psc_disable; + consoleIrqData.isOn = mpc5200_psc_isOn; + consoleIrqData.handle = (rtems_irq_hdl_param)minor; + consoleIrqData.hdl = (rtems_irq_hdl)mpc5200_psc_interrupt_handler; + + /* + * Tie interrupt handler + */ + consoleIrqData.name = psc_minor_to_irqname[minor]; + + /* + * Install rtems irq handler + */ + assert(BSP_install_rtems_irq_handler(&consoleIrqData) == 1); +#endif + + /* + * Reset rx fifo errors Error/UF/OF + */ + psc->rfstat |= 0x70; + + /* + * Reset tx fifo errors Error/UF/OF + */ + psc->tfstat |= 0x70; + +#ifdef UARTS_USE_TERMIOS_INT + /* + * Unmask receive interrupt + */ + psc->isr_imr = channel_info[minor].shadow_imr = IMR_RX_RDY_FULL; +#endif + + /* + * Enable receiver + */ + psc->cr = ((1 << 0) << 8); + + /* + * Enable transmitter + */ + psc->cr = ((1 << 2) << 8); +} + + +static int mpc5200_uart_pollRead( + int minor +) +{ + unsigned char c; + struct mpc5200_psc *psc = + (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); + + if (psc->sr_csr & (1 << 8)) + c = (psc->rb_tb >> 24); + else + return -1; + + return c; +} + + +static ssize_t mpc5200_uart_pollWrite( + int minor, + const char *buf, + size_t len +) +{ + size_t retval = len; + const char *tmp_buf = buf; + struct mpc5200_psc *psc = + (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); + + while(len--) { + while(!(psc->sr_csr & (1 << 11))) + continue; + + /*rtems_cache_flush_multiple_data_lines( (void *)buf, 1);*/ + + psc->rb_tb = (*tmp_buf << 24); + + tmp_buf++; + + } + return retval; + +} + +static ssize_t mpc5200_uart_write( + int minor, + const char *buf, + size_t len +) +{ + struct mpc5200_psc *psc = + (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); + + if (len > 0) { + int frame_len = len; + const char *frame_buf = buf; + + /* + * Check tx fifo space + */ + if(len > (TX_FIFO_SIZE - psc->tfnum)) + frame_len = TX_FIFO_SIZE - psc->tfnum; + +#ifndef SINGLE_CHAR_MODE + channel_info[minor].cur_tx_len = frame_len; +#else + frame_len = 1; +#endif + + /*rtems_cache_flush_multiple_data_lines( (void *)frame_buf, frame_len);*/ + + while (frame_len--) + /* perform byte write to avoid extra NUL characters */ + (* (volatile char *)&(psc->rb_tb)) = *frame_buf++; + + /* + * unmask interrupt + */ + psc->isr_imr = channel_info[minor].shadow_imr |= IMR_TX_RDY; + } else { + /* + * mask interrupt + */ + psc->isr_imr = channel_info[minor].shadow_imr &= ~(IMR_TX_RDY); + } + + return 0; +} + +/* + * Print functions prototyped in bspIo.h + */ +static void A_BSP_output_char( + char c +) +{ + /* + * If we are using U-Boot, then the console is already initialized + * and we can just poll bytes out at any time. + */ + #if !defined(HAS_UBOOT) + if (console_initialized == false) + return; + #endif + +#define PRINTK_WRITE mpc5200_uart_pollWrite + + PRINTK_WRITE(PRINTK_MINOR, &c, 1 ); +} + +static int A_BSP_get_char(void) +{ + /* + * If we are using U-Boot, then the console is already initialized + * and we can just poll bytes in at any time. + */ + #if !defined(HAS_UBOOT) + if (console_initialized == false) + return -1; + #endif + + return mpc5200_uart_pollRead(0); +} + +/* + *************** + * BOILERPLATE * + *************** + * + * All these functions are prototyped in rtems/c/src/lib/include/console.h. + */ + +/* + * Initialize and register the device + */ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + rtems_device_minor_number console_minor; + char dev_name[] = "/dev/ttyx"; + uint32_t tty_num = 0; + bool first = true; + + /* + * Always use and set up TERMIOS + */ + console_minor = PSC1_MINOR; + rtems_termios_initialize(); + + for (console_minor = PSC1_MINOR; + console_minor < PSC1_MINOR + NUM_PORTS; + console_minor++) { + /* + * check, whether UART is available for this board + */ + if (0 != ((1 << console_minor) & (mpc5200_uart_avail_mask))) { + /* + * Do device-specific initialization and registration for Motorola IceCube + */ + mpc5200_uart_psc_initialize(console_minor); /* /dev/tty0 */ + dev_name[8] = '0' + tty_num; + status = rtems_io_register_name (dev_name, major, console_minor); + assert(status == RTEMS_SUCCESSFUL); + + #ifdef MPC5200_PSC_INDEX_FOR_GPS_MODULE + if (console_minor == MPC5200_PSC_INDEX_FOR_GPS_MODULE) { + status = rtems_io_register_name("/dev/gps", major, console_minor); + assert(status == RTEMS_SUCCESSFUL); + } + #endif + + if (first) { + first = false; + + /* Now register the RTEMS console */ + status = rtems_io_register_name ("/dev/console", major, console_minor); + assert(status == RTEMS_SUCCESSFUL); + } + + tty_num++; + } + } + + console_initialized = true; + return RTEMS_SUCCESSFUL; +} + +/* + * Open the device + */ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_libio_open_close_args_t *args = arg; + rtems_status_code sc; + +#ifdef UARTS_USE_TERMIOS_INT + static const rtems_termios_callbacks intrCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + NULL, /* pollRead */ + mpc5200_uart_write, /* write */ + mpc5200_uart_setAttributes, /* setAttributes */ + NULL, + NULL, + 1 /* outputUsesInterrupts */ + }; +#else + static const rtems_termios_callbacks pollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + mpc5200_uart_pollRead, /* pollRead */ + mpc5200_uart_pollWrite, /* write */ + mpc5200_uart_setAttributes, /* setAttributes */ + NULL, + NULL, + 0 /* output don't use Interrupts */ + }; +#endif + + if(minor > NUM_PORTS - 1) + return RTEMS_INVALID_NUMBER; + +#ifdef UARTS_USE_TERMIOS_INT + sc = rtems_termios_open( major, minor, arg, &intrCallbacks ); +#else /* RTEMS polled I/O with termios */ + sc = rtems_termios_open( major, minor, arg, &pollCallbacks ); +#endif + + ttyp[minor] = args->iop->data1; /* Keep cookie returned by termios_open */ + + if ( !sc ) + rtems_termios_set_initial_baud( ttyp[minor], GEN5200_CONSOLE_BAUD ); + + return sc; +} + + +/* + * Close the device + */ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + if ( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + + ttyp[minor] = NULL; /* mark for int handler: tty no longer open */ + + return rtems_termios_close( arg ); +} + + +/* + * Read from the device + */ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + if(minor > NUM_PORTS-1) + return RTEMS_INVALID_NUMBER; + + return rtems_termios_read(arg); +} + +/* + * Write to the device + */ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + if ( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + return rtems_termios_write(arg); +} + +/* + * Handle ioctl request. + */ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + if ( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + + return rtems_termios_ioctl(arg); +} diff --git a/bsps/powerpc/gen83xx/console/console-config.c b/bsps/powerpc/gen83xx/console/console-config.c new file mode 100644 index 0000000000..d0071cd220 --- /dev/null +++ b/bsps/powerpc/gen83xx/console/console-config.c @@ -0,0 +1,107 @@ +/** + * @file + * + * @brief Console configuration. + */ + +/* + * Copyright (c) 2008-2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include + +#include + +#include +#include +#include + +#ifdef BSP_USE_UART_INTERRUPTS + #define DEVICE_FNS &ns16550_handler_interrupt +#else + #define DEVICE_FNS &ns16550_handler_polled +#endif + +static uint8_t gen83xx_console_get_register(uintptr_t addr, uint8_t i) +{ + volatile uint8_t *reg = (volatile uint8_t *) addr; + + return reg [i]; +} + +static void gen83xx_console_set_register(uintptr_t addr, uint8_t i, uint8_t val) +{ + volatile uint8_t *reg = (volatile uint8_t *) addr; + + reg [i] = val; +} + +static ns16550_context gen83xx_uart_context_0 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"), + .get_reg = gen83xx_console_get_register, + .set_reg = gen83xx_console_set_register, + .port = (uintptr_t) &mpc83xx.duart[0], +#if MPC83XX_CHIP_TYPE / 10 == 830 + .irq = BSP_IPIC_IRQ_UART, +#else + .irq = BSP_IPIC_IRQ_UART1, +#endif + .initial_baud = BSP_CONSOLE_BAUD +}; + +#ifdef BSP_USE_UART2 +static ns16550_context gen83xx_uart_context_1 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"), + .get_reg = gen83xx_console_get_register, + .set_reg = gen83xx_console_set_register, + .port = (uintptr_t) &mpc83xx.duart[1], +#if MPC83XX_CHIP_TYPE / 10 == 830 + .irq = BSP_IPIC_IRQ_UART, +#else + .irq = BSP_IPIC_IRQ_UART2, +#endif + .initial_baud = BSP_CONSOLE_BAUD +}; +#endif + +const console_device console_device_table[] = { + { + .device_file = "/dev/ttyS0", + .probe = ns16550_probe, + .handler = DEVICE_FNS, + .context = &gen83xx_uart_context_0.base + } +#ifdef BSP_USE_UART2 + , { + .device_file = "/dev/ttyS1", + .probe = ns16550_probe, + .handler = DEVICE_FNS, + .context = &gen83xx_uart_context_1.base + } +#endif +}; + +const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table); + +static void gen83xx_output_char(char c) +{ + rtems_termios_device_context *ctx = console_device_table[0].context; + + ns16550_polled_putchar(ctx, c); +} + +BSP_output_char_function_type BSP_output_char = gen83xx_output_char; + +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/powerpc/mpc55xxevb/console/console-config.c b/bsps/powerpc/mpc55xxevb/console/console-config.c new file mode 100644 index 0000000000..d0ea250917 --- /dev/null +++ b/bsps/powerpc/mpc55xxevb/console/console-config.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011-2012 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include + +CONSOLE_GENERIC_INFO_TABLE = { + #ifdef MPC55XX_HAS_ESCI + CONSOLE_GENERIC_INFO(mpc55xx_esci_devices + 0, &mpc55xx_esci_callbacks, "/dev/ttyS0") + #ifdef ESCI_B + , CONSOLE_GENERIC_INFO(mpc55xx_esci_devices + 1, &mpc55xx_esci_callbacks, "/dev/ttyS1") + #endif + #ifdef ESCI_C + , CONSOLE_GENERIC_INFO(mpc55xx_esci_devices + 2, &mpc55xx_esci_callbacks, "/dev/ttyS2") + #endif + #ifdef ESCI_D + , CONSOLE_GENERIC_INFO(mpc55xx_esci_devices + 3, &mpc55xx_esci_callbacks, "/dev/ttyS3") + #endif + #endif + #ifdef MPC55XX_HAS_LINFLEX + CONSOLE_GENERIC_INFO(mpc55xx_linflex_devices + 0, &mpc55xx_linflex_callbacks, "/dev/ttyS0"), + CONSOLE_GENERIC_INFO(mpc55xx_linflex_devices + 1, &mpc55xx_linflex_callbacks, "/dev/ttyS1") + #endif +}; + +CONSOLE_GENERIC_INFO_COUNT; + +CONSOLE_GENERIC_MINOR(MPC55XX_CONSOLE_MINOR); diff --git a/bsps/powerpc/mpc55xxevb/console/console-esci.c b/bsps/powerpc/mpc55xxevb/console/console-esci.c new file mode 100644 index 0000000000..9e6646fb65 --- /dev/null +++ b/bsps/powerpc/mpc55xxevb/console/console-esci.c @@ -0,0 +1,354 @@ +/** + * @file + * + * @brief Console ESCI implementation. + */ + +/* + * Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include +#include +#include + +#ifdef MPC55XX_HAS_ESCI + +mpc55xx_esci_context mpc55xx_esci_devices [] = { + { + .regs = &ESCI_A, + .irq = MPC55XX_IRQ_ESCI(0) + } + #ifdef ESCI_B + , { + .regs = &ESCI_B, + .irq = MPC55XX_IRQ_ESCI(1) + } + #endif + #ifdef ESCI_C + , { + .regs = &ESCI_C, + .irq = MPC55XX_IRQ_ESCI(2) + } + #endif + #ifdef ESCI_D + , { + .regs = &ESCI_D, + .irq = MPC55XX_IRQ_ESCI(3) + } + #endif +}; + +static void mpc55xx_esci_poll_write(int minor, char c) +{ + mpc55xx_esci_context *self = console_generic_get_context(minor); + const union ESCI_SR_tag clear_tdre = { .B = { .TDRE = 1 } }; + volatile struct ESCI_tag *regs = self->regs; + rtems_interrupt_level level; + bool done = false; + bool wait_for_transmit_done = false; + + rtems_interrupt_disable(level); + if (self->transmit_nest_level == 0) { + union ESCI_CR1_tag cr1 = { .R = regs->CR1.R }; + + if (cr1.B.TIE != 0) { + cr1.B.TIE = 0; + regs->CR1.R = cr1.R; + wait_for_transmit_done = !self->transmit_in_progress; + self->transmit_nest_level = 1; + } + } else { + ++self->transmit_nest_level; + } + rtems_interrupt_enable(level); + + while (!done) { + rtems_interrupt_disable(level); + bool tx = self->transmit_in_progress; + if (!tx || (tx && regs->SR.B.TDRE)) { + regs->SR.R = clear_tdre.R; + regs->DR.B.D = c; + self->transmit_in_progress = true; + done = true; + } + rtems_interrupt_enable(level); + } + + done = false; + while (!done) { + rtems_interrupt_disable(level); + if (wait_for_transmit_done) { + if (regs->SR.B.TDRE) { + regs->SR.R = clear_tdre.R; + self->transmit_in_progress = false; + done = true; + } + } else { + done = true; + } + + if (done && self->transmit_nest_level > 0) { + --self->transmit_nest_level; + + if (self->transmit_nest_level == 0) { + union ESCI_CR1_tag cr1 = { .R = regs->CR1.R }; + + cr1.B.TIE = 1; + regs->CR1.R = cr1.R; + } + } + rtems_interrupt_enable(level); + } +} + +static inline void mpc55xx_esci_interrupts_clear_and_enable( + mpc55xx_esci_context *self +) +{ + volatile struct ESCI_tag *regs = self->regs; + union ESCI_CR1_tag cr1 = MPC55XX_ZERO_FLAGS; + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + cr1.R = regs->CR1.R; + cr1.B.RIE = 1; + cr1.B.TIE = 1; + regs->CR1.R = cr1.R; + regs->SR.R = regs->SR.R; + rtems_interrupt_enable(level); +} + +static inline void mpc55xx_esci_interrupts_disable(mpc55xx_esci_context *self) +{ + volatile struct ESCI_tag *regs = self->regs; + union ESCI_CR1_tag cr1 = MPC55XX_ZERO_FLAGS; + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + cr1.R = regs->CR1.R; + cr1.B.RIE = 0; + cr1.B.TIE = 0; + regs->CR1.R = cr1.R; + rtems_interrupt_enable(level); +} + +static void mpc55xx_esci_interrupt_handler(void *arg) +{ + mpc55xx_esci_context *self = arg; + volatile struct ESCI_tag *regs = self->regs; + union ESCI_SR_tag sr = MPC55XX_ZERO_FLAGS; + union ESCI_SR_tag active = MPC55XX_ZERO_FLAGS; + rtems_interrupt_level level; + + /* Status */ + sr.R = regs->SR.R; + + /* Receive data register full? */ + if (sr.B.RDRF != 0) { + active.B.RDRF = 1; + } + + /* Transmit data register empty? */ + if (sr.B.TDRE != 0) { + active.B.TDRE = 1; + } + + /* Clear flags */ + rtems_interrupt_disable(level); + regs->SR.R = active.R; + self->transmit_in_progress = false; + rtems_interrupt_enable(level); + + /* Enqueue */ + if (active.B.RDRF != 0) { + char c = regs->DR.B.D; + rtems_termios_enqueue_raw_characters(self->tty, &c, 1); + } + + /* Dequeue */ + if (active.B.TDRE != 0) { + rtems_termios_dequeue_characters(self->tty, 1); + } +} + +static int mpc55xx_esci_set_attributes(int minor, const struct termios *t) +{ + mpc55xx_esci_context *self = console_generic_get_context(minor); + volatile struct ESCI_tag *regs = self->regs; + union ESCI_CR1_tag cr1 = { .R = regs->CR1.R }; + union ESCI_CR2_tag cr2 = MPC55XX_ZERO_FLAGS; + rtems_termios_baud_t br = rtems_termios_baud_to_number(t->c_ospeed); + + /* Enable module */ + cr2.B.MDIS = 0; + + /* Interrupts */ + cr1.B.TCIE = 0; + cr1.B.ILIE = 0; + cr2.B.IEBERR = 0; + cr2.B.ORIE = 0; + cr2.B.NFIE = 0; + cr2.B.FEIE = 0; + cr2.B.PFIE = 0; + + /* Disable receiver wake-up standby */ + cr1.B.RWU = 0; + + /* Disable DMA channels */ + cr2.B.RXDMA = 0; + cr2.B.TXDMA = 0; + + /* Idle line type */ + cr1.B.ILT = 0; + + /* Disable loops */ + cr1.B.LOOPS = 0; + + /* Enable or disable receiver */ + cr1.B.RE = (t->c_cflag & CREAD) ? 1 : 0; + + /* Enable transmitter */ + cr1.B.TE = 1; + + /* Baud rate */ + if (br > 0) { + br = bsp_clock_speed / (16 * br); + br = (br > 8191) ? 8191 : br; + } else { + br = 0; + } + cr1.B.SBR = br; + + /* Number of data bits */ + if ((t->c_cflag & CSIZE) != CS8) { + return -1; + } + cr1.B.M = 0; + + /* Parity */ + cr1.B.PE = (t->c_cflag & PARENB) ? 1 : 0; + cr1.B.PT = (t->c_cflag & PARODD) ? 1 : 0; + + /* Stop bits */ + if (t->c_cflag & CSTOPB ) { + /* Two stop bits */ + return -1; + } + + /* Disable LIN */ + regs->LCR.R = 0; + + /* Set control registers */ + regs->CR2.R = cr2.R; + regs->CR1.R = cr1.R; + + return 0; +} + +static int mpc55xx_esci_first_open(int major, int minor, void *arg) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + int rv = 0; + mpc55xx_esci_context *self = console_generic_get_context(minor); + struct rtems_termios_tty *tty = console_generic_get_tty_at_open(arg); + + self->tty = tty; + + rv = rtems_termios_set_initial_baud(tty, BSP_DEFAULT_BAUD_RATE); + if (rv != 0) { + bsp_fatal(MPC55XX_FATAL_CONSOLE_ESCI_BAUD); + } + + rv = mpc55xx_esci_set_attributes(minor, &tty->termios); + if (rv != 0) { + bsp_fatal(MPC55XX_FATAL_CONSOLE_ESCI_ATTRIBUTES); + } + + sc = mpc55xx_interrupt_handler_install( + self->irq, + "eSCI", + RTEMS_INTERRUPT_UNIQUE, + MPC55XX_INTC_DEFAULT_PRIORITY, + mpc55xx_esci_interrupt_handler, + self + ); + if (sc != RTEMS_SUCCESSFUL) { + bsp_fatal(MPC55XX_FATAL_CONSOLE_ESCI_IRQ_INSTALL); + } + + mpc55xx_esci_interrupts_clear_and_enable(self); + self->transmit_in_progress = false; + + return 0; +} + +static int mpc55xx_esci_last_close(int major, int minor, void* arg) +{ + mpc55xx_esci_context *self = console_generic_get_context(minor); + + mpc55xx_esci_interrupts_disable(self); + self->tty = NULL; + + return 0; +} + +static int mpc55xx_esci_poll_read(int minor) +{ + mpc55xx_esci_context *self = console_generic_get_context(minor); + volatile struct ESCI_tag *regs = self->regs; + union ESCI_SR_tag sr = MPC55XX_ZERO_FLAGS; + rtems_interrupt_level level; + int c = -1; + + rtems_interrupt_disable(level); + if (regs->SR.B.RDRF != 0) { + /* Clear flag */ + sr.B.RDRF = 1; + regs->SR.R = sr.R; + + /* Read */ + c = regs->DR.B.D; + } + rtems_interrupt_enable(level); + + return c; +} + +static int mpc55xx_esci_write(int minor, const char *out, size_t n) +{ + if (n > 0) { + mpc55xx_esci_context *self = console_generic_get_context(minor); + + self->regs->DR.B.D = out [0]; + self->transmit_in_progress = true; + } + + return 0; +} + +const console_generic_callbacks mpc55xx_esci_callbacks = { + .termios_callbacks = { + .firstOpen = mpc55xx_esci_first_open, + .lastClose = mpc55xx_esci_last_close, + .write = mpc55xx_esci_write, + .setAttributes = mpc55xx_esci_set_attributes, + .outputUsesInterrupts = TERMIOS_IRQ_DRIVEN + }, + .poll_read = mpc55xx_esci_poll_read, + .poll_write = mpc55xx_esci_poll_write +}; + +#endif /* MPC55XX_HAS_ESCI */ diff --git a/bsps/powerpc/mpc55xxevb/console/console-generic.c b/bsps/powerpc/mpc55xxevb/console/console-generic.c new file mode 100644 index 0000000000..71385adf2b --- /dev/null +++ b/bsps/powerpc/mpc55xxevb/console/console-generic.c @@ -0,0 +1,168 @@ +/** + * @file + * + * @brief Generic console driver implementation. + */ + +/* + * Copyright (c) 2011 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include +#include +#include + +#include +#include + +static const struct termios console_generic_termios = { + .c_cflag = CS8 | CREAD | CLOCAL | __CONCAT(B, BSP_DEFAULT_BAUD_RATE) +}; + +static void console_generic_char_out(char c) +{ + int minor = (int) console_generic_minor; + const console_generic_callbacks *cb = + console_generic_info_table [minor].callbacks; + + (*cb->poll_write)(minor, c); +} + +static int console_generic_char_in(void) +{ + int minor = (int) console_generic_minor; + const console_generic_callbacks *cb = + console_generic_info_table [minor].callbacks; + + return (*cb->poll_read)(minor); +} + +static void console_generic_char_out_do_init(void) +{ + int minor = (int) console_generic_minor; + const console_generic_callbacks *cb = + console_generic_info_table [minor].callbacks; + const struct termios *term = &console_generic_termios; + + BSP_output_char = console_generic_char_out; + (*cb->termios_callbacks.setAttributes)(minor, term); +} + +static void console_generic_char_out_init(char c) +{ + console_generic_char_out_do_init(); + console_generic_char_out(c); +} + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + const console_generic_info *info_table = console_generic_info_table; + rtems_device_minor_number count = console_generic_info_count; + rtems_device_minor_number console = console_generic_minor; + + if (count <= 0) { + bsp_fatal(MPC55XX_FATAL_CONSOLE_GENERIC_COUNT); + } + + rtems_termios_initialize(); + + for (minor = 0; minor < count; ++minor) { + const console_generic_info *info = info_table + minor; + + sc = rtems_io_register_name(info->device_path, major, minor); + if (sc != RTEMS_SUCCESSFUL) { + bsp_fatal(MPC55XX_FATAL_CONSOLE_GENERIC_REGISTER); + } + } + + sc = rtems_io_register_name(CONSOLE_DEVICE_NAME, major, console); + if (sc != RTEMS_SUCCESSFUL) { + bsp_fatal(MPC55XX_FATAL_CONSOLE_GENERIC_REGISTER_CONSOLE); + } + + console_generic_char_out_do_init(); + + return sc; +} + +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + rtems_device_minor_number count = console_generic_info_count; + + if (minor < count) { + const console_generic_info *info = &console_generic_info_table [minor]; + + sc = rtems_termios_open( + major, + minor, + arg, + &info->callbacks->termios_callbacks + ); + } else { + sc = RTEMS_INVALID_ID; + } + + return sc; +} + +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + return rtems_termios_close(arg); +} + +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + return rtems_termios_read(arg); +} + +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + return rtems_termios_write(arg); +} + +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + return rtems_termios_ioctl(arg); +} + +BSP_output_char_function_type BSP_output_char = console_generic_char_out_init; + +BSP_polling_getchar_function_type BSP_poll_char = console_generic_char_in; diff --git a/bsps/powerpc/mpc55xxevb/console/console-linflex.c b/bsps/powerpc/mpc55xxevb/console/console-linflex.c new file mode 100644 index 0000000000..02978be524 --- /dev/null +++ b/bsps/powerpc/mpc55xxevb/console/console-linflex.c @@ -0,0 +1,417 @@ +/** + * @file + * + * @brief Console LINFlexD implementation. + */ + +/* + * Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include +#include +#include + +#ifdef MPC55XX_HAS_LINFLEX + +mpc55xx_linflex_context mpc55xx_linflex_devices [] = { + { + .regs = &LINFLEX0, + .irq_rxi = MPC55XX_IRQ_LINFLEX_RXI(0), + .irq_txi = MPC55XX_IRQ_LINFLEX_TXI(0), + .irq_err = MPC55XX_IRQ_LINFLEX_ERR(0), + .tx_pcr_register = &((SIU_tag *) &SIUL)->PCR18, + .tx_pa_value = 1, + .rx_pcr_register = &((SIU_tag *) &SIUL)->PCR19, + .rx_psmi_register = &((SIU_tag *) &SIUL)->PSMI31, + .rx_padsel_value = 0 + }, { + .regs = &LINFLEX1, + .irq_rxi = MPC55XX_IRQ_LINFLEX_RXI(1), + .irq_txi = MPC55XX_IRQ_LINFLEX_TXI(1), + .irq_err = MPC55XX_IRQ_LINFLEX_ERR(1), + .tx_pcr_register = &((SIU_tag *) &SIUL)->PCR94, + .tx_pa_value = 1, + .rx_pcr_register = &((SIU_tag *) &SIUL)->PCR95, + .rx_psmi_register = &((SIU_tag *) &SIUL)->PSMI32, + .rx_padsel_value = 2 + } +}; + +static void enter_init_mode(volatile LINFLEX_tag *regs) +{ + LINFLEX_LINCR1_32B_tag cr1 = { .R = regs->LINCR1.R }; + cr1.B.SLEEP = 0; + cr1.B.INIT = 1; + regs->LINCR1.R = cr1.R; +} + +static void enter_active_mode(volatile LINFLEX_tag *regs) +{ + LINFLEX_LINCR1_32B_tag cr1 = { .R = regs->LINCR1.R }; + cr1.B.SLEEP = 0; + cr1.B.INIT = 0; + regs->LINCR1.R = cr1.R; +} + +static void enter_sleep_mode(volatile LINFLEX_tag *regs) +{ + LINFLEX_LINCR1_32B_tag cr1 = { .R = regs->LINCR1.R }; + cr1.B.SLEEP = 1; + cr1.B.INIT = 0; + regs->LINCR1.R = cr1.R; +} + +static void mpc55xx_linflex_poll_write(int minor, char c) +{ + mpc55xx_linflex_context *self = console_generic_get_context(minor); + volatile LINFLEX_tag *regs = self->regs; + const LINFLEX_UARTSR_32B_tag clear_dtf = { .B = { .DTF_TFF = 1 } }; + rtems_interrupt_level level; + bool done = false; + bool wait_for_transmit_done = false; + + rtems_interrupt_disable(level); + if (self->transmit_nest_level == 0) { + LINFLEX_LINIER_32B_tag ier = { .R = regs->LINIER.R }; + + if (ier.B.DTIE != 0) { + ier.B.DTIE = 0; + regs->LINIER.R = ier.R; + wait_for_transmit_done = !self->transmit_in_progress; + self->transmit_nest_level = 1; + } + } else { + ++self->transmit_nest_level; + } + rtems_interrupt_enable(level); + + while (!done) { + rtems_interrupt_disable(level); + bool tx = self->transmit_in_progress; + if (!tx || (tx && regs->UARTSR.B.DTF_TFF)) { + regs->UARTSR.R = clear_dtf.R; + regs->BDRL.B.DATA0 = c; + self->transmit_in_progress = true; + done = true; + } + rtems_interrupt_enable(level); + } + + done = false; + while (!done) { + rtems_interrupt_disable(level); + if (wait_for_transmit_done) { + if (regs->UARTSR.B.DTF_TFF) { + regs->UARTSR.R = clear_dtf.R; + self->transmit_in_progress = false; + done = true; + } + } else { + done = true; + } + + if (done && self->transmit_nest_level > 0) { + --self->transmit_nest_level; + + if (self->transmit_nest_level == 0) { + LINFLEX_LINIER_32B_tag ier = { .R = regs->LINIER.R }; + + ier.B.DTIE = 1; + regs->LINIER.R = ier.R; + } + } + rtems_interrupt_enable(level); + } +} + +static void mpc55xx_linflex_rx_interrupt_handler(void *arg) +{ + mpc55xx_linflex_context *self = arg; + volatile LINFLEX_tag *regs = self->regs; + char c = regs->BDRM.B.DATA4; + const LINFLEX_UARTSR_32B_tag clear_flags = { .B = { .RMB = 1, .DRF_RFE = 1 } }; + + regs->UARTSR.R = clear_flags.R; + + rtems_termios_enqueue_raw_characters(self->tty, &c, 1); +} + +static void mpc55xx_linflex_tx_interrupt_handler(void *arg) +{ + mpc55xx_linflex_context *self = arg; + volatile LINFLEX_tag *regs = self->regs; + + regs->UARTSR.B.DTF_TFF = 1; /* clear flag */ + self->transmit_in_progress = false; + + rtems_termios_dequeue_characters(self->tty, 1); +} + +/* +static void mpc55xx_linflex_err_interrupt_handler(void *arg) +{ + mpc55xx_linflex_context *self = arg; +} +*/ + +static int mpc55xx_linflex_set_attributes(int minor, const struct termios *t) +{ + mpc55xx_linflex_context *self = console_generic_get_context(minor); + volatile LINFLEX_tag *regs = self->regs; + LINFLEX_UARTCR_32B_tag uartcr = { .R = 0 }; + LINFLEX_GCR_32B_tag gcr = { .R = 0 }; + LINFLEX_LINIER_32B_tag ier = { .R = 0 }; + rtems_termios_baud_t br = rtems_termios_baud_to_number(t->c_ospeed); + LINFLEX_LINFBRR_32B_tag fbrr = { .R = 0 }; + LINFLEX_LINIBRR_32B_tag ibrr = { .R = 0 }; + + enter_init_mode(regs); + + /* Set to UART-mode */ + uartcr.B.UART = 1; + regs->UARTCR.R = uartcr.R; + + /* Set to buffer mode with size 1 */ + uartcr.B.TDFL_TFC = 0; + uartcr.B.RDFL_RFC0 = 0; + uartcr.B.RFBM = 0; + uartcr.B.TFBM = 0; + + /* Enable receiver and transmitter */ + uartcr.B.RXEN = 1; + uartcr.B.TXEN = 1; + + /* Number of data bits */ + uartcr.B.WL1 = 0; + if ((t->c_cflag & CSIZE) == CS8) { + uartcr.B.WL0 = 1; + } else if ((t->c_cflag & CSIZE) == CS7) { + uartcr.B.WL0 = 0; + } else { + return -1; + } + + /* Parity */ + uartcr.B.PCE = (t->c_cflag & PARENB) ? 1 : 0; + uartcr.B.PC1 = 0; + uartcr.B.PC0 = (t->c_cflag & PARODD) ? 1 : 0; + + /* Stop bits */ + gcr.B.STOP = (t->c_cflag & CSTOPB) ? 1 : 0; + + /* Set control registers */ + regs->UARTCR.R = uartcr.R; + regs->GCR.R = gcr.R; + + /* Interrupts */ + ier.B.DTIE = 1; + ier.B.DRIE = 1; + regs->LINIER.R = ier.R; + + /* Baud rate */ + if (br > 0) { + uint32_t lfdiv_mult_32 = bsp_clock_speed * 2 / br; + if((lfdiv_mult_32 & 0x1) != 0) { + ++lfdiv_mult_32; + } + fbrr.B.FBR = (lfdiv_mult_32 >> 1) & 0xF; + ibrr.B.IBR = lfdiv_mult_32 >> 5; + } else { + return -1; + } + regs->LINFBRR.R = fbrr.R; + regs->LINIBRR.R = ibrr.R; + + enter_active_mode(regs); + + return 0; +} + +static int mpc55xx_linflex_first_open(int major, int minor, void *arg) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + int rv = 0; + mpc55xx_linflex_context *self = console_generic_get_context(minor); + struct rtems_termios_tty *tty = console_generic_get_tty_at_open(arg); + SIU_PCR_tag pcr = { .R = 0 }; + SIUL_PSMI_8B_tag psmi = { .R = 0 }; + + self->tty = tty; + + pcr.B.IBE = 1; + self->rx_pcr_register->R = pcr.R; + psmi.B.PADSEL = self->rx_padsel_value; + self->rx_psmi_register->R = psmi.R; + pcr.R = 0; + pcr.B.OBE = 1; + pcr.B.PA = self->tx_pa_value; + self->tx_pcr_register->R = pcr.R; + + rv = rtems_termios_set_initial_baud(tty, BSP_DEFAULT_BAUD_RATE); + if (rv != 0) { + bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_BAUD); + } + + rv = mpc55xx_linflex_set_attributes(minor, &tty->termios); + if (rv != 0) { + bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_ATTRIBUTES); + } + + sc = mpc55xx_interrupt_handler_install( + self->irq_rxi, + "LINFlexD RXI", + RTEMS_INTERRUPT_UNIQUE, + MPC55XX_INTC_DEFAULT_PRIORITY, + mpc55xx_linflex_rx_interrupt_handler, + self + ); + if (sc != RTEMS_SUCCESSFUL) { + bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_RX_IRQ_INSTALL); + } + + sc = mpc55xx_interrupt_handler_install( + self->irq_txi, + "LINFlexD TXI", + RTEMS_INTERRUPT_UNIQUE, + MPC55XX_INTC_DEFAULT_PRIORITY, + mpc55xx_linflex_tx_interrupt_handler, + self + ); + if (sc != RTEMS_SUCCESSFUL) { + bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_TX_IRQ_INSTALL); + } + + /* + sc = mpc55xx_interrupt_handler_install( + self->irq_err, + "LINFlexD ERR", + RTEMS_INTERRUPT_UNIQUE, + MPC55XX_INTC_DEFAULT_PRIORITY, + mpc55xx_linflex_err_interrupt_handler, + self + ); + if (sc != RTEMS_SUCCESSFUL) { + bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_ERR_IRQ_INSTALL); + } + */ + + return 0; +} + +static int mpc55xx_linflex_last_close(int major, int minor, void* arg) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + mpc55xx_linflex_context *self = console_generic_get_context(minor); + volatile LINFLEX_tag *regs = self->regs; + SIU_PCR_tag pcr = { .R = 0 }; + SIUL_PSMI_8B_tag psmi = { .R = 0 }; + + /* enter initialization mode */ + enter_init_mode(regs); + + /* disable interrupts */ + regs->LINIER.R = 0; + + /* set module to sleep mode */ + enter_sleep_mode(regs); + + sc = rtems_interrupt_handler_remove( + self->irq_rxi, + mpc55xx_linflex_rx_interrupt_handler, + self + ); + if (sc != RTEMS_SUCCESSFUL) { + bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_RX_IRQ_REMOVE); + } + + sc = rtems_interrupt_handler_remove( + self->irq_txi, + mpc55xx_linflex_tx_interrupt_handler, + self + ); + if (sc != RTEMS_SUCCESSFUL) { + bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_TX_IRQ_REMOVE); + } + + /* + sc = rtems_interrupt_handler_remove( + self->irq_err, + mpc55xx_linflex_err_interrupt_handler, + self + ); + if (sc != RTEMS_SUCCESSFUL) { + bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_ERR_IRQ_REMOVE); + } + */ + + pcr.B.IBE = 1; + self->rx_pcr_register->R = pcr.R; + self->tx_pcr_register->R = pcr.R; + psmi.R = 0; + self->rx_psmi_register->R = psmi.R; + + self->tty = NULL; + + return 0; +} + +static int mpc55xx_linflex_poll_read(int minor) +{ + mpc55xx_linflex_context *self = console_generic_get_context(minor); + volatile LINFLEX_tag *regs = self->regs; + rtems_interrupt_level level; + int c = -1; + + rtems_interrupt_disable(level); + if (regs->UARTSR.B.DRF_RFE != 0) { + /* Clear flag */ + regs->UARTSR.B.DRF_RFE = 1; + + /* Read */ + c = regs->BDRM.B.DATA4; + } + rtems_interrupt_enable(level); + + return c; +} + +static int mpc55xx_linflex_write(int minor, const char *out, size_t n) +{ + if (n > 0) { + mpc55xx_linflex_context *self = console_generic_get_context(minor); + volatile LINFLEX_tag *regs = self->regs; + + regs->BDRL.B.DATA0 = out [0]; + self->transmit_in_progress = true; + /* TODO: send more then one byte */ + } + + return 0; +} + +const console_generic_callbacks mpc55xx_linflex_callbacks = { + .termios_callbacks = { + .firstOpen = mpc55xx_linflex_first_open, + .lastClose = mpc55xx_linflex_last_close, + .write = mpc55xx_linflex_write, + .setAttributes = mpc55xx_linflex_set_attributes, + .outputUsesInterrupts = TERMIOS_IRQ_DRIVEN + }, + .poll_read = mpc55xx_linflex_poll_read, + .poll_write = mpc55xx_linflex_poll_write +}; + +#endif /* MPC55XX_HAS_LINFLEX */ diff --git a/bsps/powerpc/mpc8260ads/console/console.c b/bsps/powerpc/mpc8260ads/console/console.c new file mode 100644 index 0000000000..873c38dc3e --- /dev/null +++ b/bsps/powerpc/mpc8260ads/console/console.c @@ -0,0 +1,458 @@ +/* + * This file contains the MBX8xx termios serial I/O package. + * Only asynchronous I/O is supported. + * + * The SCCs and SMCs are assigned as follows + * + * Channel Device Minor Note + * SMC1 /dev/tty0 0 + * SMC2 /dev/tty1 1 + * SCC1 2 N/A. Hardwired as ethernet port + * SCC2 /dev/tty2 3 + * SCC3 /dev/tty3 4 + * SCC4 /dev/tty4 5 + * + * The SCCs and SMCs on the eval board are assigned as follows + * + * Channel Device Minor Termios + * SMC1 /dev/tty3 4 no + * SMC2 /dev/tty4 5 no + * SCC1 /dev/tty0 0 no + * SCC2 /dev/console 1 yes + * SCC3 /dev/tty1 2 no * USED FOR NETWORK I/F + * SCC4 /dev/tty2 3 no * USED FOR NETWORK I/F + * + * All ports support termios. The use of termios is recommended for real-time + * applications. Termios provides buffering and input processing. When not + * using termios, processing is limited to the substitution of LF for CR on + * input, and the output of a CR following the output of a LF character. + * Note that the terminal should not send CR/LF pairs when the return key + * is pressed, and that output lines are terminated with LF/CR, not CR/LF + * (although that would be easy to change). + * + * I/O may be interrupt-driven (recommended for real-time applications) or + * polled. Polled I/O may be performed by this device driver entirely, or + * in part by EPPCBug. With EPPCBug 1.1, polled I/O is limited to the + * EPPCBug debug console. This is a limitation of the firmware. Later + * firmware may be able to do I/O through any port. This code assumes + * that the EPPCBug console is the default: SMC1. If the console and + * printk ports are set to anything else with EPPCBug polled I/O, the + * system will hang. Only port SMC1 is usable with EPPCBug polled I/O. + * + * LIMITATIONS: + * + * It is not possible to use different I/O modes on the different ports. The + * exception is with printk. The printk port can use a different mode from + * the other ports. If this is done, it is important not to open the printk + * port from an RTEMS application. + * + * Currently, the I/O modes are determined at build time. It would be much + * better to have the mode selected at boot time based on parameters in + * NVRAM. + * + * Interrupt-driven I/O requires termios. + * + * TESTS: + * + * TO RUN THE TESTS, USE POLLED I/O WITHOUT TERMIOS SUPPORT. Some tests + * play with the interrupt masks and turn off I/O. Those tests will hang + * when interrupt-driven I/O is used. Other tests, such as cdtest, do I/O + * from the static constructors before the console is open. This test + * will not work with interrupt-driven I/O. Because of the buffering + * performed in termios, test output may not be in sequence.The tests + * should all be fixed to work with interrupt-driven I/O and to + * produce output in the expected sequence. Obviously, the termios test + * requires termios support in the driver. + * + * Set CONSOLE_MINOR to the appropriate device minor number in the + * config file. This allows the RTEMS application console to be different + * from the EPPBug debug console or the GDB port. + * + * This driver handles all five available serial ports: it distinguishes + * the sub-devices using minor device numbers. It is not possible to have + * other protocols running on the other ports when this driver is used as + * currently written. + */ + +/* + * Based on code (alloc860.c in eth_comm port) by + * Jay Monkman (jmonkman@frasca.com), + * Copyright (C) 1998 by Frasca International, Inc. + * + * Modifications by Darlene Stewart + * and Charles-Antoine Gauthier . + * Copyright (c) 2000, National Research Council of Canada + * + * Modifications by Andy Dachs for MPC8260 + * support. + */ +#include +#include +#include + +#include +#include +#include +#include + +static void _BSP_output_char( char c ); +static rtems_status_code do_poll_read( rtems_device_major_number major, rtems_device_minor_number minor, void * arg); +static rtems_status_code do_poll_write( rtems_device_major_number major, rtems_device_minor_number minor, void * arg); + +BSP_output_char_function_type BSP_output_char = _BSP_output_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; + +/* + * do_poll_read + * + * Input characters through polled I/O. Returns has soon as a character has + * been received. Otherwise, if we wait for the number of requested characters, + * we could be here forever! + * + * CR is converted to LF on input. The terminal should not send a CR/LF pair + * when the return or enter key is pressed. + * + * Input parameters: + * major - ignored. Should be the major number for this driver. + * minor - selected channel. + * arg->buffer - where to put the received characters. + * arg->count - number of characters to receive before returning--Ignored. + * + * Output parameters: + * arg->bytes_moved - the number of characters read. Always 1. + * + * Return value: RTEMS_SUCCESSFUL + * + * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! + */ +static rtems_status_code do_poll_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args = arg; + int c; + +#define BSP_READ m8xx_uart_pollRead + + while( (c = BSP_READ(minor)) == -1 ); + rw_args->buffer[0] = (uint8_t)c; + if( rw_args->buffer[0] == '\r' ) + rw_args->buffer[0] = '\n'; + rw_args->bytes_moved = 1; + return RTEMS_SUCCESSFUL; +} + +/* + * do_poll_write + * + * Output characters through polled I/O. Returns only once every character has + * been sent. + * + * CR is transmitted AFTER a LF on output. + * + * Input parameters: + * major - ignored. Should be the major number for this driver. + * minor - selected channel + * arg->buffer - where to get the characters to transmit. + * arg->count - the number of characters to transmit before returning. + * + * Output parameters: + * arg->bytes_moved - the number of characters read + * + * Return value: RTEMS_SUCCESSFUL + * + * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! + */ +static rtems_status_code do_poll_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args = arg; + uint32_t i; + char cr ='\r'; + +#define BSP_WRITE m8xx_uart_pollWrite + + for( i = 0; i < rw_args->count; i++ ) { + BSP_WRITE(minor, &(rw_args->buffer[i]), 1); + if ( rw_args->buffer[i] == '\n' ) + BSP_WRITE(minor, &cr, 1); + } + rw_args->bytes_moved = i; + return RTEMS_SUCCESSFUL; + +} + +/* + * Print functions prototyped in bspIo.h + */ + +static void _BSP_output_char( char c ) +{ + /* + * Can't rely on console_initialize having been called before this function + * is used, so it may fail unless output is done through EPPC-Bug. + */ +#define PRINTK_WRITE m8xx_uart_pollWrite + + PRINTK_WRITE( PRINTK_MINOR, &c, 1 ); +} + +/* + *************** + * BOILERPLATE * + *************** + * + * All these functions are prototyped in rtems/c/src/lib/include/console.h. + */ + +/* + * Initialize and register the device + */ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + rtems_device_minor_number console_minor; + + /* + * Set up TERMIOS if needed + */ + + console_minor = CONSOLE_MINOR; + +#if UARTS_USE_TERMIOS == 1 + + rtems_termios_initialize (); +#else + rtems_termios_initialize (); +#endif /* UARTS_USE_TERMIOS */ + + /* + * Do common initialization. + */ + m8xx_uart_initialize(); + + /* + * Do device-specific initialization + */ +#if 0 + m8xx_uart_smc_initialize(SMC1_MINOR); /* /dev/tty4 */ + m8xx_uart_smc_initialize(SMC2_MINOR); /* /dev/tty5 */ +#endif + + m8xx_uart_scc_initialize(SCC1_MINOR); /* /dev/tty0 */ + m8xx_uart_scc_initialize(SCC2_MINOR); /* /dev/tty1 */ + +#if 0 /* used as network connections */ + m8xx_uart_scc_initialize(SCC3_MINOR); /* /dev/tty2 */ + m8xx_uart_scc_initialize(SCC4_MINOR); /* /dev/tty3 */ +#endif + + /* + * Set up interrupts + */ + m8xx_uart_interrupts_initialize(); + + status = rtems_io_register_name ("/dev/tty0", major, SCC1_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + chmod("/dev/tty0",0660); + chown("/dev/tty0",2,0); + + status = rtems_io_register_name ("/dev/tty1", major, SCC2_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + chmod("/dev/tty1",0660); + chown("/dev/tty1",2,0); + +#if 0 + status = rtems_io_register_name ("/dev/tty2", major, SCC3_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + + status = rtems_io_register_name ("/dev/tty3", major, SCC4_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + + status = rtems_io_register_name ("/dev/tty4", major, SMC1_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + + status = rtems_io_register_name ("/dev/tty5", major, SMC2_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); +#endif + /* Now register the RTEMS console */ + status = rtems_io_register_name ("/dev/console", major, console_minor); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + chmod("/dev/console",0666); + chown("/dev/console",2,0); + + return RTEMS_SUCCESSFUL; +} + +/* + * Open the device + */ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ +#if UARTS_IO_MODE == 1 /* RTEMS interrupt-driven I/O with termios */ + /* Used to track termios private data for callbacks */ + extern struct rtems_termios_tty *ttyp[]; + rtems_libio_open_close_args_t *args = arg; + + static const rtems_termios_callbacks intrCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + NULL, /* pollRead */ + m8xx_uart_write, /* write */ + m8xx_uart_setAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + 1 /* outputUsesInterrupts */ + }; +#else +#if (UARTS_USE_TERMIOS == 1) && (UARTS_IO_MODE != 1) + static const rtems_termios_callbacks pollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + m8xx_uart_pollRead, /* pollRead */ + m8xx_uart_pollWrite, /* write */ + m8xx_uart_setAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + 0 /* outputUsesInterrupts */ + }; +#endif + +#endif + + rtems_status_code sc; + + if ( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + +#if UARTS_USE_TERMIOS == 1 + +#if UARTS_IO_MODE == 1 /* RTEMS interrupt-driven I/O with termios */ + sc = rtems_termios_open( major, minor, arg, &intrCallbacks ); + ttyp[minor] = args->iop->data1; /* Keep cookie returned by termios_open */ +#else /* RTEMS polled I/O with termios */ + sc = rtems_termios_open( major, minor, arg, &pollCallbacks ); +#endif + +#else /* UARTS_USE_TERMIOS != 1 */ + /* no termios -- default to polled I/O */ + sc = RTEMS_SUCCESSFUL; +#endif /* UARTS_USE_TERMIOS != 1 */ + + return sc; + +} + +/* + * Close the device + */ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + if ( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + +#if UARTS_USE_TERMIOS == 1 + return rtems_termios_close( arg ); +#else + return RTEMS_SUCCESSFUL; +#endif + +} + +/* + * Read from the device + */ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + if ( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + +#if UARTS_USE_TERMIOS == 1 + return rtems_termios_read( arg ); +#else + return do_poll_read( major, minor, arg ); +#endif + +} + +/* + * Write to the device + */ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + if ( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + +#if UARTS_USE_TERMIOS == 1 + return rtems_termios_write( arg ); +#else + /* no termios -- default to polled */ + return do_poll_write( major, minor, arg ); +#endif + +} + +/* + * Handle ioctl request. + */ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + if ( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + +#if UARTS_USE_TERMIOS == 1 + return rtems_termios_ioctl( arg ); +#else + return RTEMS_SUCCESSFUL; +#endif + +} + +/* + * Support routine for console-generic + */ +int mbx8xx_console_get_configuration(void) +{ +#if UARTS_IO_MODE == 1 + return 0x02; +#else + return 0; +#endif + +} diff --git a/bsps/powerpc/psim/console/console-io.c b/bsps/powerpc/psim/console/console-io.c new file mode 100644 index 0000000000..512b90dde2 --- /dev/null +++ b/bsps/powerpc/psim/console/console-io.c @@ -0,0 +1,78 @@ +/* + * This file contains the hardware specific portions of the TTY driver + * for the simulated serial port on the PowerPC simulator. + */ + +/* + * COPYRIGHT (c) 1989-2004. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include + +/* + * console_initialize_hardware + * + * This routine initializes the console hardware. + * + */ + +void console_initialize_hardware(void) +{ +} + +/* external prototypes for monitor interface routines */ + +void outbyte( char ); +char inbyte( void ); + +/* + * console_outbyte_polled + * + * This routine transmits a character using polling. + */ + +void console_outbyte_polled( + int port, + char ch +) +{ + outbyte( ch ); +} + +/* + * console_inbyte_nonblocking + * + * This routine polls for a character. + */ + +int console_inbyte_nonblocking( + int port +) +{ + char c; + + c = inbyte(); + if (!c) + return -1; + return c; +} + +/* + * To support printk + */ + +#include + +static void PSIM_output_char(char c) { console_outbyte_polled( 0, c ); } + +BSP_output_char_function_type BSP_output_char = PSIM_output_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/powerpc/psim/console/consupp.S b/bsps/powerpc/psim/console/consupp.S new file mode 100644 index 0000000000..bb9e834fc6 --- /dev/null +++ b/bsps/powerpc/psim/console/consupp.S @@ -0,0 +1,33 @@ +/* + * Adapted from the mvme-inbyte.S and mvme-outbyte.S files in libgloss. + * These should work on all targets using the ppcbug monitor. + * + * Copyright (c) 1995 Cygnus Support + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include "ppc-asm.h" + + .file "support.s" + .text +FUNC_START(outbyte) + li r10,0x20 + sc + blr +FUNC_END(outbyte) + + .text +FUNC_START(inbyte) + li r10,0x0 + sc + blr +FUNC_END(inbyte) diff --git a/bsps/powerpc/qemuppc/console/console-io.c b/bsps/powerpc/qemuppc/console/console-io.c new file mode 100644 index 0000000000..738bd27966 --- /dev/null +++ b/bsps/powerpc/qemuppc/console/console-io.c @@ -0,0 +1,77 @@ +/* + * This file contains the hardware specific portions of the TTY driver + * for the serial ports on the qemuppc. + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include + +static void +__outb(int port, unsigned char v) +{ + *((volatile unsigned char *)(0x80000000 + port)) = v; +} + +static unsigned char +__inb(int port) +{ + return *((volatile unsigned char *)(0x80000000 + port)); +} + +/* + * console_initialize_hardware + * + * This routine initializes the console hardware. + * + */ +void console_initialize_hardware(void) +{ + return; +} + +/* + * console_outbyte_polled + * + * This routine transmits a character using polling. + */ +void console_outbyte_polled( + int port, + char ch +) +{ + __outb(0x3f8 + 0x00, ch); +} + +/* + * console_inbyte_nonblocking + * + * This routine polls for a character. + */ +int console_inbyte_nonblocking( + int port +) +{ + + if ( __inb(0x3f8 + 0x05) & 0x01 ) + return __inb(0x3f8 + 0x00); + return -1; +} + +#include + +static void simBSP_output_char(char c) { console_outbyte_polled( 0, c ); } + +BSP_output_char_function_type BSP_output_char = simBSP_output_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/powerpc/qoriq/console/console-config.c b/bsps/powerpc/qoriq/console/console-config.c new file mode 100644 index 0000000000..4c1ca1d3f6 --- /dev/null +++ b/bsps/powerpc/qoriq/console/console-config.c @@ -0,0 +1,330 @@ +/** + * @file + * + * @ingroup QorIQ + * + * @brief Console configuration. + */ + +/* + * Copyright (c) 2010, 2017 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +static void output_char(char c); + +#ifdef QORIQ_IS_HYPERVISOR_GUEST +typedef struct { + rtems_termios_device_context base; + uint32_t handle; +} qoriq_bc_context; + +static bool qoriq_bc_probe(rtems_termios_device_context *base) +{ + qoriq_bc_context *ctx; + const void *fdt; + int node; + const uint32_t *handle; + int len; + + fdt = bsp_fdt_get(); + + node = fdt_node_offset_by_compatible(fdt, -1, "epapr,hv-byte-channel"); + if (node < 0) { + return false; + } + + handle = fdt_getprop(fdt, node, "hv-handle", &len); + if (handle == NULL || len != 4) { + return false; + } + + ctx = (qoriq_bc_context *) base; + ctx->handle = fdt32_to_cpu(*handle); + + BSP_output_char = output_char; + return true; +} + +static int qoriq_bc_read_polled(rtems_termios_device_context *base) +{ + qoriq_bc_context *ctx; + char buf[EV_BYTE_CHANNEL_MAX_BYTES]; + unsigned int count; + unsigned int status; + + ctx = (qoriq_bc_context *) base; + count = 1; + status = ev_byte_channel_receive(ctx->handle, &count, buf); + + if (status != EV_SUCCESS || count == 0) { + return -1; + } + + return (unsigned char) buf[0]; +} + +static void qoriq_bc_write_polled( + rtems_termios_device_context *base, + const char *buf, + size_t len +) +{ + qoriq_bc_context *ctx; + uint32_t handle; + + ctx = (qoriq_bc_context *) base; + handle = ctx->handle; + + while (len > 0) { + unsigned int count; + unsigned int status; + char buf2[EV_BYTE_CHANNEL_MAX_BYTES]; + const char *out; + + if (len < EV_BYTE_CHANNEL_MAX_BYTES) { + count = len; + out = memcpy(buf2, buf, len); + } else { + count = EV_BYTE_CHANNEL_MAX_BYTES; + out = buf; + } + + status = ev_byte_channel_send(handle, &count, out); + + if (status == EV_SUCCESS) { + len -= count; + buf += count; + } + } +} + +static const rtems_termios_device_handler qoriq_bc_handler_polled = { + .poll_read = qoriq_bc_read_polled, + .write = qoriq_bc_write_polled, + .mode = TERMIOS_POLLED +}; + +static qoriq_bc_context qoriq_bc_context_0 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("BC 0"), +}; +#endif /* QORIQ_IS_HYPERVISOR_GUEST */ + +#if (QORIQ_UART_0_ENABLE + QORIQ_UART_BRIDGE_0_ENABLE == 2) \ + || (QORIQ_UART_1_ENABLE + QORIQ_UART_BRIDGE_1_ENABLE == 2) + #define BRIDGE_MASTER +#elif QORIQ_UART_BRIDGE_0_ENABLE || QORIQ_UART_BRIDGE_1_ENABLE + #define BRIDGE_SLAVE +#endif + +#ifdef BSP_USE_UART_INTERRUPTS + #define DEVICE_FNS &ns16550_handler_interrupt +#else + #define DEVICE_FNS &ns16550_handler_polled +#endif + +#if QORIQ_UART_0_ENABLE || QORIQ_UART_1_ENABLE + static bool uart_probe(rtems_termios_device_context *base) + { + ns16550_context *ctx = (ns16550_context *) base; + + ctx->clock = BSP_bus_frequency; + + return ns16550_probe(base); + } + + static uint8_t get_register(uintptr_t addr, uint8_t i) + { + volatile uint8_t *reg = (uint8_t *) addr; + + return reg [i]; + } + + static void set_register(uintptr_t addr, uint8_t i, uint8_t val) + { + volatile uint8_t *reg = (uint8_t *) addr; + + reg [i] = val; + } +#endif + +#if QORIQ_UART_0_ENABLE +static ns16550_context qoriq_uart_context_0 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"), + .get_reg = get_register, + .set_reg = set_register, + .port = (uintptr_t) &qoriq.uart_0, + .irq = QORIQ_IRQ_DUART_1, + .initial_baud = BSP_CONSOLE_BAUD +}; +#endif + +#if QORIQ_UART_1_ENABLE +static ns16550_context qoriq_uart_context_1 = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"), + .get_reg = get_register, + .set_reg = set_register, + .port = (uintptr_t) &qoriq.uart_1, + .irq = QORIQ_IRQ_DUART_1, + .initial_baud = BSP_CONSOLE_BAUD +}; +#endif + +#ifdef BRIDGE_MASTER + #define BRIDGE_PROBE qoriq_uart_bridge_master_probe + #define BRIDGE_FNS &qoriq_uart_bridge_master + #if QORIQ_UART_BRIDGE_0_ENABLE + static uart_bridge_master_context bridge_0_context = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 0"), + .device_path = "/dev/ttyS0", + .type = INTERCOM_TYPE_UART_0, + .transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY( + bridge_0_context.transmit_fifo + ) + }; + #define BRIDGE_0_CONTEXT &bridge_0_context.base + #endif + #if QORIQ_UART_BRIDGE_1_ENABLE + static uart_bridge_master_context bridge_1_context = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 1"), + .device_path = "/dev/ttyS1", + .type = INTERCOM_TYPE_UART_1, + .transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY( + bridge_1_context.transmit_fifo + ) + }; + #define BRIDGE_1_CONTEXT &bridge_1_context.base + #endif +#endif + +#ifdef BRIDGE_SLAVE + #define BRIDGE_PROBE console_device_probe_default + #define BRIDGE_FNS &qoriq_uart_bridge_slave + #if QORIQ_UART_BRIDGE_0_ENABLE + static uart_bridge_slave_context bridge_0_context = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 0"), + .type = INTERCOM_TYPE_UART_0, + .transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY( + bridge_0_context.transmit_fifo + ) + }; + #define BRIDGE_0_CONTEXT &bridge_0_context.base + #endif + #if QORIQ_UART_BRIDGE_1_ENABLE + static uart_bridge_slave_context bridge_1_context = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 1"), + .type = INTERCOM_TYPE_UART_1, + .transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY( + bridge_1_context.transmit_fifo + ) + }; + #define BRIDGE_1_CONTEXT &bridge_1_context.base + #endif +#endif + +const console_device console_device_table[] = { + #ifdef QORIQ_IS_HYPERVISOR_GUEST + { + .device_file = "/dev/ttyBC0", + .probe = qoriq_bc_probe, + .handler = &qoriq_bc_handler_polled, + .context = &qoriq_bc_context_0.base + }, + #endif + #if QORIQ_UART_0_ENABLE + { + .device_file = "/dev/ttyS0", + .probe = uart_probe, + .handler = DEVICE_FNS, + .context = &qoriq_uart_context_0.base + }, + #endif + #if QORIQ_UART_1_ENABLE + { + .device_file = "/dev/ttyS1", + .probe = uart_probe, + .handler = DEVICE_FNS, + .context = &qoriq_uart_context_1.base + }, + #endif + #if QORIQ_UART_BRIDGE_0_ENABLE + { + #if QORIQ_UART_1_ENABLE + .device_file = "/dev/ttyB0", + #else + .device_file = "/dev/ttyS0", + #endif + .probe = BRIDGE_PROBE, + .handler = BRIDGE_FNS, + .context = BRIDGE_0_CONTEXT + }, + #endif + #if QORIQ_UART_BRIDGE_1_ENABLE + { + #if QORIQ_UART_1_ENABLE + .device_file = "/dev/ttyB1", + #else + .device_file = "/dev/ttyS1", + #endif + .probe = BRIDGE_PROBE, + .handler = BRIDGE_FNS, + .context = BRIDGE_1_CONTEXT + } + #endif +}; + +const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table); + +static void output_char(char c) +{ + rtems_termios_device_context *base = console_device_table[0].context; + +#ifdef QORIQ_IS_HYPERVISOR_GUEST + qoriq_bc_write_polled(base, &c, 1); +#else + ns16550_polled_putchar(base, c); +#endif +} + +#ifdef QORIQ_IS_HYPERVISOR_GUEST +static void qoriq_bc_output_char_init(char c) +{ + rtems_termios_device_context *base = console_device_table[0].context; + + qoriq_bc_probe(base); + output_char(c); +} + +BSP_output_char_function_type BSP_output_char = qoriq_bc_output_char_init; +#else +BSP_output_char_function_type BSP_output_char = output_char; +#endif + +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/powerpc/qoriq/console/uart-bridge-master.c b/bsps/powerpc/qoriq/console/uart-bridge-master.c new file mode 100644 index 0000000000..588e0a42ad --- /dev/null +++ b/bsps/powerpc/qoriq/console/uart-bridge-master.c @@ -0,0 +1,181 @@ +/** + * @file + * + * @ingroup QorIQUartBridge + * + * @brief UART bridge master implementation. + */ + +/* + * Copyright (c) 2011-2015 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#define TRANSMIT_EVENT RTEMS_EVENT_13 + +static void serial_settings(int fd) +{ + struct termios term; + int rv = tcgetattr(fd, &term); + assert(rv == 0); + + term.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); + term.c_oflag &= ~OPOST; + term.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + term.c_cflag &= ~(CSIZE | PARENB); + term.c_cflag |= CS8; + + term.c_cc [VMIN] = 1; + term.c_cc [VTIME] = 1; + + rv = tcsetattr(fd, TCSANOW, &term); + assert(rv == 0); +} + +static void uart_bridge_master_service(intercom_packet *packet, void *arg) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + uart_bridge_master_context *ctx = arg; + + sc = rtems_chain_append_with_notification( + &ctx->transmit_fifo, + &packet->glue.node, + ctx->transmit_task, + TRANSMIT_EVENT + ); + assert(sc == RTEMS_SUCCESSFUL); +} + +static void receive_task(rtems_task_argument arg) +{ + uart_bridge_master_context *ctx = (uart_bridge_master_context *) arg; + intercom_type type = ctx->type; + + int fd = open(ctx->device_path, O_RDONLY); + assert(fd >= 0); + + serial_settings(fd); + + while (true) { + intercom_packet *packet = qoriq_intercom_allocate_packet( + type, + INTERCOM_SIZE_64 + ); + ssize_t in = read(fd, packet->data, packet->size - 1); + if (in > 0) { + packet->size = (size_t) in; + qoriq_intercom_send_packet(QORIQ_UART_BRIDGE_SLAVE_CORE, packet); + } else { + qoriq_intercom_free_packet(packet); + } + } +} + +static void transmit_task(rtems_task_argument arg) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + uart_bridge_master_context *ctx = (uart_bridge_master_context *) arg; + rtems_chain_control *fifo = &ctx->transmit_fifo; + + int fd = open(ctx->device_path, O_WRONLY); + assert(fd >= 0); + + serial_settings(fd); + + while (true) { + intercom_packet *packet = NULL; + sc = rtems_chain_get_with_wait( + fifo, + TRANSMIT_EVENT, + RTEMS_NO_TIMEOUT, + (rtems_chain_node **) &packet + ); + assert(sc == RTEMS_SUCCESSFUL); + write(fd, packet->data, packet->size); + qoriq_intercom_free_packet(packet); + } +} + +static rtems_id create_task( + char name, + rtems_task_entry entry, + uart_bridge_master_context *ctx +) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + rtems_id task = RTEMS_ID_NONE; + char index = (char) ('0' + ctx->type - INTERCOM_TYPE_UART_0); + + sc = rtems_task_create( + rtems_build_name('U', 'B', name, index), + QORIQ_UART_BRIDGE_TASK_PRIORITY, + 0, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &task + ); + assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_start( + task, + entry, + (rtems_task_argument) ctx + ); + assert(sc == RTEMS_SUCCESSFUL); + + return task; +} + +bool qoriq_uart_bridge_master_probe(rtems_termios_device_context *base) +{ + uart_bridge_master_context *ctx = (uart_bridge_master_context *) base; + intercom_type type = ctx->type; + + qoriq_intercom_service_install(type, uart_bridge_master_service, ctx); + create_task('R', receive_task, ctx); + ctx->transmit_task = create_task('T', transmit_task, ctx); + + return true; +} + +static bool first_open( + struct rtems_termios_tty *tty, + rtems_termios_device_context *base, + struct termios *term, + rtems_libio_open_close_args_t *args +) +{ + return false; +} + +static bool set_attributes( + rtems_termios_device_context *base, + const struct termios *term +) +{ + return false; +} + +const rtems_termios_device_handler qoriq_uart_bridge_master = { + .first_open = first_open, + .set_attributes = set_attributes, + .mode = TERMIOS_POLLED +}; diff --git a/bsps/powerpc/qoriq/console/uart-bridge-slave.c b/bsps/powerpc/qoriq/console/uart-bridge-slave.c new file mode 100644 index 0000000000..44d4cfb712 --- /dev/null +++ b/bsps/powerpc/qoriq/console/uart-bridge-slave.c @@ -0,0 +1,195 @@ +/** + * @file + * + * @ingroup QorIQUartBridge + * + * @brief UART bridge slave implementation. + */ + +/* + * Copyright (c) 2011 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include + +#include +#include + +#define TRANSMIT_EVENT RTEMS_EVENT_13 + +static rtems_mode disable_preemption(void) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + rtems_mode prev_mode = 0; + + sc = rtems_task_mode (RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &prev_mode); + assert(sc == RTEMS_SUCCESSFUL); + + return prev_mode; +} + +static void restore_preemption(rtems_mode prev_mode) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + + sc = rtems_task_mode (prev_mode, RTEMS_PREEMPT_MASK, &prev_mode); + assert(sc == RTEMS_SUCCESSFUL); +} + +static void uart_bridge_slave_service(intercom_packet *packet, void *arg) +{ + uart_bridge_slave_context *ctx = arg; + struct rtems_termios_tty *tty = ctx->tty; + + /* Workaround for https://www.rtems.org/bugzilla/show_bug.cgi?id=1736 */ + rtems_mode prev_mode = disable_preemption(); + + rtems_termios_enqueue_raw_characters(tty, packet->data, (int) packet->size); + qoriq_intercom_free_packet(packet); + + restore_preemption(prev_mode); +} + +static void transmit_task(rtems_task_argument arg) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + uart_bridge_slave_context *ctx = (uart_bridge_slave_context *) arg; + rtems_chain_control *fifo = &ctx->transmit_fifo; + struct rtems_termios_tty *tty = ctx->tty; + + while (true) { + intercom_packet *packet = NULL; + sc = rtems_chain_get_with_wait( + fifo, + TRANSMIT_EVENT, + RTEMS_NO_TIMEOUT, + (rtems_chain_node **) &packet + ); + assert(sc == RTEMS_SUCCESSFUL); + + /* Workaround for https://www.rtems.org/bugzilla/show_bug.cgi?id=1736 */ + rtems_mode prev_mode = disable_preemption(); + + size_t size = packet->size; + qoriq_intercom_send_packet(QORIQ_UART_BRIDGE_MASTER_CORE, packet); + rtems_termios_dequeue_characters(tty, (int) size); + + restore_preemption(prev_mode); + } +} + +static void create_transmit_task( + uart_bridge_slave_context *ctx +) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + rtems_id task = RTEMS_ID_NONE; + char index = (char) ('0' + ctx->type - INTERCOM_TYPE_UART_0); + + sc = rtems_task_create( + rtems_build_name('U', 'B', 'T', index), + QORIQ_UART_BRIDGE_TASK_PRIORITY, + 0, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &task + ); + assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_start( + task, + transmit_task, + (rtems_task_argument) ctx + ); + assert(sc == RTEMS_SUCCESSFUL); + + ctx->transmit_task = task; +} + +static bool first_open( + struct rtems_termios_tty *tty, + rtems_termios_device_context *base, + struct termios *term, + rtems_libio_open_close_args_t *args +) +{ + uart_bridge_slave_context *ctx = (uart_bridge_slave_context *) base; + intercom_type type = ctx->type; + + ctx->tty = tty; + rtems_termios_set_initial_baud(tty, 115200); + create_transmit_task(ctx); + qoriq_intercom_service_install(type, uart_bridge_slave_service, ctx); + + return true; +} + +static void last_close( + struct rtems_termios_tty *tty, + rtems_termios_device_context *base, + rtems_libio_open_close_args_t *args +) +{ + uart_bridge_slave_context *ctx = (uart_bridge_slave_context *) base; + + qoriq_intercom_service_remove(ctx->type); +} + +static void write_with_interrupts( + rtems_termios_device_context *base, + const char *buf, + size_t len +) +{ + if (len > 0) { + rtems_status_code sc = RTEMS_SUCCESSFUL; + uart_bridge_slave_context *ctx = (uart_bridge_slave_context *) base; + intercom_packet *packet = qoriq_intercom_allocate_packet( + ctx->type, + INTERCOM_SIZE_64 + ); + + packet->size = len; + memcpy(packet->data, buf, len); + + /* + * Due to the lovely Termios implementation we have to hand this over to + * another context. + */ + sc = rtems_chain_append_with_notification( + &ctx->transmit_fifo, + &packet->glue.node, + ctx->transmit_task, + TRANSMIT_EVENT + ); + assert(sc == RTEMS_SUCCESSFUL); + } +} + +static bool set_attributes( + rtems_termios_device_context *base, + const struct termios *term +) +{ + return false; +} + +const rtems_termios_device_handler qoriq_uart_bridge_slave = { + .first_open = first_open, + .last_close = last_close, + .write = write_with_interrupts, + .set_attributes = set_attributes, + .mode = TERMIOS_IRQ_DRIVEN +}; diff --git a/bsps/powerpc/shared/console/console.c b/bsps/powerpc/shared/console/console.c new file mode 100644 index 0000000000..f275683cc2 --- /dev/null +++ b/bsps/powerpc/shared/console/console.c @@ -0,0 +1,314 @@ +/* + * console.c -- console I/O package + * + * Copyright (C) 1999 Eric Valette. valette@crf.canon.fr + * + * This code is based on the pc386 BSP console.c so the following + * copyright also applies : + * + * (C) Copyright 1997 - + * - NavIST Group - Real-Time Distributed Systems and Industrial Automation + * + * Till Straumann, , 12/20/2001 + * separate BSP specific stuff from generics... + * + * http://pandora.ist.utl.pt + * + * Instituto Superior Tecnico * Lisboa * PORTUGAL + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include /* printk */ + +/* Definitions for BSPConsolePort */ +/* + * Possible value for console input/output : + * BSP_CONSOLE_PORT_CONSOLE + * BSP_UART_COM1 + * BSP_UART_COM2 + */ +int BSPConsolePort = BSP_CONSOLE_PORT; + +int BSPBaseBaud = BSP_UART_BAUD_BASE; + +/* + * TERMIOS_OUTPUT_MODE should be a 'bspopts.h/configure'-able option; + * we could even make it a link-time option (but that would require + * small changes)... + */ +#if defined(USE_POLLED_IO) + #define TERMIOS_OUTPUT_MODE TERMIOS_POLLED +#elif defined(USE_TASK_DRIVEN_IO) + #define TERMIOS_OUTPUT_MODE TERMIOS_TASK_DRIVEN +#else + #define TERMIOS_OUTPUT_MODE TERMIOS_IRQ_DRIVEN +#endif + +/*-------------------------------------------------------------------------+ +| External Prototypes ++--------------------------------------------------------------------------*/ + +static int conSetAttr(int minor, const struct termios *); + +typedef struct TtySTblRec_ { + char *name; + rtems_irq_hdl isr; +} TtySTblRec, *TtySTbl; + +static TtySTblRec ttyS[]={ + { "/dev/ttyS0", +#ifdef BSP_UART_IOBASE_COM1 + BSP_uart_termios_isr_com1 +#else + 0 +#endif + }, + { "/dev/ttyS1", +#ifdef BSP_UART_IOBASE_COM2 + BSP_uart_termios_isr_com2 +#else + 0 +#endif + }, +}; + +/*-------------------------------------------------------------------------+ +| Console device driver INITIALIZE entry point. ++--------------------------------------------------------------------------+ +| Initilizes the I/O console (keyboard + VGA display) driver. ++--------------------------------------------------------------------------*/ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + + /* + * The video was initialized in the start.s code and does not need + * to be reinitialized. + */ + + /* + * Set up TERMIOS + */ + rtems_termios_initialize(); + + /* + * Do device-specific initialization + */ + + /* RTEMS calls this routine once with 'minor'==0; loop through + * all known instances... + */ + + for (minor=0; minor < sizeof(ttyS)/sizeof(ttyS[0]); minor++) { + char *nm; + /* + * Skip ports (possibly not supported by BSP...) we have no ISR for + */ + if ( ! ttyS[minor].isr ) + continue; + /* + * Register the device + */ + status = rtems_io_register_name ((nm=ttyS[minor].name), major, minor); + if ( RTEMS_SUCCESSFUL==status && BSPConsolePort == minor) { + printk("Registering /dev/console as minor %" PRIu32 " (==%s)\n", + minor, + ttyS[minor].name); + /* also register an alias */ + status = rtems_io_register_name ( (nm="/dev/console"), major, minor); + } + + if (status != RTEMS_SUCCESSFUL) { + printk("Error registering %s!\n",nm); + rtems_fatal_error_occurred (status); + } + } + + return RTEMS_SUCCESSFUL; +} /* console_initialize */ + +#if !defined(USE_POLLED_IO) +static int console_first_open(int major, int minor, void *arg) +{ + rtems_status_code status; + + /* must not open a minor device we have no ISR for */ + assert( minor>=0 && minor < sizeof(ttyS)/sizeof(ttyS[0]) && ttyS[minor].isr ); + + /* 9600-8-N-1 */ + BSP_uart_init(minor, 9600, 0); + status = BSP_uart_install_isr(minor, ttyS[minor].isr); + if (!status) { + printk("Error installing serial console interrupt handler for '%s'!\n", + ttyS[minor].name); + rtems_fatal_error_occurred(status); + } + + /* + * Pass data area info down to driver + */ + BSP_uart_termios_set(minor, ((rtems_libio_open_close_args_t *)arg)->iop->data1); + + /* Enable interrupts on channel */ + BSP_uart_intr_ctrl(minor, BSP_UART_INTR_CTRL_TERMIOS); + + return 0; +} +#endif + +#if !defined(USE_POLLED_IO) +static int console_last_close(int major, int minor, void *arg) +{ + BSP_uart_remove_isr(minor, ttyS[minor].isr); + return 0; +} +#endif + +/*-------------------------------------------------------------------------+ +| Console device driver OPEN entry point ++--------------------------------------------------------------------------*/ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + static rtems_termios_callbacks cb = +#if defined(USE_POLLED_IO) + { + NULL, /* firstOpen */ + NULL, /* lastClose */ + NULL, /* pollRead */ + BSP_uart_termios_write_polled, /* write */ + conSetAttr, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_POLLED /* outputUsesInterrupts */ + }; +#else + { + console_first_open, /* firstOpen */ + console_last_close, /* lastClose */ +#ifdef USE_TASK_DRIVEN_IO + BSP_uart_termios_read_com, /* pollRead */ +#else + NULL, /* pollRead */ +#endif + BSP_uart_termios_write_com, /* write */ + conSetAttr, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_OUTPUT_MODE /* outputUsesInterrupts */ + }; +#endif + + status = rtems_termios_open (major, minor, arg, &cb); + + if (status != RTEMS_SUCCESSFUL) { + printk("Error opening console device\n"); + return status; + } + + return RTEMS_SUCCESSFUL; +} + +/*-------------------------------------------------------------------------+ +| Console device driver CLOSE entry point ++--------------------------------------------------------------------------*/ +rtems_device_driver +console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_device_driver res = RTEMS_SUCCESSFUL; + + res = rtems_termios_close (arg); + + return res; +} /* console_close */ + +/*-------------------------------------------------------------------------+ +| Console device driver READ entry point. ++--------------------------------------------------------------------------+ +| Read characters from the I/O console. We only have stdin. ++--------------------------------------------------------------------------*/ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + return rtems_termios_read (arg); +} /* console_read */ + +/*-------------------------------------------------------------------------+ +| Console device driver WRITE entry point. ++--------------------------------------------------------------------------+ +| Write characters to the I/O console. Stderr and stdout are the same. ++--------------------------------------------------------------------------*/ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + return rtems_termios_write (arg); +} /* console_write */ + +/* + * Handle ioctl request. + */ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ +/* does the BSP support break callbacks ? */ +#if defined(BIOCSETBREAKCB) && defined(BIOCGETBREAKCB) + rtems_libio_ioctl_args_t *ioa=arg; + switch (ioa->command) { + case BIOCSETBREAKCB: return BSP_uart_set_break_cb(minor, ioa); + case BIOCGETBREAKCB: return BSP_uart_get_break_cb(minor, ioa); + default: break; + } +#endif + return rtems_termios_ioctl (arg); +} + +static int conSetAttr( + int minor, + const struct termios *t +) +{ + rtems_termios_baud_t baud; + + baud = rtems_termios_baud_to_number(t->c_ospeed); + if ( baud > 115200 ) + rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR); + + BSP_uart_set_baud(minor, baud); + + return 0; +} diff --git a/bsps/powerpc/shared/console/uart.c b/bsps/powerpc/shared/console/uart.c new file mode 100644 index 0000000000..62212b98db --- /dev/null +++ b/bsps/powerpc/shared/console/uart.c @@ -0,0 +1,781 @@ +/* + * This software is Copyright (C) 1998 by T.sqware - all rights limited + * It is provided in to the public domain "as is", can be freely modified + * as far as this copyight notice is kept unchanged, but does not imply + * an endorsement by T.sqware of the product in which it is included. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Basic 16552 driver + */ + +struct uart_data +{ + unsigned long ioBase; + int irq; + int hwFlow; + int baud; + BSP_UartBreakCbRec breakCallback; + int ioMode; +}; + +/* + * Initialization of BSP specific data. + * The constants are pulled in from a BSP + * specific file, whereas all of the code + * in this file is generic and makes no + * assumptions about addresses, irq vectors + * etc... + */ + +#define UART_UNSUPP ((unsigned long)(-1)) + +static struct uart_data uart_data[2] = { + { +#ifdef BSP_UART_IOBASE_COM1 + BSP_UART_IOBASE_COM1, + BSP_UART_COM1_IRQ, +#else + UART_UNSUPP, + -1, +#endif + }, + { +#ifdef BSP_UART_IOBASE_COM2 + BSP_UART_IOBASE_COM2, + BSP_UART_COM2_IRQ, +#else + UART_UNSUPP, + -1, +#endif + }, +}; + +#define MAX_UARTS (sizeof(uart_data)/sizeof(uart_data[0])) +#define SANITY_CHECK(uart) \ + assert( MAX_UARTS > (unsigned)(uart) && uart_data[(uart)].ioBase != UART_UNSUPP ) +/* + * Macros to read/write register of uart, if configuration is + * different just rewrite these macros + */ + +static inline unsigned char +uread(int uart, unsigned int reg) +{ + return in_8((uint8_t*)(uart_data[uart].ioBase + reg)); +} + +static inline void +uwrite(int uart, int reg, unsigned int val) +{ + out_8((uint8_t*)(uart_data[uart].ioBase + reg), val); +} + + +static void +uartError(int uart, void *termiosPrivate) +{ + unsigned char uartStatus, dummy; + BSP_UartBreakCbProc h; + + uartStatus = uread(uart, LSR); + dummy = uread(uart, RBR); + +#ifdef UARTDEBUG + if (uartStatus & OE) + printk("********* Over run Error **********\n"); + if (uartStatus & PE) + printk("********* Parity Error **********\n"); + if (uartStatus & FE) + printk("********* Framing Error **********\n"); + if (uartStatus & BI) { + printk("********* BREAK INTERRUPT *********\n"); +#endif + if ((h=uart_data[uart].breakCallback.handler)) { + h(uart, + (dummy<<8)|uartStatus, + termiosPrivate, + uart_data[uart].breakCallback.private); + } +#ifdef UARTDEBUG + if (uartStatus & ERFIFO) + printk("********* Error receive Fifo **********\n"); +#endif +} + +/* + * Uart initialization, it is hardcoded to 8 bit, no parity, + * one stop bit, FIFO, things to be changed + * are baud rate and nad hw flow control, + * and longest rx fifo setting + */ +void +BSP_uart_init(int uart, int baud, int hwFlow) +{ + unsigned char tmp; + + /* Sanity check */ + SANITY_CHECK(uart); + + /* Make sure any printk activity drains before + * re-initializing. + */ + while ( ! (uread(uart, LSR) & TEMT) ) + ; + + switch(baud) + { + case 50: + case 75: + case 110: + case 134: + case 300: + case 600: + case 1200: + case 2400: + case 9600: + case 19200: + case 38400: + case 57600: + case 115200: + break; + default: + assert(0); + return; + } + + /* Set DLAB bit to 1 */ + uwrite(uart, LCR, DLAB); + + if ( (int)BSPBaseBaud <= 0 ) { + /* Use current divisor assuming BSPBaseBaud gives us the current speed */ + BSPBaseBaud = BSPBaseBaud ? -BSPBaseBaud : 9600; + BSPBaseBaud *= ((uread(uart, DLM) << 8) | uread(uart, DLL)); + } + + /* Set baud rate */ + uwrite(uart, DLL, (BSPBaseBaud/baud) & 0xff); + uwrite(uart, DLM, ((BSPBaseBaud/baud) >> 8) & 0xff); + + /* 8-bit, no parity , 1 stop */ + uwrite(uart, LCR, CHR_8_BITS); + + /* Set DTR, RTS and OUT2 high */ + uwrite(uart, MCR, DTR | RTS | OUT_2); + + /* Enable FIFO */ + uwrite(uart, FCR, FIFO_EN | XMIT_RESET | RCV_RESET | RECEIVE_FIFO_TRIGGER12); + + /* Disable Interrupts */ + uwrite(uart, IER, 0); + + /* Read status to clear them */ + tmp = uread(uart, LSR); + tmp = uread(uart, RBR); + tmp = uread(uart, MSR); + (void) tmp; /* avoid set but not used warning */ + + /* Remember state */ + uart_data[uart].hwFlow = hwFlow; + uart_data[uart].baud = baud; + return; +} + +/* + * Set baud + */ +void +BSP_uart_set_baud(int uart, int baud) +{ + unsigned char mcr, ier; + + /* Sanity check */ + SANITY_CHECK(uart); + + /* + * This function may be called whenever TERMIOS parameters + * are changed, so we have to make sure that baud change is + * indeed required. + */ + + if(baud == uart_data[uart].baud) + { + return; + } + + mcr = uread(uart, MCR); + ier = uread(uart, IER); + + BSP_uart_init(uart, baud, uart_data[uart].hwFlow); + + uwrite(uart, MCR, mcr); + uwrite(uart, IER, ier); + + return; +} + +/* + * Enable/disable interrupts + */ +void +BSP_uart_intr_ctrl(int uart, int cmd) +{ + + SANITY_CHECK(uart); + + switch(cmd) + { + case BSP_UART_INTR_CTRL_DISABLE: + uwrite(uart, IER, INTERRUPT_DISABLE); + break; + case BSP_UART_INTR_CTRL_ENABLE: + if(uart_data[uart].hwFlow) + { + uwrite(uart, IER, + (RECEIVE_ENABLE | + TRANSMIT_ENABLE | + RECEIVER_LINE_ST_ENABLE | + MODEM_ENABLE + ) + ); + } + else + { + uwrite(uart, IER, + (RECEIVE_ENABLE | + TRANSMIT_ENABLE | + RECEIVER_LINE_ST_ENABLE + ) + ); + } + break; + case BSP_UART_INTR_CTRL_TERMIOS: + if(uart_data[uart].hwFlow) + { + uwrite(uart, IER, + (RECEIVE_ENABLE | + RECEIVER_LINE_ST_ENABLE | + MODEM_ENABLE + ) + ); + } + else + { + uwrite(uart, IER, + (RECEIVE_ENABLE | + RECEIVER_LINE_ST_ENABLE + ) + ); + } + break; + case BSP_UART_INTR_CTRL_GDB: + uwrite(uart, IER, RECEIVE_ENABLE); + break; + default: + assert(0); + break; + } + + return; +} + +void +BSP_uart_throttle(int uart) +{ + unsigned int mcr; + + SANITY_CHECK(uart); + + if(!uart_data[uart].hwFlow) + { + /* Should not happen */ + assert(0); + return; + } + mcr = uread (uart, MCR); + /* RTS down */ + mcr &= ~RTS; + uwrite(uart, MCR, mcr); + + return; +} + +void +BSP_uart_unthrottle(int uart) +{ + unsigned int mcr; + + SANITY_CHECK(uart); + + if(!uart_data[uart].hwFlow) + { + /* Should not happen */ + assert(0); + return; + } + mcr = uread (uart, MCR); + /* RTS up */ + mcr |= RTS; + uwrite(uart, MCR, mcr); + + return; +} + +/* + * Status function, -1 if error + * detected, 0 if no received chars available, + * 1 if received char available, 2 if break + * is detected, it will eat break and error + * chars. It ignores overruns - we cannot do + * anything about - it execpt count statistics + * and we are not counting it. + */ +int +BSP_uart_polled_status(int uart) +{ + unsigned char val; + + SANITY_CHECK(uart); + + val = uread(uart, LSR); + + if(val & BI) + { + /* BREAK found, eat character */ + uread(uart, RBR); + return BSP_UART_STATUS_BREAK; + } + + if((val & (DR | OE | FE)) == 1) + { + /* No error, character present */ + return BSP_UART_STATUS_CHAR; + } + + if((val & (DR | OE | FE)) == 0) + { + /* Nothing */ + return BSP_UART_STATUS_NOCHAR; + } + + /* + * Framing or parity error + * eat character + */ + uread(uart, RBR); + + return BSP_UART_STATUS_ERROR; +} + +/* + * Polled mode write function + */ +void +BSP_uart_polled_write(int uart, int val) +{ + unsigned char val1; + + /* Sanity check */ + SANITY_CHECK(uart); + + for(;;) + { + if((val1=uread(uart, LSR)) & THRE) + { + break; + } + } + + if(uart_data[uart].hwFlow) + { + for(;;) + { + if(uread(uart, MSR) & CTS) + { + break; + } + } + } + + uwrite(uart, THR, val & 0xff); + + return; +} + +void +BSP_output_char_via_serial(const char val) +{ + BSP_uart_polled_write(BSPConsolePort, val); +} + +/* + * Polled mode read function + */ +int +BSP_uart_polled_read(int uart) +{ + unsigned char val; + + SANITY_CHECK(uart); + + for(;;) + { + if(uread(uart, LSR) & DR) + { + break; + } + } + + val = uread(uart, RBR); + + return (int)(val & 0xff); +} + +unsigned +BSP_poll_char_via_serial() +{ + return BSP_uart_polled_read(BSPConsolePort); +} + +static void +uart_noop(const rtems_irq_connect_data *unused) +{ + return; +} + +/* note that the IRQ names contain _ISA_ for legacy + * reasons. They can be any interrupt, depending + * on the particular BSP... + */ + +static int +uart_isr_is_on(const rtems_irq_connect_data *irq) +{ + int uart; + + uart = (irq->name == BSP_UART_COM1_IRQ) ? + BSP_UART_COM1 : BSP_UART_COM2; + + return uread(uart,IER); +} + +static int +doit(int uart, rtems_irq_hdl handler, int (*p)(const rtems_irq_connect_data*)) +{ + rtems_irq_connect_data d={0}; + d.name = uart_data[uart].irq; + d.off = d.on = uart_noop; + d.isOn = uart_isr_is_on; + d.hdl = handler; + return p(&d); +} + +int +BSP_uart_install_isr(int uart, rtems_irq_hdl handler) +{ +/* Using shared interrupts by default might break things.. the + * shared IRQ installer uses malloc() and if a BSP had called this + * during early init it might not work... + */ +#ifdef BSP_UART_USE_SHARED_IRQS + return doit(uart, handler, BSP_install_rtems_shared_irq_handler); +#else + return doit(uart, handler, BSP_install_rtems_irq_handler); +#endif +} + +int +BSP_uart_remove_isr(int uart, rtems_irq_hdl handler) +{ + return doit(uart, handler, BSP_remove_rtems_irq_handler); +} + +/* ================ Termios support =================*/ + +static volatile int termios_stopped_com[2] = {0,0}; +static volatile int termios_tx_active_com[2] = {0,0}; +static void* termios_ttyp_com[2] = {NULL,NULL}; +static char termios_tx_hold_com[2] = {0,0}; +static volatile char termios_tx_hold_valid_com[2] = {0,0}; + +/* + * Set channel parameters + */ +void +BSP_uart_termios_set(int uart, void *p) +{ + struct rtems_termios_tty *ttyp = p; + unsigned char val; + SANITY_CHECK(uart); + + if(uart_data[uart].hwFlow) + { + val = uread(uart, MSR); + + termios_stopped_com[uart] = (val & CTS) ? 0 : 1; + } + else + { + termios_stopped_com[uart] = 0; + } + termios_tx_active_com[uart] = 0; + termios_ttyp_com[uart] = ttyp; + termios_tx_hold_com[uart] = 0; + termios_tx_hold_valid_com[uart] = 0; + + uart_data[uart].ioMode = ttyp->device.outputUsesInterrupts; + + return; +} + +ssize_t +BSP_uart_termios_write_polled(int minor, const char *buf, size_t len) +{ + int uart=minor; /* could differ, theoretically */ + int nwrite; + const char *b = buf; + + for (nwrite=0 ; nwrite < len ; nwrite++) { + BSP_uart_polled_write(uart, *b++); + } + return nwrite; +} + +ssize_t +BSP_uart_termios_write_com(int minor, const char *buf, size_t len) +{ + int uart=minor; /* could differ, theoretically */ + + if(len <= 0) + { + return 0; + } + + /* If the TX buffer is busy - something is royally screwed up */ + /* assert((uread(BSP_UART_COM1, LSR) & THRE) != 0); */ + + if(termios_stopped_com[uart]) + { + /* CTS low */ + termios_tx_hold_com[uart] = *buf; + termios_tx_hold_valid_com[uart] = 1; + return 0; + } + + /* Write character */ + uwrite(uart, THR, *buf & 0xff); + + /* Enable interrupts if necessary */ + if(!termios_tx_active_com[uart] && uart_data[uart].hwFlow) + { + termios_tx_active_com[uart] = 1; + uwrite(uart, IER, + (RECEIVE_ENABLE | + TRANSMIT_ENABLE | + RECEIVER_LINE_ST_ENABLE | + MODEM_ENABLE + ) + ); + } + else if(!termios_tx_active_com[uart]) + { + termios_tx_active_com[uart] = 1; + uwrite(uart, IER, + (RECEIVE_ENABLE | + TRANSMIT_ENABLE | + RECEIVER_LINE_ST_ENABLE + ) + ); + } + + return 0; +} + +int +BSP_uart_termios_read_com(int uart) +{ + int off = (int)0; + char buf[40]; + rtems_interrupt_level l; + + /* read bytes */ + while (( off < sizeof(buf) ) && ( uread(uart, LSR) & DR )) { + buf[off++] = uread(uart, RBR); + } + + /* write out data */ + if ( off > 0 ) { + rtems_termios_enqueue_raw_characters(termios_ttyp_com[uart], buf, off); + } + + /* enable receive interrupts */ + rtems_interrupt_disable(l); + uwrite(uart, IER, uread(uart, IER) | (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE)); + rtems_interrupt_enable(l); + + return ( EOF ); +} + +static void +BSP_uart_termios_isr_com(int uart) +{ + unsigned char buf[40]; + unsigned char val, ier; + int off, ret, vect; + + off = 0; + + for(;;) + { + vect = uread(uart, IIR) & 0xf; + + switch(vect) + { + case MODEM_STATUS : + val = uread(uart, MSR); + if(uart_data[uart].hwFlow) + { + if(val & CTS) + { + /* CTS high */ + termios_stopped_com[uart] = 0; + if(termios_tx_hold_valid_com[uart]) + { + termios_tx_hold_valid_com[uart] = 0; + BSP_uart_termios_write_com(uart, &termios_tx_hold_com[uart], + 1); + } + } + else + { + /* CTS low */ + termios_stopped_com[uart] = 1; + } + } + break; + case NO_MORE_INTR : + /* No more interrupts */ + if(off != 0) + { + /* Update rx buffer */ + rtems_termios_enqueue_raw_characters(termios_ttyp_com[uart], + (char *)buf, + off); + } + return; + case TRANSMITTER_HODING_REGISTER_EMPTY : + /* + * TX holding empty: we have to disable these interrupts + * if there is nothing more to send. + */ + + ret = rtems_termios_dequeue_characters(termios_ttyp_com[uart], 1); + + /* If nothing else to send disable interrupts */ + if(ret == 0 && uart_data[uart].hwFlow) + { + uwrite(uart, IER, + (RECEIVE_ENABLE | + RECEIVER_LINE_ST_ENABLE | + MODEM_ENABLE + ) + ); + termios_tx_active_com[uart] = 0; + } + else if(ret == 0) + { + uwrite(uart, IER, + (RECEIVE_ENABLE | + RECEIVER_LINE_ST_ENABLE + ) + ); + termios_tx_active_com[uart] = 0; + } + break; + case RECEIVER_DATA_AVAIL : + case CHARACTER_TIMEOUT_INDICATION: + if ( uart_data[uart].ioMode == TERMIOS_TASK_DRIVEN ) + { + /* ensure interrupts are enabled */ + if ( (ier = uread(uart,IER)) & RECEIVE_ENABLE ) + { + /* disable interrupts and notify termios */ + ier &= ~(RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE); + uwrite(uart, IER, ier); + rtems_termios_rxirq_occured(termios_ttyp_com[uart]); + } + } + else + { + /* RX data ready */ + assert(off < sizeof(buf)); + while ( off < sizeof(buf) && ( DR & uread(uart, LSR) ) ) + buf[off++] = uread(uart, RBR); + } + break; + case RECEIVER_ERROR: + /* RX error: eat character */ + uartError(uart, termios_ttyp_com[uart]); + break; + default: + /* Should not happen */ + assert(0); + return; + } + } +} + +/* + * XXX - Note that this can now be one isr with the uart + * passed as the parameter. + */ +void +BSP_uart_termios_isr_com1(void *unused) +{ + BSP_uart_termios_isr_com(BSP_UART_COM1); +} + +void +BSP_uart_termios_isr_com2(void *unused) +{ + BSP_uart_termios_isr_com(BSP_UART_COM2); +} + +/* retrieve 'break' handler info */ +int +BSP_uart_get_break_cb(int uart, rtems_libio_ioctl_args_t *arg) +{ +BSP_UartBreakCb cb=arg->buffer; +unsigned long flags; + SANITY_CHECK(uart); + rtems_interrupt_disable(flags); + *cb = uart_data[uart].breakCallback; + rtems_interrupt_enable(flags); + arg->ioctl_return=0; + return RTEMS_SUCCESSFUL; +} + +/* install 'break' handler */ +int +BSP_uart_set_break_cb(int uart, rtems_libio_ioctl_args_t *arg) +{ +BSP_UartBreakCb cb=arg->buffer; +unsigned long flags; + SANITY_CHECK(uart); + rtems_interrupt_disable(flags); + uart_data[uart].breakCallback = *cb; + rtems_interrupt_enable(flags); + arg->ioctl_return=0; + return RTEMS_SUCCESSFUL; +} diff --git a/bsps/powerpc/ss555/console/console.c b/bsps/powerpc/ss555/console/console.c new file mode 100644 index 0000000000..e13e4734ea --- /dev/null +++ b/bsps/powerpc/ss555/console/console.c @@ -0,0 +1,371 @@ +/* + * console.c + * + * This file contains the Intec SS555 termios serial I/O package. + * + * The SCI channels are assigned as follows + * + * Channel Device Minor + * SCI1 /dev/tty0 0 + * SCI2 /dev/tty1 1 + * + * All ports support termios. The use of termios is recommended for real-time + * applications. Termios provides buffering and input processing. When not + * using termios, processing is limited to the substitution of LF for CR on + * input, and the output of a CR following the output of a LF character. + * Note that the terminal should not send CR/LF pairs when the return key + * is pressed, and that output lines are terminated with LF/CR, not CR/LF + * (although that would be easy to change). + * + * I/O may be interrupt-driven (recommended for real-time applications) or + * polled. + * + * LIMITATIONS: + * + * It is not possible to use different I/O modes on the different ports. The + * exception is with printk. The printk port can use a different mode from + * the other ports. If this is done, it is important not to open the printk + * port from an RTEMS application. + * + * Currently, the I/O modes are determined at build time. It would be much + * better to have the mode selected at boot time based on parameters in + * NVRAM. + * + * Interrupt-driven I/O requires termios. + * + * TESTS: + * + * TO RUN THE TESTS, USE POLLED I/O WITHOUT TERMIOS SUPPORT. Some tests + * play with the interrupt masks and turn off I/O. Those tests will hang + * when interrupt-driven I/O is used. Other tests, such as cdtest, do I/O + * from the static constructors before the console is open. This test + * will not work with interrupt-driven I/O. Because of the buffering + * performed in termios, test output may not be in sequence.The tests + * should all be fixed to work with interrupt-driven I/O and to + * produce output in the expected sequence. Obviously, the termios test + * requires termios support in the driver. + * + * Set CONSOLE_MINOR to the appropriate device minor number in the + * config file. This allows the RTEMS application console to be different + * from the GDB port. + * + * This driver handles both available serial ports: it distinguishes + * the sub-devices using minor device numbers. It is not possible to have + * other protocols running on the other ports when this driver is used as + * currently written. + * + * + * SS555 port sponsored by Defence Research and Development Canada - Suffield + * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca) + * + * Derived from c/src/lib/libbsp/powerpc/mbx8xx/console/console.c: + * + * Based on code (alloc860.c in eth_comm port) by + * Jay Monkman (jmonkman@frasca.com), + * Copyright (C) 1998 by Frasca International, Inc. + * + * Modifications by Darlene Stewart + * and Charles-Antoine Gauthier . + * Copyright (c) 2000, National Research Council of Canada + * + */ +#include +#include +#include + +#include +#include +#include +#include /* Must be before libio.h */ + +static void _BSP_output_char( char c ); +static rtems_status_code do_poll_read( rtems_device_major_number major, rtems_device_minor_number minor, void * arg); +static rtems_status_code do_poll_write( rtems_device_major_number major, rtems_device_minor_number minor, void * arg); + +static void _BSP_null_char( char c ) {return;} + +BSP_output_char_function_type BSP_output_char = _BSP_null_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; + +/* + * do_poll_read + * + * Input characters through polled I/O. Returns as soon as a character has + * been received. Otherwise, if we wait for the number of requested + * characters, we could be here forever! + * + * CR is converted to LF on input. The terminal should not send a CR/LF pair + * when the return or enter key is pressed. + * + * Input parameters: + * major - ignored. Should be the major number for this driver. + * minor - selected channel. + * arg->buffer - where to put the received characters. + * arg->count - number of characters to receive before returning--Ignored. + * + * Output parameters: + * arg->bytes_moved - the number of characters read. Always 1. + * + * Return value: RTEMS_SUCCESSFUL + * + * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! + */ +static rtems_status_code do_poll_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args = arg; + int c; + + while( (c = m5xx_uart_pollRead(minor)) == -1 ); + rw_args->buffer[0] = (uint8_t)c; + if( rw_args->buffer[0] == '\r' ) + rw_args->buffer[0] = '\n'; + rw_args->bytes_moved = 1; + + return RTEMS_SUCCESSFUL; +} + +/* + * do_poll_write + * + * Output characters through polled I/O. Returns only once every character has + * been sent. + * + * CR is transmitted AFTER a LF on output. + * + * Input parameters: + * major - ignored. Should be the major number for this driver. + * minor - selected channel + * arg->buffer - where to get the characters to transmit. + * arg->count - the number of characters to transmit before returning. + * + * Output parameters: + * arg->bytes_moved - the number of characters read + * + * Return value: RTEMS_SUCCESSFUL + * + * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! + */ +static rtems_status_code do_poll_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args = arg; + uint32_t i; + char cr ='\r'; + + for( i = 0; i < rw_args->count; i++ ) { + m5xx_uart_pollWrite(minor, &(rw_args->buffer[i]), 1); + if ( rw_args->buffer[i] == '\n' ) + m5xx_uart_pollWrite(minor, &cr, 1); + } + rw_args->bytes_moved = i; + + return RTEMS_SUCCESSFUL; +} + +/* + * Print functions prototyped in bspIo.h + */ + +static void _BSP_output_char( char c ) +{ + char cr = '\r'; + + /* + * Can't rely on console_initialize having been called before this + * function is used, so it may fail. + */ + + m5xx_uart_pollWrite( PRINTK_MINOR, &c, 1 ); + if( c == '\n' ) + m5xx_uart_pollWrite( PRINTK_MINOR, &cr, 1 ); +} + +/* + *************** + * BOILERPLATE * + *************** + * + * All these functions are prototyped in rtems/c/src/lib/include/console.h. + */ + +/* + * Initialize and register the device + */ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + + /* + * Set up TERMIOS if needed + */ + #if UARTS_USE_TERMIOS == 1 + rtems_termios_initialize (); + #endif /* UARTS_USE_TERMIOS */ + + /* + * Do device-specific initialization + */ + BSP_output_char = _BSP_output_char; + + m5xx_uart_initialize(SCI1_MINOR); + status = rtems_io_register_name ("/dev/tty0", major, SCI1_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + + m5xx_uart_initialize(SCI2_MINOR); + status = rtems_io_register_name ("/dev/tty1", major, SCI2_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + + /* Now register the RTEMS console */ + status = rtems_io_register_name ("/dev/console", major, CONSOLE_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + + return RTEMS_SUCCESSFUL; +} + +/* + * Open the device + */ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code sc; + + if ( minor > NUM_PORTS - 1 ) + return RTEMS_INVALID_NUMBER; + + #if (UARTS_USE_TERMIOS == 1) + { + #if (UARTS_IO_MODE == 1) /* RTEMS interrupt-driven I/O with termios */ + + static const rtems_termios_callbacks callbacks = { + m5xx_uart_firstOpen, /* firstOpen */ + m5xx_uart_lastClose, /* lastClose */ + NULL, /* pollRead */ + m5xx_uart_write, /* write */ + m5xx_uart_setAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_IRQ_DRIVEN /* outputUsesInterrupts */ + }; + sc = rtems_termios_open( major, minor, arg, &callbacks ); + + #else /* UARTS_IO_MODE != 1 */ /* RTEMS polled I/O with termios */ + + static const rtems_termios_callbacks callbacks = { + m5xx_uart_firstOpen, /* firstOpen */ + m5xx_uart_lastClose, /* lastClose */ + m5xx_uart_pollRead, /* pollRead */ + m5xx_uart_pollWrite, /* write */ + m5xx_uart_setAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_POLLED /* outputUsesInterrupts */ + }; + sc = rtems_termios_open( major, minor, arg, &callbacks ); + + #endif + + return sc; + } + + #else /* no termios -- default to polled I/O */ + { + sc = RTEMS_SUCCESSFUL; + } + #endif + + return sc; +} + +/* + * Close the device + */ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + if ( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + + #if UARTS_USE_TERMIOS == 1 + return rtems_termios_close( arg ); + #else + return RTEMS_SUCCESSFUL; + #endif +} + +/* + * Read from the device + */ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + if ( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + + #if UARTS_USE_TERMIOS == 1 + return rtems_termios_read( arg ); + #else + return do_poll_read( major, minor, arg ); + #endif +} + +/* + * Write to the device + */ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + if ( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + + #if UARTS_USE_TERMIOS == 1 + return rtems_termios_write( arg ); + #else + return do_poll_write( major, minor, arg ); + #endif +} + +/* + * Handle ioctl request. + */ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + if ( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + + #if UARTS_USE_TERMIOS == 1 + return rtems_termios_ioctl( arg ); + #else + return RTEMS_SUCCESSFUL; + #endif +} diff --git a/bsps/powerpc/t32mppc/console/console.c b/bsps/powerpc/t32mppc/console/console.c new file mode 100644 index 0000000000..5fbd648765 --- /dev/null +++ b/bsps/powerpc/t32mppc/console/console.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2012, 2015 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +/* + * Console driver for Lauterbach Trace32 Simulator. The implementation is + * based on the example in "demo/powerpc/etc/terminal/terminal_mpc85xx.cmm" in + * the Trace32 system directory. + */ + +#include +#include +#include + +volatile unsigned char messagebufferin[256]; + +volatile unsigned char messagebufferout[256]; + +typedef struct { + rtems_termios_device_context base; + int input_size; + int input_index; +} t32_console_context; + +static t32_console_context t32_console_instance; + +static bool t32_console_first_open( + rtems_termios_tty *tty, + rtems_termios_device_context *base, + struct termios *term, + rtems_libio_open_close_args_t *args +) +{ + rtems_termios_set_initial_baud(tty, 115200); + + return true; +} + +static int t32_console_read_polled(rtems_termios_device_context *base) +{ + t32_console_context *ctx = (t32_console_context *) base; + int c; + + if (ctx->input_size == 0) { + int new_bufsize = messagebufferin[0]; + + if (new_bufsize != 0) { + ctx->input_size = new_bufsize; + ctx->input_index = 0; + } else { + return -1; + } + } + + c = messagebufferin[4 + ctx->input_index]; + + ++ctx->input_index; + if (ctx->input_index >= ctx->input_size) { + messagebufferin[0] = 0; + ctx->input_size = 0; + } + + return c; +} + +static void t32_console_write_char_polled(char c) +{ + while (messagebufferout[0] != 0) { + /* Wait for ready */ + } + + messagebufferout[4] = (unsigned char) c; + messagebufferout[0] = 1; +} + +static void t32_console_write_polled( + rtems_termios_device_context *base, + const char *s, + size_t n +) +{ + size_t i; + + for (i = 0; i < n; ++i) { + t32_console_write_char_polled(s[i]); + } +} + +const rtems_termios_device_handler t32_console_handler = { + .first_open = t32_console_first_open, + .poll_read = t32_console_read_polled, + .write = t32_console_write_polled, + .mode = TERMIOS_POLLED +}; + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + t32_console_context *ctx = &t32_console_instance; + + rtems_termios_initialize(); + rtems_termios_device_context_initialize(&ctx->base, "T32 Console"); + rtems_termios_device_install( + CONSOLE_DEVICE_NAME, + &t32_console_handler, + NULL, + &ctx->base + ); + + return RTEMS_SUCCESSFUL; +} + +BSP_output_char_function_type BSP_output_char = t32_console_write_char_polled; + +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/powerpc/tqm8xx/console/console.c b/bsps/powerpc/tqm8xx/console/console.c new file mode 100644 index 0000000000..5a681b19fb --- /dev/null +++ b/bsps/powerpc/tqm8xx/console/console.c @@ -0,0 +1,1115 @@ +/*===============================================================*\ +| Project: RTEMS TQM8xx BSP | ++-----------------------------------------------------------------+ +| This file has been adapted to MPC8xx by | +| Thomas Doerfler | +| Copyright (c) 2008 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | +| | +| See the other copyright notice below for the original parts. | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.org/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the console driver | +\*===============================================================*/ +/* derived from: */ +/* + * SMC1/2 SCC1..4 raw console serial I/O. + * adapted to work with up to 4 SCC and 2 SMC + * + * This driver is an example of `TASK DRIVEN' `POLLING' or `INTERRUPT' I/O. + * + * To run with interrupt-driven I/O, ensure m8xx_smc1_interrupt + * is set before calling the initialization routine. + * + * Author: + * W. Eric Norum + * Saskatchewan Accelerator Laboratory + * University of Saskatchewan + * Saskatoon, Saskatchewan, CANADA + * eric@skatter.usask.ca + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * Interrupt-driven input buffer + */ +#define RXBUFSIZE 16 + +#define M8xx_SICR_BRG1 (0) +#define M8xx_SICR_BRG2 (1) +#define M8xx_SICR_BRG3 (2) +#define M8xx_SICR_BRG4 (3) + +#define M8xx_SICR_SCCRX_MSK(scc) (( 7) << (((scc))*8+3)) +#define M8xx_SICR_SCCRX(scc,clk) ((clk) << (((scc))*8+3)) + +#define M8xx_SICR_SCCTX_MSK(scc) (( 7) << (((scc))*8+0)) +#define M8xx_SICR_SCCTX(scc,clk) ((clk) << (((scc))*8+0)) + +#define M8xx_SIMODE_SMCCS(smc,clk) ((clk) << ((smc)*16+12)) +#define M8xx_SIMODE_SMCCS_MSK(smc) M8xx_SIMODE_SMCCS(smc,7) + +#define CONS_CHN_CNT 6 +#define CONS_CHN_SCC1 0 +#define CONS_CHN_SCC2 1 +#define CONS_CHN_SCC3 2 +#define CONS_CHN_SCC4 3 +#define CONS_CHN_SMC1 4 +#define CONS_CHN_SMC2 5 +#define CONS_CHN_NONE -1 + +/* + * possible identifiers for bspopts.h: CONS_SxCy_MODE + */ +#define CONS_MODE_UNUSED -1 +#define CONS_MODE_POLLED TERMIOS_POLLED +#define CONS_MODE_IRQ TERMIOS_IRQ_DRIVEN + +#define CHN_IS_SCC(chan) ((chan) < CONS_CHN_SMC1) + +#define BRG_CNT 4 + +#define MAX_IDL_DEFAULT 10 +#define DEVICEPREFIX "tty" + +/* + * Interrupt-driven callback + */ +static int m8xx_scc_mode[CONS_CHN_CNT]; +static void *sccttyp[CONS_CHN_CNT]; +typedef struct m8xx_console_chan_desc_s { + bool is_scc; /* true for SCC */ + struct { + volatile m8xxSCCparms_t *sccp; + volatile m8xxSMCparms_t *smcp; + } parms; + struct { + volatile m8xxSCCRegisters_t *sccr; + volatile m8xxSMCRegisters_t *smcr; + } regs; + int ivec_src; + int cr_chan_code; + int brg_used; +} m8xx_console_chan_desc_t; + +m8xx_console_chan_desc_t m8xx_console_chan_desc[CONS_CHN_CNT] = { + /* SCC1 */ + {TRUE, + {(m8xxSCCparms_t *)&(m8xx.scc1p),NULL}, + {&(m8xx.scc1),NULL}, + BSP_CPM_IRQ_SCC1, + M8xx_CR_CHAN_SCC1, + -1}, + /* SCC2 */ + {TRUE, + {&(m8xx.scc2p),NULL}, + {&(m8xx.scc2),NULL}, + BSP_CPM_IRQ_SCC2, + M8xx_CR_CHAN_SCC2, + -1}, + /* SCC3 */ + {TRUE, + {&(m8xx.scc3p),NULL}, + {&(m8xx.scc3),NULL}, + BSP_CPM_IRQ_SCC3, + M8xx_CR_CHAN_SCC3, + -1}, + /* SCC4 */ + {TRUE, + {&(m8xx.scc4p),NULL}, + {&(m8xx.scc4),NULL}, + BSP_CPM_IRQ_SCC4, + M8xx_CR_CHAN_SCC4, + -1}, + /* SMC1 */ + {FALSE, + {NULL,&(m8xx.smc1p)}, + {NULL,&(m8xx.smc1)}, + BSP_CPM_IRQ_SMC1, + M8xx_CR_CHAN_SMC1, + -1}, + /* SMC2 */ + {FALSE, + {NULL,&(m8xx.smc2p)}, + {NULL,&(m8xx.smc2)}, + BSP_CPM_IRQ_SMC2_OR_PIP, + M8xx_CR_CHAN_SMC2, + -1}}; + +#define CHN_PARAM_GET(chan,param) \ + (m8xx_console_chan_desc[chan].is_scc \ + ? m8xx_console_chan_desc[chan].parms.sccp->param \ + : m8xx_console_chan_desc[chan].parms.smcp->param) + +#define CHN_PARAM_SET(chan,param,value) \ + do {if (m8xx_console_chan_desc[chan].is_scc) \ + m8xx_console_chan_desc[chan].parms.sccp->param = value; \ + else \ + m8xx_console_chan_desc[chan].parms.smcp->param = value; \ + } while (0) + +#define CHN_EVENT_GET(chan) \ + (m8xx_console_chan_desc[chan].is_scc \ + ? m8xx_console_chan_desc[chan].regs.sccr->scce \ + : m8xx_console_chan_desc[chan].regs.smcr->smce) + +#define CHN_EVENT_CLR(chan,mask) \ + do { \ + if (m8xx_console_chan_desc[chan].is_scc) \ + m8xx_console_chan_desc[chan].regs.sccr->scce = (mask); \ + else \ + m8xx_console_chan_desc[chan].regs.smcr->smce = (mask); \ + }while (0) + +#define CHN_MASK_GET(chan) \ + (m8xx_console_chan_desc[chan].is_scc \ + ? m8xx_console_chan_desc[chan].regs.sccr->sccm \ + : m8xx_console_chan_desc[chan].regs.smcr->smcm) + +#define CHN_MASK_SET(chan,mask) \ + do { \ + if (m8xx_console_chan_desc[chan].is_scc) \ + m8xx_console_chan_desc[chan].regs.sccr->sccm = (mask); \ + else \ + m8xx_console_chan_desc[chan].regs.smcr->smcm = (mask); \ + }while (0) + + +/* + * I/O buffers and pointers to buffer descriptors + */ +#define SCC_RXBD_CNT 4 +#define SCC_TXBD_CNT 4 +typedef volatile char sccRxBuf_t[SCC_RXBD_CNT][RXBUFSIZE]; +static sccRxBuf_t *rxBuf[CONS_CHN_CNT]; + +static volatile m8xxBufferDescriptor_t *sccFrstRxBd[CONS_CHN_CNT]; +static volatile m8xxBufferDescriptor_t *sccCurrRxBd[CONS_CHN_CNT]; +static volatile m8xxBufferDescriptor_t *sccFrstTxBd[CONS_CHN_CNT]; +static volatile m8xxBufferDescriptor_t *sccPrepTxBd[CONS_CHN_CNT]; +static volatile m8xxBufferDescriptor_t *sccDequTxBd[CONS_CHN_CNT]; + +/* + * Compute baud-rate-generator configuration register value + */ +static uint32_t +sccBRGval (int baud) +{ + int divisor; + int div16 = 0; + + divisor = ((BSP_bus_frequency / 16) + (baud / 2)) / baud; + if (divisor > 4096) { + div16 = 1; + divisor = (divisor + 8) / 16; + } + return M8xx_BRG_EN | M8xx_BRG_EXTC_BRGCLK | ((divisor - 1) << 1) | div16; +} + +typedef struct { + uint32_t reg_content; + int link_cnt; +}brg_state_t; +brg_state_t scc_brg_state[BRG_CNT]; + +/* + * initialize brg_state + */ +static void sccBRGinit(void) +{ + int brg_idx; + + for (brg_idx = 0;brg_idx < BRG_CNT;brg_idx++) { + scc_brg_state[brg_idx].reg_content = 0; + scc_brg_state[brg_idx].link_cnt = 0; + } +#ifndef MDE360 + /* + * on ZEM40, init CLK4/5 inputs + */ + m8xx.papar |= ((1 << 11) | (1 << 12)); + m8xx.padir &= ~((1 << 11) | (1 << 12)); +#endif +} + +#if CONS_USE_EXT_CLK +/* + * input clock frq for CPM clock inputs + */ +static uint32_t clkin_frq[2][4] = { +#ifdef MDE360 + {0,0,0,0}, + {0,0,0,0} +#else + {0,0,0,1843000}, + {1843000,0,0,0} +#endif +}; +#endif + +/* + * allocate, set and connect baud rate generators + * FIXME: or clock input + * FIXME: set pin to be clock input + */ + +static int sccBRGalloc(int chan,int baud) +{ + rtems_interrupt_level level; + m8xx_console_chan_desc_t *chan_desc = &(m8xx_console_chan_desc[chan]); + uint32_t reg_val; + int old_brg; + int new_brg = -1; + int brg_idx; +#if CONS_USE_EXT_CLK + int clk_group; + int clk_sel; +#endif + + old_brg = chan_desc->brg_used; + /* compute brg register contents needed */ + reg_val = sccBRGval(baud); + +#if CONS_EXT_CLK + /* search for clock input with this frq */ + clk_group = ((chan == CONS_CHN_SCC3) || + (chan == CONS_CHN_SCC4) || + (chan == CONS_CHN_SMC2)) ? 1 : 0; + + for (clk_sel = 0, new_brg = -1; + (clk_sel < 4) && (new_brg < 0); + clk_sel++) { + if (baud == (clkin_frq[clk_group][clk_sel] / 16)) { + new_brg = clk_sel + 4; + } + } +#endif + + rtems_interrupt_disable(level); + + if (new_brg < 0) { + /* search for brg with this settings */ + for (brg_idx = 0; + (new_brg < 0) && (brg_idx < BRG_CNT); + brg_idx++) { + if (scc_brg_state[brg_idx].reg_content == reg_val) { + new_brg = brg_idx; + } + } + /* + * if not found: check, whether brg currently in use + * is linked only from our channel + */ + if ((new_brg < 0) && + (old_brg >= 0) && + (scc_brg_state[old_brg].link_cnt == 1)) { + new_brg = old_brg; + } + /* if not found: search for unused brg, set it */ + for (brg_idx = 0; + (new_brg < 0) && (brg_idx < BRG_CNT); + brg_idx++) { + if (scc_brg_state[brg_idx].link_cnt == 0) { + new_brg = brg_idx; + } + } + } + + /* decrease old link count */ + if ((old_brg >= 0) && + (old_brg < 4)) { + scc_brg_state[old_brg].link_cnt--; + } + /* increase new brg link count, set brg */ + if ((new_brg >= 0) && + (new_brg < 4)) { + scc_brg_state[new_brg].link_cnt++; + scc_brg_state[new_brg].reg_content = reg_val; + (&m8xx.brgc1)[new_brg] = reg_val; + } + rtems_interrupt_enable(level); + + /* connect to scc/smc */ + if (new_brg >= 0) { + m8xx_console_chan_desc[chan].brg_used = new_brg; + /* + * Put SCC in NMSI mode, connect SCC to BRG or CLKx + */ + if (m8xx_console_chan_desc[chan].is_scc) { + m8xx.sicr = ((m8xx.sicr & ~(M8xx_SICR_SCCRX_MSK(chan) | + M8xx_SICR_SCCTX_MSK(chan))) | + M8xx_SICR_SCCRX(chan,new_brg)| + M8xx_SICR_SCCTX(chan,new_brg)); + } + else { + /* connect SMC to BRGx or CLKx... */ + m8xx.simode = ((m8xx.simode & ~(M8xx_SIMODE_SMCCS_MSK(chan - CONS_CHN_SMC1)))| + M8xx_SIMODE_SMCCS(chan - CONS_CHN_SMC1,new_brg)); + } + } + return (new_brg < 0); +} + + +/* + * Hardware-dependent portion of tcsetattr(). + */ +static int +sccSetAttributes (int minor, const struct termios *t) +{ + int baud; + + switch (t->c_ospeed) { + default: baud = -1; break; + case B50: baud = 50; break; + case B75: baud = 75; break; + case B110: baud = 110; break; + case B134: baud = 134; break; + case B150: baud = 150; break; + case B200: baud = 200; break; + case B300: baud = 300; break; + case B600: baud = 600; break; + case B1200: baud = 1200; break; + case B1800: baud = 1800; break; + case B2400: baud = 2400; break; + case B4800: baud = 4800; break; + case B9600: baud = 9600; break; + case B19200: baud = 19200; break; + case B38400: baud = 38400; break; + case B57600: baud = 57600; break; + case B115200: baud = 115200; break; + case B230400: baud = 230400; break; + case B460800: baud = 460800; break; + } + return sccBRGalloc(minor,baud); + return 0; +} + +/* + * Interrupt handler + */ +static rtems_isr +sccInterruptHandler (void *arg) +{ + int chan = (int)arg; + + /* + * Buffer received? + */ + if (CHN_EVENT_GET(chan) & 0x1) { + /* + * clear SCC event flag + */ + CHN_EVENT_CLR(chan,0x01); + /* + * process event + */ + while ((sccCurrRxBd[chan]->status & M8xx_BD_EMPTY) == 0) { + if (sccttyp[chan] != NULL) { + rtems_cache_invalidate_multiple_data_lines((void *)sccCurrRxBd[chan]->buffer, + sccCurrRxBd[chan]->length); + rtems_termios_enqueue_raw_characters (sccttyp[chan], + (char *)sccCurrRxBd[chan]->buffer, + sccCurrRxBd[chan]->length); + } + /* + * clear status + */ + sccCurrRxBd[chan]->status = + (sccCurrRxBd[chan]->status + & (M8xx_BD_WRAP | M8xx_BD_INTERRUPT)) + | M8xx_BD_EMPTY; + /* + * advance to next BD + */ + if ((sccCurrRxBd[chan]->status & M8xx_BD_WRAP) != 0) { + sccCurrRxBd[chan] = sccFrstRxBd[chan]; + } + else { + sccCurrRxBd[chan]++; + } + } + } + /* + * Buffer transmitted? + */ + if (CHN_EVENT_GET(chan) & 0x2) { + /* + * then clear interrupt event bit + */ + CHN_EVENT_CLR(chan,0x2); + /* + * and signal successful transmit to termios + */ + /* + * FIXME: multiple dequeue calls for multiple buffers + */ + while((sccDequTxBd[chan] != sccPrepTxBd[chan]) && + ((sccDequTxBd[chan]->status & M8xx_BD_READY) == 0)) { + if (sccttyp[chan] != NULL) { + rtems_termios_dequeue_characters (sccttyp[chan], + sccDequTxBd[chan]->length); + } + /* + * advance to next BD + */ + if ((sccDequTxBd[chan]->status & M8xx_BD_WRAP) != 0) { + sccDequTxBd[chan] = sccFrstTxBd[chan]; + } + else { + sccDequTxBd[chan]++; + } + } + } +} + +static void +mpc8xx_console_irq_on(const rtems_irq_connect_data *irq) +{ + CHN_MASK_SET(irq->name - BSP_CPM_IRQ_LOWEST_OFFSET, + 3); /* Enable TX and RX interrupts */ +} + +static void +mpc8xx_console_irq_off(const rtems_irq_connect_data *irq) +{ + CHN_MASK_SET(irq->name - BSP_CPM_IRQ_LOWEST_OFFSET, + 0); /* Disable TX and RX interrupts */ +} + +static int +mpc8xx_console_irq_isOn(const rtems_irq_connect_data *irq) +{ + return (0 != CHN_MASK_GET(irq->name - BSP_CPM_IRQ_LOWEST_OFFSET)); /* Check TX and RX interrupts */ +} + +static void +sccInitialize (int chan) +{ + int i; + /* + * allocate buffers + * FIXME: use a cache-line size boundary alloc here + */ + rxBuf[chan] = malloc(sizeof(*rxBuf[chan]) + 2*PPC_CACHE_ALIGNMENT); + if (rxBuf[chan] == NULL) { + rtems_panic("Cannot allocate console rx buffer\n"); + } + else { + /* + * round up rxBuf[chan] to start at a cache line size + */ + rxBuf[chan] = (sccRxBuf_t *) + (((uint32_t)rxBuf[chan]) + + (PPC_CACHE_ALIGNMENT + - ((uint32_t)rxBuf[chan]) % PPC_CACHE_ALIGNMENT)); + } + /* + * Allocate buffer descriptors + */ + sccCurrRxBd[chan] = + sccFrstRxBd[chan] = m8xx_bd_allocate(SCC_RXBD_CNT); + sccPrepTxBd[chan] = + sccDequTxBd[chan] = + sccFrstTxBd[chan] = m8xx_bd_allocate(SCC_TXBD_CNT); + switch(chan) { + case CONS_CHN_SCC1: + /* + * Configure port A pins to enable TXD1 and RXD1 pins + * FIXME: add setup for modem control lines.... + */ + m8xx.papar |= 0x03; + m8xx.padir &= ~0x03; + + /* + * Configure port C pins to enable RTS1 pins (static active low) + */ + m8xx.pcpar &= ~0x01; + m8xx.pcso &= ~0x01; + m8xx.pcdir |= 0x01; + m8xx.pcdat &= ~0x01; + break; + case CONS_CHN_SCC2: + /* + * Configure port A pins to enable TXD2 and RXD2 pins + * FIXME: add setup for modem control lines.... + */ + m8xx.papar |= 0x0C; + m8xx.padir &= ~0x0C; + + /* + * Configure port C pins to enable RTS2 pins (static active low) + */ + m8xx.pcpar &= ~0x02; + m8xx.pcso &= ~0x02; + m8xx.pcdir |= 0x02; + m8xx.pcdat &= ~0x02; + break; + case CONS_CHN_SCC3: + /* + * Configure port A pins to enable TXD3 and RXD3 pins + * FIXME: add setup for modem control lines.... + */ + m8xx.papar |= 0x30; + m8xx.padir &= ~0x30; + + /* + * Configure port C pins to enable RTS3 (static active low) + */ + m8xx.pcpar &= ~0x04; + m8xx.pcso &= ~0x04; + m8xx.pcdir |= 0x04; + m8xx.pcdat &= ~0x04; + break; + case CONS_CHN_SCC4: + /* + * Configure port A pins to enable TXD4 and RXD4 pins + * FIXME: add setup for modem control lines.... + */ + m8xx.papar |= 0xC0; + m8xx.padir &= ~0xC0; + + /* + * Configure port C pins to enable RTS4 pins (static active low) + */ + m8xx.pcpar &= ~0x08; + m8xx.pcso &= ~0x08; + m8xx.pcdir |= 0x08; + m8xx.pcdat &= ~0x08; + break; + case CONS_CHN_SMC1: + /* + * Configure port B pins to enable SMTXD1 and SMRXD1 pins + */ + m8xx.pbpar |= 0xC0; + m8xx.pbdir &= ~0xC0; + break; + case CONS_CHN_SMC2: + /* + * Configure port B pins to enable SMTXD2 and SMRXD2 pins + */ + m8xx.pbpar |= 0xC00; + m8xx.pbdir &= ~0xC00; + break; + } + /* + * allocate and connect BRG + */ + sccBRGalloc(chan,9600); + + + /* + * Set up SCCx parameter RAM common to all protocols + */ + CHN_PARAM_SET(chan,rbase,(char *)sccFrstRxBd[chan] - (char *)&m8xx); + CHN_PARAM_SET(chan,tbase,(char *)sccFrstTxBd[chan] - (char *)&m8xx); + CHN_PARAM_SET(chan,rfcr ,M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0)); + CHN_PARAM_SET(chan,tfcr ,M8xx_TFCR_MOT | M8xx_TFCR_DMA_SPACE(0)); + if (m8xx_scc_mode[chan] != TERMIOS_POLLED) + CHN_PARAM_SET(chan,mrblr,RXBUFSIZE); + else + CHN_PARAM_SET(chan,mrblr,1); + + /* + * Set up SCCx parameter RAM UART-specific parameters + */ + CHN_PARAM_SET(chan,un.uart.max_idl ,MAX_IDL_DEFAULT); + CHN_PARAM_SET(chan,un.uart.brkln ,0); + CHN_PARAM_SET(chan,un.uart.brkec ,0); + CHN_PARAM_SET(chan,un.uart.brkcr ,0); + if (m8xx_console_chan_desc[chan].is_scc) { + m8xx_console_chan_desc[chan].parms.sccp->un.uart.character[0]=0x8000; /* no char filter */ + m8xx_console_chan_desc[chan].parms.sccp->un.uart.rccm=0x80FF; /* control character mask */ + } + + /* + * Set up the Receive Buffer Descriptors + */ + for (i = 0;i < SCC_RXBD_CNT;i++) { + sccFrstRxBd[chan][i].status = M8xx_BD_EMPTY | M8xx_BD_INTERRUPT; + if (i == SCC_RXBD_CNT-1) { + sccFrstRxBd[chan][i].status |= M8xx_BD_WRAP; + } + sccFrstRxBd[chan][i].length = 0; + sccFrstRxBd[chan][i].buffer = (*rxBuf[chan])[i]; + } + /* + * Setup the Transmit Buffer Descriptor + */ + for (i = 0;i < SCC_TXBD_CNT;i++) { + sccFrstTxBd[chan][i].status = M8xx_BD_INTERRUPT; + if (i == SCC_TXBD_CNT-1) { + sccFrstTxBd[chan][i].status |= M8xx_BD_WRAP; + } + sccFrstTxBd[chan][i].length = 0; + sccFrstTxBd[chan][i].buffer = NULL; + } + + /* + * Set up SCC general and protocol-specific mode registers + */ + CHN_EVENT_CLR(chan,~0); /* Clear any pending events */ + CHN_MASK_SET(chan,0); /* Mask all interrupt/event sources */ + + if (m8xx_console_chan_desc[chan].is_scc) { + m8xx_console_chan_desc[chan].regs.sccr->psmr = 0xb000; /* 8N1, CTS flow control */ + m8xx_console_chan_desc[chan].regs.sccr->gsmr_h = 0x00000000; + m8xx_console_chan_desc[chan].regs.sccr->gsmr_l = 0x00028004; /* UART mode */ + } + else { + m8xx_console_chan_desc[chan].regs.smcr->smcmr = 0x4820; + } + /* + * Send "Init parameters" command + */ + m8xx_cp_execute_cmd(M8xx_CR_OP_INIT_RX_TX + | m8xx_console_chan_desc[chan].cr_chan_code); + + /* + * Enable receiver and transmitter + */ + if (m8xx_console_chan_desc[chan].is_scc) { + m8xx_console_chan_desc[chan].regs.sccr->gsmr_l |= 0x00000030; + } + else { + m8xx_console_chan_desc[chan].regs.smcr->smcmr |= 0x0003; + } + + if (m8xx_scc_mode[chan] != TERMIOS_POLLED) { + + rtems_irq_connect_data irq_conn_data = { + m8xx_console_chan_desc[chan].ivec_src, + sccInterruptHandler, /* rtems_irq_hdl */ + (rtems_irq_hdl_param)chan, /* (rtems_irq_hdl_param) */ + mpc8xx_console_irq_on, /* (rtems_irq_enable) */ + mpc8xx_console_irq_off, /* (rtems_irq_disable) */ + mpc8xx_console_irq_isOn /* (rtems_irq_is_enabled) */ + }; + if (!BSP_install_rtems_irq_handler (&irq_conn_data)) { + rtems_panic("console: cannot install IRQ handler"); + } + } +} + +/* + * polled scc read function + */ +static int +sccPollRead (int minor) +{ + int c = -1; + int chan = minor; + + while(1) { + if ((sccCurrRxBd[chan]->status & M8xx_BD_EMPTY) != 0) { + return -1; + } + + if (0 == (sccCurrRxBd[chan]->status & (M8xx_BD_OVERRUN + | M8xx_BD_PARITY_ERROR + | M8xx_BD_FRAMING_ERROR + | M8xx_BD_BREAK + | M8xx_BD_IDLE))) { + /* character received and no error detected */ + rtems_cache_invalidate_multiple_data_lines((void *)sccCurrRxBd[chan]->buffer, + sccCurrRxBd[chan]->length); + c = (unsigned)*((char *)sccCurrRxBd[chan]->buffer); + /* + * clear status + */ + } + sccCurrRxBd[chan]->status = + (sccCurrRxBd[chan]->status + & (M8xx_BD_WRAP | M8xx_BD_INTERRUPT)) + | M8xx_BD_EMPTY; + /* + * advance to next BD + */ + if ((sccCurrRxBd[chan]->status & M8xx_BD_WRAP) != 0) { + sccCurrRxBd[chan] = sccFrstRxBd[chan]; + } + else { + sccCurrRxBd[chan]++; + } + if (c >= 0) { + return c; + } + } +} + + +/* + * Device-dependent write routine + * Interrupt-driven devices: + * Begin transmission of as many characters as possible (minimum is 1). + * Polling devices: + * Transmit all characters. + */ +static ssize_t +sccInterruptWrite (int minor, const char *buf, size_t len) +{ + if (len > 0) { + int chan = minor; + + if ((sccPrepTxBd[chan]->status & M8xx_BD_READY) == 0) { + sccPrepTxBd[chan]->buffer = (char *)buf; + sccPrepTxBd[chan]->length = len; + rtems_cache_flush_multiple_data_lines((const void *)buf,len); + /* + * clear status, set ready bit + */ + sccPrepTxBd[chan]->status = + (sccPrepTxBd[chan]->status + & M8xx_BD_WRAP) + | M8xx_BD_READY | M8xx_BD_INTERRUPT; + if ((sccPrepTxBd[chan]->status & M8xx_BD_WRAP) != 0) { + sccPrepTxBd[chan] = sccFrstTxBd[chan]; + } + else { + sccPrepTxBd[chan]++; + } + } + } + + return 0; +} + +static ssize_t +sccPollWrite (int minor, const char *buf, size_t len) +{ + static char txBuf[CONS_CHN_CNT][SCC_TXBD_CNT]; + int chan = minor; + int bd_used; + size_t retval = len; + + while (len--) { + while (sccPrepTxBd[chan]->status & M8xx_BD_READY) + continue; + bd_used = sccPrepTxBd[chan]-sccFrstTxBd[chan]; + txBuf[chan][bd_used] = *buf++; + rtems_cache_flush_multiple_data_lines((const void *)&txBuf[chan][bd_used], + sizeof(txBuf[chan][bd_used])); + sccPrepTxBd[chan]->buffer = &(txBuf[chan][bd_used]); + sccPrepTxBd[chan]->length = 1; + sccPrepTxBd[chan]->status = + (sccPrepTxBd[chan]->status + & M8xx_BD_WRAP) + | M8xx_BD_READY; + if ((sccPrepTxBd[chan]->status & M8xx_BD_WRAP) != 0) { + sccPrepTxBd[chan] = sccFrstTxBd[chan]; + } + else { + sccPrepTxBd[chan]++; + } + } + return retval; +} + +/* + * printk basic support + */ +int BSP_output_chan = CONS_CHN_NONE; /* channel used for printk operation */ + +static void console_debug_putc_onlcr(const char c) +{ + rtems_interrupt_level irq_level; + + if (BSP_output_chan != CONS_CHN_NONE) { + rtems_interrupt_disable(irq_level); + + sccPollWrite (BSP_output_chan,&c,1); + rtems_interrupt_enable(irq_level); + } +} + +BSP_output_char_function_type BSP_output_char = console_debug_putc_onlcr; +BSP_polling_getchar_function_type BSP_poll_char = NULL; + + +/* +*************** +* BOILERPLATE * +*************** +*/ + +struct { + rtems_device_minor_number minor; + int driver_mode; +} channel_list[] = { + {CONS_CHN_SMC1,CONS_SMC1_MODE}, + {CONS_CHN_SMC2,CONS_SMC2_MODE}, + {CONS_CHN_SCC1,CONS_SCC1_MODE}, + {CONS_CHN_SCC2,CONS_SCC2_MODE}, + {CONS_CHN_SCC3,CONS_SCC3_MODE}, + {CONS_CHN_SCC4,CONS_SCC4_MODE} +}; + + +/* + * Initialize and register the device + */ +rtems_device_driver console_initialize(rtems_device_major_number major, + rtems_device_minor_number minor,/* ignored */ + void *arg + ) +{ + rtems_status_code status = RTEMS_SUCCESSFUL; + int chan,entry,ttynum; + char tty_name[] = "/dev/tty00"; + + /* + * Set up TERMIOS + */ + rtems_termios_initialize (); + /* + * init BRG allocataion + */ + sccBRGinit(); + ttynum = 0; + for (entry = 0; + (entry < sizeof(channel_list)/sizeof(channel_list[0])) + && (status == RTEMS_SUCCESSFUL); + entry++) { + if (channel_list[entry].driver_mode != CONS_MODE_UNUSED) { + /* + * Do device-specific initialization + */ + chan = channel_list[entry].minor; + m8xx_scc_mode[chan] = channel_list[entry].driver_mode; + sccInitialize (chan); + + /* + * build device name + */ + tty_name[sizeof(tty_name)-2] = '0'+ttynum; + ttynum++; + /* + * Register the device + */ + status = rtems_io_register_name (tty_name, + major, + channel_list[entry].minor); + if (status != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred (status); + } + } + } + /* + * register /dev/console + */ + status = rtems_io_register_name ("/dev/console", + major, + CONSOLE_CHN); + if (status != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred (status); + } + /* + * enable printk support + */ + BSP_output_chan = PRINTK_CHN; + + return RTEMS_SUCCESSFUL; +} + +/* + * Open the device + */ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg + ) +{ + rtems_status_code status; + int chan = minor; + rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *)arg; + static const rtems_termios_callbacks interruptCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + NULL, /* pollRead */ + sccInterruptWrite, /* write */ + sccSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_IRQ_DRIVEN /* outputUsesInterrupts */ + }; + static const rtems_termios_callbacks pollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + sccPollRead, /* pollRead */ + sccPollWrite, /* write */ + sccSetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + 0 /* outputUsesInterrupts */ + }; + + if (m8xx_scc_mode[chan] == TERMIOS_IRQ_DRIVEN) { + status = rtems_termios_open (major, minor, arg, &interruptCallbacks); + sccttyp[chan] = args->iop->data1; + } + else { + status = rtems_termios_open (major, minor, arg, &pollCallbacks); + sccttyp[chan] = args->iop->data1; + } + return status; +} + +/* + * Close the device + */ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg + ) +{ + rtems_status_code rc; + + rc = rtems_termios_close (arg); + sccttyp[minor] = NULL; + + return rc; + +} + +/* + * Read from the device + */ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg + ) +{ + return rtems_termios_read (arg); +} + +/* + * Write to the device + */ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg + ) +{ + return rtems_termios_write (arg); +} + +#if 0 +static int scc_io_set_trm_char(rtems_device_minor_number minor, + rtems_libio_ioctl_args_t *ioa) +{ + rtems_status_code rc = RTEMS_SUCCESSFUL; + con360_io_trm_char_t *trm_char_info = ioa->buffer; + + /* + * check, that parameter is non-NULL + */ + if ((rc == RTEMS_SUCCESSFUL) && + (trm_char_info == NULL)) { + rc = RTEMS_INVALID_ADDRESS; + } + /* + * transfer max_idl + */ + if (rc == RTEMS_SUCCESSFUL) { + if (trm_char_info->max_idl >= 0x10000) { + rc = RTEMS_INVALID_NUMBER; + } + else if (trm_char_info->max_idl > 0) { + CHN_PARAM_SET(minor,un.uart.max_idl ,trm_char_info->max_idl); + } + else if (trm_char_info->max_idl == 0) { + CHN_PARAM_SET(minor,un.uart.max_idl ,MAX_IDL_DEFAULT); + } + } + /* + * transfer characters + */ + if (rc == RTEMS_SUCCESSFUL) { + if (trm_char_info->char_cnt > CON8XX_TRM_CHAR_CNT) { + rc = RTEMS_TOO_MANY; + } + else if (trm_char_info->char_cnt >= 0) { + /* + * check, whether device is a SCC + */ + if ((rc == RTEMS_SUCCESSFUL) && + !m8xx_console_chan_desc[minor].is_scc) { + rc = RTEMS_UNSATISFIED; + } + else { + int idx = 0; + for(idx = 0;idx < trm_char_info->char_cnt;idx++) { + m8xx_console_chan_desc[minor].parms.sccp->un.uart.character[idx] = + trm_char_info->character[idx] & 0x00ff; + } + if (trm_char_info->char_cnt < CON8XX_TRM_CHAR_CNT) { + m8xx_console_chan_desc[minor].parms.sccp + ->un.uart.character[trm_char_info->char_cnt] = 0x8000; + } + } + } + } + + return rc; +} +#endif + +/* + * Handle ioctl request. + */ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg + ) +{ + rtems_libio_ioctl_args_t *ioa=arg; + + switch (ioa->command) { +#if 0 + case CON8XX_IO_SET_TRM_CHAR: + return scc_io_set_trm_char(minor, ioa); +#endif + default: + return rtems_termios_ioctl (arg); + break; + } +} + diff --git a/bsps/powerpc/virtex/console/consolelite.c b/bsps/powerpc/virtex/console/consolelite.c new file mode 100644 index 0000000000..4d0b2db17f --- /dev/null +++ b/bsps/powerpc/virtex/console/consolelite.c @@ -0,0 +1,425 @@ +/* + * This file contains the console driver for the xilinx uart lite. + * + * Author: Keith Robertson + * COPYRIGHT (c) 2005 by Linn Products Ltd, Scotland. + * + * Derived from libbsp/no_cpu/no_bsp/console.c and therefore also: + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + */ + +#include + +#include +#include +#include + +#include +#include +#include + +#include RTEMS_XPARAMETERS_H + +/* Status Register Masks */ +#define PARITY_ERROR 0x80 /* Parity Error */ +#define FRAME_ERROR 0x40 /* Frame Error */ +#define OVERRUN_ERROR 0x20 /* Overrun Error */ +#define STATUS_REG_ERROR_MASK ( PARITY_ERROR | FRAME_ERROR | OVERRUN_ERROR ) + +#define INTR_ENABLED 0x10 /* Interrupts are enabled */ +#define TX_FIFO_FULL 0x08 /* Transmit FIFO is full */ +#define TX_FIFO_EMPTY 0x04 /* Transmit FIFO is empty */ +#define RX_FIFO_FULL 0x02 /* Receive FIFO is full */ +#define RX_FIFO_VALID_DATA 0x01 /* Receive FIFO has valid data */ +/* Control Register Masks*/ +#define ENABLE_INTR 0x10 /* Enable interrupts */ +#define RST_RX_FIFO 0x02 /* Reset and clear RX FIFO */ +#define RST_TX_FIFO 0x01 /* Reset and clear TX FIFO */ + +/* General Defines */ +#define TX_FIFO_SIZE 16 +#define RX_FIFO_SIZE 16 + + + + +#define RECV_REG 0 +#define TRAN_REG 4 +#define STAT_REG 8 +#define CTRL_REG 12 + + + +RTEMS_INLINE_ROUTINE uint32_t xlite_uart_control(uint32_t base) +{ + uint32_t c = *((volatile uint32_t*)(base+CTRL_REG)); + return c; +} + + +RTEMS_INLINE_ROUTINE uint32_t xlite_uart_status(uint32_t base) +{ + uint32_t c = *((volatile uint32_t*)(base+STAT_REG)); + return c; +} + + +RTEMS_INLINE_ROUTINE uint32_t xlite_uart_read(uint32_t base) +{ + uint32_t c = *((volatile uint32_t*)(base+RECV_REG)); + return c; +} + + +RTEMS_INLINE_ROUTINE void xlite_uart_write(uint32_t base, char ch) +{ + *(volatile uint32_t*)(base+TRAN_REG) = (uint32_t)ch; + return; +} + + + +static int xlite_write_char(uint32_t base, char ch) +{ + uint32_t retrycount= 0, idler, status; + + while( ((status = xlite_uart_status(base)) & TX_FIFO_FULL) != 0 ) + { + ++retrycount; + + /* uart tx is busy */ + if( retrycount == 0x4000 ) + { + /* retrycount is arbitrary- just make it big enough so the uart is sure to be timed out before it trips */ + return -1; + } + + /* spin for a bit so we can sample the register rather than + * continually reading it */ + for( idler= 0; idler < 0x2000; idler++); + } + + xlite_uart_write(base, ch); + + return 1; +} + +static void xlite_init(int minor ) +{ + /* Nothing to do */ +} + +#if VIRTEX_CONSOLE_USE_INTERRUPTS +static void xlite_interrupt_handler(void *arg) +{ + int minor = (int) arg; + const console_tbl *ct = Console_Port_Tbl[minor]; + console_data *cd = &Console_Port_Data[minor]; + uint32_t base = ct->ulCtrlPort1; + uint32_t status = xlite_uart_status(base); + + while ((status & RX_FIFO_VALID_DATA) != 0) { + char c = (char) xlite_uart_read(base); + + rtems_termios_enqueue_raw_characters(cd->termios_data, &c, 1); + + status = xlite_uart_status(base); + } + + if (cd->bActive) { + rtems_termios_dequeue_characters(cd->termios_data, 1); + } +} +#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */ + +static int xlite_open( + int major, + int minor, + void *arg +) +{ + const console_tbl *ct = Console_Port_Tbl[minor]; + uint32_t base = ct->ulCtrlPort1; +#if VIRTEX_CONSOLE_USE_INTERRUPTS + rtems_status_code sc; +#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */ + + /* clear status register */ + *((volatile uint32_t*)(base+STAT_REG)) = 0; + + /* clear control register; reset fifos */ + *((volatile uint32_t*)(base+CTRL_REG)) = RST_RX_FIFO | RST_TX_FIFO; + +#if VIRTEX_CONSOLE_USE_INTERRUPTS + *((volatile uint32_t*)(base+CTRL_REG)) = ENABLE_INTR; + + sc = rtems_interrupt_handler_install( + ct->ulIntVector, + "xlite", + RTEMS_INTERRUPT_UNIQUE, + xlite_interrupt_handler, + (void *) minor + ); + assert(sc == RTEMS_SUCCESSFUL); +#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */ + + return 0; +} + +static int xlite_close( + int major, + int minor, + void *arg +) +{ + const console_tbl *ct = Console_Port_Tbl[minor]; + uint32_t base = ct->ulCtrlPort1; +#if VIRTEX_CONSOLE_USE_INTERRUPTS + rtems_status_code sc; +#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */ + + *((volatile uint32_t*)(base+CTRL_REG)) = 0; + +#if VIRTEX_CONSOLE_USE_INTERRUPTS + sc = rtems_interrupt_handler_remove( + ct->ulIntVector, + xlite_interrupt_handler, + (void *) minor + ); + assert(sc == RTEMS_SUCCESSFUL); +#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */ + + return 0; +} + + + +static int xlite_read_polled (int minor ) +{ + uint32_t base = Console_Port_Tbl[minor]->ulCtrlPort1; + + unsigned int status = xlite_uart_status(base); + + if(status & RX_FIFO_VALID_DATA) + return (int)xlite_uart_read(base); + else + return -1; +} + +#if VIRTEX_CONSOLE_USE_INTERRUPTS + +static ssize_t xlite_write_interrupt_driven( + int minor, + const char *buf, + size_t len +) +{ + console_data *cd = &Console_Port_Data[minor]; + + if (len > 0) { + const console_tbl *ct = Console_Port_Tbl[minor]; + uint32_t base = ct->ulCtrlPort1; + + xlite_uart_write(base, buf[0]); + + cd->bActive = true; + } else { + cd->bActive = false; + } + + return 0; +} + +#else /* VIRTEX_CONSOLE_USE_INTERRUPTS */ + +static ssize_t xlite_write_buffer_polled( + int minor, + const char *buf, + size_t len +) +{ + uint32_t base = Console_Port_Tbl[minor]->ulCtrlPort1; + int nwrite = 0; + + /* + * poll each byte in the string out of the port. + */ + while (nwrite < len) + { + if( xlite_write_char(base, *buf++) < 0 ) break; + nwrite++; + } + + /* + * return the number of bytes written. + */ + return nwrite; +} + +#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */ + +static void xlite_write_char_polled( + int minor, + char c +) +{ + uint32_t base = Console_Port_Tbl[minor]->ulCtrlPort1; + xlite_write_char(base, c); + return; +} + +static int xlite_set_attributes(int minor, const struct termios *t) +{ + return RTEMS_SUCCESSFUL; +} + + + + + + + +static const console_fns xlite_fns_polled = +{ + .deviceProbe = libchip_serial_default_probe, + .deviceFirstOpen = xlite_open, + .deviceLastClose = xlite_close, + .deviceRead = xlite_read_polled, + .deviceInitialize = xlite_init, + .deviceWritePolled = xlite_write_char_polled, + .deviceSetAttributes = xlite_set_attributes, +#if VIRTEX_CONSOLE_USE_INTERRUPTS + .deviceWrite = xlite_write_interrupt_driven, + .deviceOutputUsesInterrupts = true +#else /* VIRTEX_CONSOLE_USE_INTERRUPTS */ + .deviceWrite = xlite_write_buffer_polled, + .deviceOutputUsesInterrupts = false +#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */ +}; + + + + + + +/* +** Set ulCtrlPort1 to the base address of each UART Lite instance. Set in vhdl model. +*/ + + +console_tbl Console_Configuration_Ports[] = { +{ + "/dev/ttyS0", /* sDeviceName */ + SERIAL_CUSTOM, /* deviceType */ + &xlite_fns_polled, /* pDeviceFns */ + NULL, /* deviceProbe, assume it is there */ + NULL, /* pDeviceFlow */ + 16, /* ulMargin */ + 8, /* ulHysteresis */ + (void *) NULL, /* NULL */ /* pDeviceParams */ + STDIN_BASEADDRESS, /* ulCtrlPort1 */ + 0, /* ulCtrlPort2 */ + 0, /* ulDataPort */ + NULL, /* getRegister */ + NULL, /* setRegister */ + NULL, /* unused */ /* getData */ + NULL, /* unused */ /* setData */ + 0, /* ulClock */ + #ifdef XPAR_XPS_INTC_0_RS232_UART_INTERRUPT_INTR + .ulIntVector = XPAR_XPS_INTC_0_RS232_UART_INTERRUPT_INTR + #else + .ulIntVector = 0 + #endif +}, +#ifdef XPAR_UARTLITE_1_BASEADDR +{ + "/dev/ttyS1", /* sDeviceName */ + SERIAL_CUSTOM, /* deviceType */ + &xlite_fns_polled, /* pDeviceFns */ + NULL, /* deviceProbe, assume it is there */ + NULL, /* pDeviceFlow */ + 16, /* ulMargin */ + 8, /* ulHysteresis */ + (void *) NULL, /* NULL */ /* pDeviceParams */ + XPAR_UARTLITE_1_BASEADDR, /* ulCtrlPort1 */ + 0, /* ulCtrlPort2 */ + 0, /* ulDataPort */ + NULL, /* getRegister */ + NULL, /* setRegister */ + NULL, /* unused */ /* getData */ + NULL, /* unused */ /* setData */ + 0, /* ulClock */ + 0 /* ulIntVector -- base for port */ +}, +#endif +#ifdef XPAR_UARTLITE_2_BASEADDR +{ + "/dev/ttyS2", /* sDeviceName */ + SERIAL_CUSTOM, /* deviceType */ + &xlite_fns_polled, /* pDeviceFns */ + NULL, /* deviceProbe, assume it is there */ + NULL, /* pDeviceFlow */ + 16, /* ulMargin */ + 8, /* ulHysteresis */ + (void *) NULL, /* NULL */ /* pDeviceParams */ + XPAR_UARTLITE_2_BASEADDR, /* ulCtrlPort1 */ + 0, /* ulCtrlPort2 */ + 0, /* ulDataPort */ + NULL, /* getRegister */ + NULL, /* setRegister */ + NULL, /* unused */ /* getData */ + NULL, /* unused */ /* setData */ + 0, /* ulClock */ + 0 /* ulIntVector -- base for port */ +}, +#endif +#ifdef XPAR_UARTLITE_2_BASEADDR +{ + "/dev/ttyS3", /* sDeviceName */ + SERIAL_CUSTOM, /* deviceType */ + &xlite_fns_polled, /* pDeviceFns */ + NULL, /* deviceProbe, assume it is there */ + NULL, /* pDeviceFlow */ + 16, /* ulMargin */ + 8, /* ulHysteresis */ + (void *) NULL, /* NULL */ /* pDeviceParams */ + XPAR_UARTLITE_3_BASEADDR, /* ulCtrlPort1 */ + 0, /* ulCtrlPort2 */ + 0, /* ulDataPort */ + NULL, /* getRegister */ + NULL, /* setRegister */ + NULL, /* unused */ /* getData */ + NULL, /* unused */ /* setData */ + 0, /* ulClock */ + 0 /* ulIntVector -- base for port */ +} +#endif +}; + +unsigned long Console_Configuration_Count = + RTEMS_ARRAY_SIZE(Console_Configuration_Ports); + + +#include + +static void outputChar(char ch) +{ + xlite_write_char_polled( 0, ch ); +} + +static int inputChar(void) +{ + return xlite_read_polled(0); +} + +BSP_output_char_function_type BSP_output_char = outputChar; +BSP_polling_getchar_function_type BSP_poll_char = inputChar; + + diff --git a/bsps/riscv/riscv_generic/console/console-io.c b/bsps/riscv/riscv_generic/console/console-io.c new file mode 100644 index 0000000000..ded68ef7d2 --- /dev/null +++ b/bsps/riscv/riscv_generic/console/console-io.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2015 University of York. + * Hesham Almatary + * + * Copyright (c) 2013, The Regents of the University of California (Regents). + * All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +/* Most of the code below is copied from riscv-pk project */ +# define TOHOST_CMD(dev, cmd, payload) \ + (((uint64_t)(dev) << 56) | ((uint64_t)(cmd) << 48) | (uint64_t)(payload)) + +#define FROMHOST_DEV(fromhost_value) ((uint64_t)(fromhost_value) >> 56) +#define FROMHOST_CMD(fromhost_value) ((uint64_t)(fromhost_value) << 8 >> 56) +#define FROMHOST_DATA(fromhost_value) ((uint64_t)(fromhost_value) << 16 >> 16) + +volatile uint64_t tohost __attribute__((section(".htif"))); +volatile uint64_t fromhost __attribute__((section(".htif"))); +volatile int htif_console_buf; + +static void __check_fromhost() +{ + uint64_t fh = fromhost; + if (!fh) { + return; + } + fromhost = 0; + + // this should be from the console + assert(FROMHOST_DEV(fh) == 1); + switch (FROMHOST_CMD(fh)) { + case 0: + htif_console_buf = 1 + (uint8_t)FROMHOST_DATA(fh); + break; + case 1: + break; + default: + assert(0); + } +} + +static void __set_tohost(uintptr_t dev, uintptr_t cmd, uintptr_t data) +{ + while (tohost) { + __check_fromhost(); + } + tohost = TOHOST_CMD(dev, cmd, data); +} + +int htif_console_getchar() +{ + __check_fromhost(); + int ch = htif_console_buf; + if (ch >= 0) { + htif_console_buf = -1; + __set_tohost(1, 0, 0); + } + + return ch - 1; +} + +static void do_tohost_fromhost(uintptr_t dev, uintptr_t cmd, uintptr_t data) +{ + __set_tohost(dev, cmd, data); + + while (1) { + uint64_t fh = fromhost; + if (fh) { + if (FROMHOST_DEV(fh) == dev && FROMHOST_CMD(fh) == cmd) { + fromhost = 0; + break; + } + __check_fromhost(); + } + } +} + +void htif_console_putchar(uint8_t ch) +{ + __set_tohost(1, 1, ch); +} + +void htif_poweroff() +{ + while (1) { + fromhost = 0; + tohost = 1; + } +} + +void console_initialize_hardware(void) +{ + /* Do nothing */ +} + +static void outbyte_console(char ch) +{ + htif_console_putchar(ch); +} + +static char inbyte_console(void) +{ + return htif_console_getchar(); +} + +/* + * console_outbyte_polled + * + * This routine transmits a character using polling. + */ +void console_outbyte_polled( + int port, + char ch +) +{ + outbyte_console( ch ); +} + +/* + * console_inbyte_nonblocking + * + * This routine polls for a character. + */ + +int console_inbyte_nonblocking(int port) +{ + char c; + + c = inbyte_console(); + if (!c) { + return -1; + } + return (int) c; +} + +/* + * To support printk + */ + +#include + +static void RISCV_output_char(char c) +{ + console_outbyte_polled( 0, c ); +} + +BSP_output_char_function_type BSP_output_char = RISCV_output_char; +BSP_polling_getchar_function_type BSP_poll_char = + (void *)console_inbyte_nonblocking; diff --git a/bsps/sh/gensh1/console/sci.c b/bsps/sh/gensh1/console/sci.c new file mode 100644 index 0000000000..04d9ca5c70 --- /dev/null +++ b/bsps/sh/gensh1/console/sci.c @@ -0,0 +1,358 @@ +/* + * /dev/sci[0|1] for Hitachi SH 703X + * + * Author: Ralf Corsepius (corsepiu@faw.uni-ulm.de) + * + * COPYRIGHT (c) 1997-1999, Ralf Corsepius, Ulm, Germany + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * + * COPYRIGHT (c) 1998. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * NOTE: Some SH variants have 3 sci devices + */ + +#define SCI_MINOR_DEVICES 2 + +#define SH_SCI_BASE_0 SCI0_SMR +#define SH_SCI_BASE_1 SCI1_SMR + +struct scidev_t { + char * name ; + uint32_t addr ; + rtems_device_minor_number minor ; + unsigned short opened ; + tcflag_t cflags ; + speed_t spd ; +} sci_device[SCI_MINOR_DEVICES] = +{ + { "/dev/sci0", SH_SCI_BASE_0, 0, 0, CS8, B9600 }, + { "/dev/sci1", SH_SCI_BASE_1, 1, 0, CS8, B9600 } +} ; + +/* imported from scitab.rel */ +extern int _sci_get_brparms( + speed_t spd, + unsigned char *smr, + unsigned char *brr ); + +/* Translate termios' tcflag_t into sci settings */ +static int _sci_set_cflags( + struct scidev_t *sci_dev, + tcflag_t c_cflag, + speed_t spd ) +{ + uint8_t smr ; + uint8_t brr ; + + if ( spd ) + { + if ( _sci_get_brparms( spd, &smr, &brr ) != 0 ) + return -1 ; + } + + if ( c_cflag & CSIZE ) + { + if ( c_cflag & CS8 ) + smr &= ~SCI_SEVEN_BIT_DATA; + else if ( c_cflag & CS7 ) + smr |= SCI_SEVEN_BIT_DATA; + else + return -1 ; + } + + if ( c_cflag & CSTOPB ) + smr |= SCI_STOP_BITS_2; + else + smr &= ~SCI_STOP_BITS_2; + + if ( c_cflag & PARENB ) + smr |= SCI_PARITY_ON ; + else + smr &= ~SCI_PARITY_ON ; + + if ( c_cflag & PARODD ) + smr |= SCI_ODD_PARITY ; + else + smr &= ~SCI_ODD_PARITY; + + write8( smr, sci_dev->addr + SCI_SMR ); + write8( brr, sci_dev->addr + SCI_BRR ); + + return 0 ; +} + +static void _sci_init( + rtems_device_minor_number minor ) +{ + uint16_t temp16 ; + + /* Pin function controller initialisation for asynchronous mode */ + if( minor == 0) + { + temp16 = read16( PFC_PBCR1); + temp16 &= ~( PB8MD | PB9MD ); + temp16 |= (PB_TXD0 | PB_RXD0); + write16( temp16, PFC_PBCR1); + } + else + { + temp16 = read16( PFC_PBCR1); + temp16 &= ~( PB10MD | PB11MD); + temp16 |= (PB_TXD1 | PB_RXD1); + write16( temp16, PFC_PBCR1); + } + + /* disable sck-pin */ + if( minor == 0) + { + temp16 = read16( PFC_PBCR1); + temp16 &= ~(PB12MD); + write16( temp16, PFC_PBCR1); + } + else + { + temp16 = read16( PFC_PBCR1); + temp16 &= ~(PB13MD); + write16( temp16, PFC_PBCR1); + } +} + +static void _sci_tx_polled( + int minor, + const char buf ) +{ + struct scidev_t *scidev = &sci_device[minor] ; + int8_t ssr ; + + while ( !inb((scidev->addr + SCI_SSR) & SCI_TDRE )) + ; + write8(buf,scidev->addr+SCI_TDR); + + ssr = inb(scidev->addr+SCI_SSR); + ssr &= ~SCI_TDRE ; + write8(ssr,scidev->addr+SCI_SSR); +} + +static int _sci_rx_polled ( + int minor) +{ + struct scidev_t *scidev = &sci_device[minor] ; + + unsigned char c; + char ssr ; + ssr = read8(scidev->addr + SCI_SSR) ; + + if (ssr & (SCI_PER | SCI_FER | SCI_ORER)) + write8(ssr & ~(SCI_PER | SCI_FER | SCI_ORER), scidev->addr+SCI_SSR); + + if ( !(ssr & SCI_RDRF) ) + return -1; + + c = read8(scidev->addr + SCI_RDR) ; + + write8(ssr & ~SCI_RDRF,scidev->addr + SCI_SSR); + return c; +} + +/* + * sci_initialize + */ + +rtems_device_driver sh_sci_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg ) +{ + rtems_device_driver status ; + rtems_device_minor_number i; + + /* + * register all possible devices. + * the initialization of the hardware is done by sci_open + */ + + for ( i = 0 ; i < SCI_MINOR_DEVICES ; i++ ) + { + status = rtems_io_register_name( + sci_device[i].name, + major, + sci_device[i].minor ); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + } + + /* default hardware setup */ + + return RTEMS_SUCCESSFUL; +} + + +/* + * Open entry point + */ + +rtems_device_driver sh_sci_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg ) +{ + uint8_t temp8; + + /* check for valid minor number */ + if(( minor > ( SCI_MINOR_DEVICES -1 )) || ( minor < 0 )) + { + return RTEMS_INVALID_NUMBER; + } + + /* device already opened */ + if ( sci_device[minor].opened > 0 ) + { + sci_device[minor].opened++ ; + return RTEMS_SUCCESSFUL ; + } + + _sci_init( minor ); + + if (minor == 0) { + temp8 = read8(sci_device[minor].addr + SCI_SCR); + temp8 &= ~(SCI_TE | SCI_RE) ; + write8(temp8, sci_device[minor].addr + SCI_SCR); /* Clear SCR */ + _sci_set_cflags( &sci_device[minor], sci_device[minor].cflags, sci_device[minor].spd ); + +/* FIXME: Should be one bit delay */ + CPU_delay(50000); /* microseconds */ + + temp8 |= SCI_RE | SCI_TE; + write8(temp8, sci_device[minor].addr + SCI_SCR); /* Enable clock output */ + } else { + temp8 = read8(sci_device[minor].addr + SCI_SCR); + temp8 &= ~(SCI_TE | SCI_RE) ; + write8(temp8, sci_device[minor].addr + SCI_SCR); /* Clear SCR */ + _sci_set_cflags( &sci_device[minor], sci_device[minor].cflags, sci_device[minor].spd ); + +/* FIXME: Should be one bit delay */ + CPU_delay(50000); /* microseconds */ + + temp8 |= SCI_RE | SCI_TE; + write8(temp8, sci_device[minor].addr + SCI_SCR); /* Enable clock output */ + } + + sci_device[minor].opened++ ; + + return RTEMS_SUCCESSFUL ; +} + +/* + * Close entry point + */ + +rtems_device_driver sh_sci_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + if( sci_device[minor].opened == 0 ) + { + return RTEMS_INVALID_NUMBER; + } + + sci_device[minor].opened-- ; + + return RTEMS_SUCCESSFUL ; +} + +/* + * read bytes from the serial port. + */ + +rtems_device_driver sh_sci_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + int count = 0; + + rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg; + char * buffer = rw_args->buffer; + int maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + buffer[ count ] = _sci_rx_polled(minor); + if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { + buffer[ count++ ] = '\n'; + break; + } + } + + rw_args->bytes_moved = count; + return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; +} + +/* + * write bytes to the serial port. + */ + +rtems_device_driver sh_sci_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + int count; + + rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg; + char *buffer = rw_args->buffer; + int maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { +#if 0 + if ( buffer[ count ] == '\n') { + outbyte(minor, '\r'); + } +#endif + _sci_tx_polled( minor, buffer[ count ] ); + } + + rw_args->bytes_moved = maximum; + return 0; +} + +/* + * IO Control entry point + */ + +rtems_device_driver sh_sci_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + /* Not yet supported */ + return RTEMS_SUCCESSFUL ; +} diff --git a/bsps/sh/gensh2/console/config.c b/bsps/sh/gensh2/console/config.c new file mode 100644 index 0000000000..a2f25742dd --- /dev/null +++ b/bsps/sh/gensh2/console/config.c @@ -0,0 +1,130 @@ +/* + * This file contains the TTY driver table. The implementation is + * based on libchip/serial drivers, but it uses internal SHx SCI so + * the implementation of the driver is placed in + * lib/libcpu/sh/sh7045/sci instead of libchip/serial. + * + * COPYRIGHT (c) 1989-2001. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Function set for interrupt enabled termios console + */ +const console_fns sh_sci_fns = +{ + libchip_serial_default_probe, /* deviceProbe */ + sh_sci_first_open, /* deviceFirstOpen */ + NULL, /* deviceLastClose */ + NULL, /* deviceRead */ + sh_sci_write_support_int, /* deviceWrite */ + sh_sci_initialize_interrupts, /* deviceInitialize */ + sh_sci_write_polled, /* deviceWritePolled */ + sh_sci_set_attributes, /* deviceSetAttributes */ + TERMIOS_IRQ_DRIVEN /* deviceOutputUsesInterrupts */ +}; + +/* + * Function set for polled termios console + */ +const console_fns sh_sci_fns_polled = +{ + libchip_serial_default_probe, /* deviceProbe */ + sh_sci_first_open, /* deviceFirstOpen */ + sh_sci_last_close, /* deviceLastClose */ + sh_sci_inbyte_nonblocking_polled, /* deviceRead */ + sh_sci_write_support_polled, /* deviceWrite */ + sh_sci_init, /* deviceInitialize */ + sh_sci_write_polled, /* deviceWritePolled */ + sh_sci_set_attributes, /* deviceSetAttributes */ + TERMIOS_POLLED /* deviceOutputUsesInterrupts */ +}; + +#if 1 /* (CONSOLE_USE_INTERRUPTS) */ +#define SCI_FUNCTIONS &sh_sci_fns +#else +#define SCI_FUNCTIONS &sh_sci_fns_polled +#endif + +static const struct termios term1 = { + 0, + 0, + 0, + 0, + {0}, + B9600 | CS8, + B9600 | CS8 +}; + +static const struct termios term2 = { + 0, + 0, + 0, + 0, + {0}, + B115200 | CS8, + B115200 | CS8 +}; + +console_tbl Console_Configuration_Ports[] = { + { + "/dev/sci0", /* sDeviceName */ + SERIAL_CUSTOM, /* deviceType */ + SCI_FUNCTIONS, /* pDeviceFns */ + NULL, /* deviceProbe */ + NULL, /* pDeviceFlow */ + 16, /* ulMargin */ + 8, /* ulHysteresis */ + (void *)&term1, /* baud rate */ /* pDeviceParams */ + SCI_SMR0, /* ulCtrlPort1 */ + 3, /* ulCtrlPort2 as IRQ priority level*/ + TXI0_ISP_V, /* ulDataPort as TX end vector number*/ + NULL, /* unused */ /* getRegister */ + NULL, /* unused */ /* setRegister */ + NULL, /* unused */ /* getData */ + NULL, /* unused */ /* setData */ + 0, /* ulClock */ + RXI0_ISP_V, /* ulIntVector as RX end vector number*/ + }, + { + "/dev/sci1", /* sDeviceName */ + SERIAL_CUSTOM, /* deviceType */ + SCI_FUNCTIONS, /* pDeviceFns */ + NULL, /* deviceProbe */ + NULL, /* pDeviceFlow */ + 16, /* ulMargin */ + 8, /* ulHysteresis */ + (void *)&term2, /* baud rate */ /* pDeviceParams */ + SCI_SMR1, /* ulCtrlPort1 */ + 3, /* ulCtrlPort2 as IRQ priority level*/ + TXI1_ISP_V, /* ulDataPort as TX end vector number*/ + NULL, /* unused */ /* getRegister */ + NULL, /* unused */ /* setRegister */ + NULL, /* unused */ /* getData */ + NULL, /* unused */ /* setData */ + 0, /* ulClock */ + RXI1_ISP_V, /* ulIntVector as RX end vector number*/ + } +}; + +/* + * Declare some information used by the console driver + */ + +#define NUM_CONSOLE_PORTS (sizeof(Console_Configuration_Ports)/sizeof(console_tbl)) + +unsigned long Console_Configuration_Count = NUM_CONSOLE_PORTS; diff --git a/bsps/sh/gensh2/console/sci.c b/bsps/sh/gensh2/console/sci.c new file mode 100644 index 0000000000..143fc1bb94 --- /dev/null +++ b/bsps/sh/gensh2/console/sci.c @@ -0,0 +1,554 @@ +/* + * /dev/sci[0|1] for Hitachi SH 704X + * + * The SH doesn't have a designated console device. Therefore we "alias" + * another device as /dev/console and revector all calls to /dev/console + * to this device. + * + * This approach is similar to installing a sym-link from one device to + * another device. If rtems once will support sym-links for devices files, + * this implementation could be dropped. + */ + +/* + * Author: Ralf Corsepius (corsepiu@faw.uni-ulm.de) + * + * COPYRIGHT (c) 1997-1998, FAW Ulm, Germany + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * + * COPYRIGHT (c) 1998. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + * Modified to reflect sh7045 processor: + * John M. Mills (jmills@tga.com) + * TGA Technologies, Inc. + * 100 Pinnacle Way, Suite 140 + * Norcross, GA 30071 U.S.A. + * + * This modified file may be copied and distributed in accordance + * the above-referenced license. It is provided for critique and + * developmental purposes without any warranty nor representation + * by the authors or by TGA Technologies. + */ + +#include + + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifndef STANDALONE_EVB +#define STANDALONE_EVB 0 +#endif + +/* + * NOTE: Some SH variants have 3 sci devices + */ + +#define SCI_MINOR_DEVICES 2 + +/* + * FIXME: sh7045 register names match Hitachi data book, + * but conflict with RTEMS sh7032 usage. + */ + +#define SH_SCI_BASE_0 SCI_SMR0 +#define SH_SCI_BASE_1 SCI_SMR1 + +#define SH_SCI_DEF_COMM_0 CS8, B9600 +#define SH_SCI_DEF_COMM_1 CS8, B38400 +/* #define SH_SCI_DEF_COMM_1 CS8, B9600 */ + +struct scidev_t { + char * name; + uint32_t addr; + rtems_device_minor_number minor; + unsigned short opened; + tcflag_t cflags; + speed_t spd; +} sci_device[SCI_MINOR_DEVICES] = +{ + { "/dev/sci0", SH_SCI_BASE_0, 0, 0, SH_SCI_DEF_COMM_0 }, + { "/dev/sci1", SH_SCI_BASE_1, 1, 0, SH_SCI_DEF_COMM_1 } +}; + +/* local data structures maintain hardware configuration */ +#if UNUSED +static sci_setup_t sio_param[2]; +#endif + +/* Translate termios' tcflag_t into sci settings */ +static int _sci_set_cflags( + struct scidev_t *sci_dev, + tcflag_t c_cflag, + speed_t spd +) +{ + uint8_t smr; + uint8_t brr; + + if ( spd ) + { + if ( _sci_get_brparms( spd, &smr, &brr ) != 0 ) + return -1; + } + + if ( c_cflag & CSIZE ) + { + if ( c_cflag & CS8 ) + smr &= ~SCI_SEVEN_BIT_DATA; + else if ( c_cflag & CS7 ) + smr |= SCI_SEVEN_BIT_DATA; + else + return -1; + } + + if ( c_cflag & CSTOPB ) + smr |= SCI_STOP_BITS_2; + else + smr &= ~SCI_STOP_BITS_2; + + if ( c_cflag & PARENB ) + smr |= SCI_PARITY_ON; + else + smr &= ~SCI_PARITY_ON; + + if ( c_cflag & PARODD ) + smr |= SCI_ODD_PARITY; + else + smr &= ~SCI_ODD_PARITY; + + write8( smr, sci_dev->addr + SCI_SMR ); + write8( brr, sci_dev->addr + SCI_BRR ); + + return 0; +} + +/* + * local functions operate SCI ports 0 and 1 + * called from polling routines or ISRs + */ +static bool wrtSCI0(unsigned char ch) +{ + uint8_t temp; + bool result = false; + + if ((read8(SCI_SSR0) & SCI_TDRE) != 0x00) { + /* Write the character to the TDR */ + write8(ch, SCI_TDR0); + /* Clear the TDRE bit */ + temp = read8(SCI_SSR0) & ~SCI_TDRE; + write8(temp, SCI_SSR0); + result = true; + } + return result; +} /* wrtSCI0 */ + +static bool wrtSCI1(unsigned char ch) +{ + uint8_t temp; + bool result = false; + + if ((read8(SCI_SSR1) & SCI_TDRE) != 0x00) { + /* Write the character to the TDR */ + write8(ch, SCI_TDR1); + /* Clear the TDRE bit */ + temp = read8(SCI_SSR1) & ~SCI_TDRE; + write8(temp, SCI_SSR1); + result = true; + } + return result; +} /* wrtSCI1 */ + +/* polled output steers byte to selected port */ +static void sh_sci_outbyte_polled( + rtems_device_minor_number minor, + char ch ) +{ + if (minor == 0) /* blocks until port ready */ + while (wrtSCI0(ch) != true); /* SCI0*/ + else + while (wrtSCI1(ch) != true); /* SCI1*/ +} /* sh_sci_outbyte_polled */ + +/* + * Initial version calls polled output driver and blocks + */ +static void outbyte( + rtems_device_minor_number minor, + char ch) +{ + sh_sci_outbyte_polled(minor, (unsigned char)ch); +} /* outbyte */ + +static bool rdSCI0(unsigned char *ch) +{ + uint8_t temp; + bool result = false; + + if ((read8(SCI_SSR0) & SCI_RDRF) != 0x00) { + /* read input */ + *ch = read8(SCI_RDR0); + /* Clear RDRF flag */ + temp = read8(SCI_SSR0) & ~SCI_RDRF; + write8(temp, SCI_SSR0); + /* Check for transmission errors */ + if (temp & (SCI_ORER | SCI_FER | SCI_PER)) { + /* TODO: report to RTEMS transmission error */ + + /* clear error flags*/ + temp &= ~(SCI_ORER | SCI_FER | SCI_PER); + write8(temp, SCI_SSR0); + } + result = true; + } + return result; +} /* rdSCI0 */ + +static bool rdSCI1(unsigned char *ch) +{ + uint8_t temp; + bool result = false; + + if ((read8(SCI_SSR1) & SCI_RDRF) != 0x00) { + /* read input */ + *ch = read8(SCI_RDR1); + /* Clear RDRF flag */ + temp= read8(SCI_SSR1) & ~SCI_RDRF; + write8(temp, SCI_SSR1); + /* Check for transmission errors */ + if (temp & (SCI_ORER | SCI_FER | SCI_PER)) { + /* TODO: report to RTEMS transmission error */ + + /* clear error flags*/ + temp &= ~(SCI_ORER | SCI_FER | SCI_PER); + write8(temp, SCI_SSR1); + } + result = true; + } + return result; +} /* rdSCI1 */ + +/* initial version pulls byte from selected port */ +static char sh_sci_inbyte_polled( rtems_device_minor_number minor ) +{ + uint8_t ch = 0; + + if (minor == 0) /* blocks until char.ready */ + while (rdSCI0(&ch) != true); /* SCI0 */ + else + while (rdSCI1(&ch) != true); /* SCI1 */ + return ch; +} /* sh_sci_inbyte_polled */ + +/* Initial version calls polled input driver */ +static char inbyte( rtems_device_minor_number minor ) +{ + char ch; + + ch = sh_sci_inbyte_polled(minor); + return ch; +} /* inbyte */ + +/* sh_sci_initialize + * + * This routine initializes (registers) the sh_sci IO drivers. + * + * Input parameters: ignored + * + * Output parameters: NONE + * + * Return values: RTEMS_SUCCESSFUL + * if all sci[...] register, else calls + * rtems_fatal_error_occurred(status) + */ +rtems_device_driver sh_sci_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg ) +{ + rtems_device_driver status; + rtems_device_minor_number i; + + /* + * register all possible devices. + * the initialization of the hardware is done by sci_open + * + * One of devices could be previously registered by console + * initialization therefore we check it everytime + */ + for ( i = 0 ; i < SCI_MINOR_DEVICES ; i++ ) { + /* OK. We assume it is not registered yet. */ + status = rtems_io_register_name( + sci_device[i].name, + major, + sci_device[i].minor + ); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + } + + /* non-default hardware setup occurs in sh_sci_open() */ + return RTEMS_SUCCESSFUL; +} + +/* + * Open entry point + * Sets up port and pins for selected sci. + */ +rtems_device_driver sh_sci_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg ) +{ + uint8_t temp8; + uint16_t temp16; + + unsigned a; + + /* check for valid minor number */ + if (( minor > ( SCI_MINOR_DEVICES -1 )) || ( minor < 0 )) { + return RTEMS_INVALID_NUMBER; + } + + /* device already opened */ + if ( sci_device[minor].opened > 0 ) { + sci_device[minor].opened++; + return RTEMS_SUCCESSFUL; + } + + /* set PFC registers to enable I/O pins */ + + if ((minor == 0)) { + temp16 = read16(PFC_PACRL2); /* disable SCK0, DMA, IRQ */ + temp16 &= ~(PA2MD1 | PA2MD0); + temp16 |= (PA_TXD0 | PA_RXD0); /* enable pins for Tx0, Rx0 */ + write16(temp16, PFC_PACRL2); + + } else if (minor == 1) { + temp16 = read16(PFC_PACRL2); /* disable SCK1, DMA, IRQ */ + temp16 &= ~(PA5MD1 | PA5MD0); + temp16 |= (PA_TXD1 | PA_RXD1); /* enable pins for Tx1, Rx1 */ + write16(temp16, PFC_PACRL2); + + } /* add other devices and pins as req'd. */ + + /* set up SCI registers */ + write8(0x00, sci_device[minor].addr + SCI_SCR); /* Clear SCR */ + /* set SMR and BRR */ + _sci_set_cflags( &sci_device[minor], sci_device[minor].cflags, sci_device[minor].spd ); + + for (a=0; a < 10000L; a++) { /* Delay */ + __asm__ volatile ("nop"); + } + + write8((SCI_RE | SCI_TE), /* enable async. Tx and Rx */ + sci_device[minor].addr + SCI_SCR); + + /* clear error flags */ + temp8 = read8(sci_device[minor].addr + SCI_SSR); + while (temp8 & (SCI_RDRF | SCI_ORER | SCI_FER | SCI_PER)) { + temp8 = read8(sci_device[minor].addr + SCI_RDR); /* flush input */ + temp8 = read8(sci_device[minor].addr + SCI_SSR); /* clear some flags */ + write8(temp8 & ~(SCI_RDRF | SCI_ORER | SCI_FER | SCI_PER), + sci_device[minor].addr + SCI_SSR); + temp8 = read8(sci_device[minor].addr + SCI_SSR); /* check if everything is OK */ + } + /* Clear RDRF flag */ + write8(0x00, sci_device[minor].addr + SCI_TDR); /* force output */ + /* Clear the TDRE bit */ + temp8 = read8(sci_device[minor].addr + SCI_SSR) & ~SCI_TDRE; + write8(temp8, sci_device[minor].addr + SCI_SSR); + + /* add interrupt setup if required */ + + + sci_device[minor].opened++; + + return RTEMS_SUCCESSFUL; +} + +/* + * Close entry point + */ +rtems_device_driver sh_sci_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + /* FIXME: Incomplete */ + if ( sci_device[minor].opened > 0 ) + sci_device[minor].opened--; + else + return RTEMS_INVALID_NUMBER; + + return RTEMS_SUCCESSFUL; +} + +/* + * read bytes from the serial port. We only have stdin. + */ +rtems_device_driver sh_sci_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args; + char *buffer; + int maximum; + int count = 0; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + buffer[ count ] = inbyte(minor); + if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { + buffer[ count++ ] = '\n'; + break; + } + } + + rw_args->bytes_moved = count; + return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; +} + +/* + * write bytes to the serial port. Stdout and stderr are the same. + */ +rtems_device_driver sh_sci_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + int count; + int maximum; + rtems_libio_rw_args_t *rw_args; + char *buffer; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + if ( buffer[ count ] == '\n') { + outbyte(minor, '\r'); + } + outbyte( minor, buffer[ count ] ); + } + + rw_args->bytes_moved = maximum; + return 0; +} + +/* + * IO Control entry point + */ +rtems_device_driver sh_sci_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + /* Not yet supported */ + return RTEMS_SUCCESSFUL; +} + +/* + * Termios polled first open + */ +static int _sh_sci_poll_first_open(int major, int minor, void *arg) +{ + return sh_sci_open(major, minor, arg); +} + +/* + * Termios general last close + */ +static int _sh_sci_last_close(int major, int minor, void *arg) +{ + return sh_sci_close(major, minor, arg); +} + +/* + * Termios polled read + */ +static int _sh_sci_poll_read(int minor) +{ + int value = -1; + uint8_t ch = 0; + + if ( minor == 0 ) { + if ( rdSCI0( &ch ) ) + value = (int) ch; + } else if ( minor == 1 ) { + if ( rdSCI1( &ch ) ) + value = (int) ch; + } + return value; +} + +/* + * Termios polled write + */ +static ssize_t _sh_sci_poll_write(int minor, const char *buf, size_t len) +{ + size_t count; + + for (count = 0; count < len; count++) + outbyte( minor, buf[count] ); + return count; +} + +/* + * Termios set attributes + */ +static int _sh_sci_set_attributes( int minor, const struct termios *t) +{ + return _sci_set_cflags( &sci_device[ minor ], t->c_cflag, t->c_ospeed); +} + + +const rtems_termios_callbacks sci_poll_callbacks = { + _sh_sci_poll_first_open, /* FirstOpen*/ + _sh_sci_last_close, /* LastClose*/ + _sh_sci_poll_read, /* PollRead */ + _sh_sci_poll_write, /* Write */ + _sh_sci_set_attributes, /* setAttributes */ + NULL, /* stopRemoteTX */ + NULL, /* StartRemoteTX */ + 0 /* outputUsesInterrupts */ +}; + +/* FIXME: not yet supported */ +const rtems_termios_callbacks sci_interrupt_callbacks; + +const rtems_termios_callbacks* sh_sci_get_termios_handlers( bool poll ) +{ + return poll ? + &sci_poll_callbacks : + &sci_interrupt_callbacks; +} diff --git a/bsps/sh/gensh2/console/sci_termios.c b/bsps/sh/gensh2/console/sci_termios.c new file mode 100644 index 0000000000..5d588065af --- /dev/null +++ b/bsps/sh/gensh2/console/sci_termios.c @@ -0,0 +1,449 @@ +/* + * Termios console serial driver. + */ + +/* + * Based on SCI driver by Ralf Corsepius and John M. Mills + * + * Author: Radzislaw Galler + * + * COPYRIGHT (c) 1989-2001. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + */ + +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + + +/* + * Some handy macros + */ +#define SH_SCI_REG_DATA(_data, _minor, _register) \ + (write8(_data, Console_Port_Tbl[_minor]->ulCtrlPort1 + (_register))) + +#define SH_SCI_REG_FLAG(_flag, _minor, _register) \ + (write8(read8(Console_Port_Tbl[_minor]->ulCtrlPort1 + (_register)) | (_flag), \ + Console_Port_Tbl[_minor]->ulCtrlPort1 + (_register))) + +#define SH_SCI_REG_MASK(_flag, _minor, _register) \ + (write8(read8(Console_Port_Tbl[_minor]->ulCtrlPort1 + (_register)) & ~(_flag),\ + Console_Port_Tbl[_minor]->ulCtrlPort1 + (_register))) + +/* + * NOTE: Some SH variants have 3 sci devices + */ + +#define SCI_MINOR_DEVICES 2 + + +/* + * Automatically generated function imported from scitab.rel + */ +extern int _sci_get_brparms( + speed_t spd, + unsigned char *smr, + unsigned char *brr +); + +/* + * Translate termios flags into SCI settings + */ +int sh_sci_set_attributes( + int minor, + const struct termios *t +) +{ + uint8_t smr; + uint8_t brr; + int a; + + tcflag_t c_cflag = t->c_cflag; + speed_t spd = t->c_ospeed; + + if ( spd ) { + if ( _sci_get_brparms( spd, &smr, &brr ) != 0 ) + return -1 ; + } + + if ( c_cflag & CSIZE ) { + if ( c_cflag & CS8 ) + smr &= ~SCI_SEVEN_BIT_DATA; + else if ( c_cflag & CS7 ) + smr |= SCI_SEVEN_BIT_DATA; + else + return -1 ; + } + + if ( c_cflag & CSTOPB ) + smr |= SCI_STOP_BITS_2; + else + smr &= ~SCI_STOP_BITS_2; + + if ( c_cflag & PARENB ) + smr |= SCI_PARITY_ON ; + else + smr &= ~SCI_PARITY_ON ; + + if ( c_cflag & PARODD ) + smr |= SCI_ODD_PARITY ; + else + smr &= ~SCI_ODD_PARITY; + + SH_SCI_REG_MASK((SCI_RE | SCI_TE), minor, SCI_SCR); + + SH_SCI_REG_DATA(smr, minor, SCI_SMR); + SH_SCI_REG_DATA(brr, minor, SCI_BRR); + + for (a=0; a < 10000L; a++) { /* Delay one bit */ + __asm__ volatile ("nop"); + } + + SH_SCI_REG_FLAG((SCI_RE | SCI_TE), minor, SCI_SCR); + + return 0; +} + +/* + * Receive-data-full ISR + * + * The same routine for all interrupt sources of the same type. + */ +static rtems_isr sh_sci_rx_isr(rtems_vector_number vector) +{ + int minor; + + for (minor = 0; minor < Console_Port_Count; minor++) { + if (Console_Port_Tbl[minor]->ulIntVector == vector) { + char temp8; + + /* + * FIXME: error handling should be added + */ + temp8 = read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_RDR); + + rtems_termios_enqueue_raw_characters( + Console_Port_Data[minor].termios_data, &temp8, 1); + + SH_SCI_REG_MASK(SCI_RDRF, minor, SCI_SSR); + break; + } + } +} + +/* + * Transmit-data-empty ISR + * + * The same routine for all interrupt sources of the same type. + */ +static rtems_isr sh_sci_tx_isr(rtems_vector_number vector) +{ + int minor; + + for (minor = 0; minor < Console_Port_Count; minor++) { + if (Console_Port_Tbl[minor]->ulDataPort == vector) { + /* + * FIXME: Error handling should be added + */ + + /* + * Mask end-of-transmission interrupt + */ + SH_SCI_REG_MASK(SCI_TIE, minor, SCI_SCR); + + if (rtems_termios_dequeue_characters( + Console_Port_Data[minor].termios_data, 1)) { + /* + * More characters to be received - interrupt must be enabled + */ + SH_SCI_REG_FLAG(SCI_TIE, minor, SCI_SCR); + } + break; + } + } +} + + +/* + * Initialization of serial port + */ +void sh_sci_init(int minor) +{ + uint16_t temp16; + + /* + * set PFC registers to enable I/O pins + */ + if ((minor == 0)) { + temp16 = read16(PFC_PACRL2); /* disable SCK0, DMA, IRQ */ + temp16 &= ~(PA2MD1 | PA2MD0); + temp16 |= (PA_TXD0 | PA_RXD0); /* enable pins for Tx0, Rx0 */ + write16(temp16, PFC_PACRL2); + + } else if (minor == 1) { + temp16 = read16(PFC_PACRL2); /* disable SCK1, DMA, IRQ */ + temp16 &= ~(PA5MD1 | PA5MD0); + temp16 |= (PA_TXD1 | PA_RXD1); /* enable pins for Tx1, Rx1 */ + write16(temp16, PFC_PACRL2); + } + + /* + * Non-default hardware setup occurs in sh_sci_first_open + */ +} + +/* + * Initialization of interrupts + * + * Interrupts can be started only after opening a device, so interrupt + * flags are set up in sh_sci_first_open function + */ +void sh_sci_initialize_interrupts(int minor) +{ + rtems_isr_entry old_isr; + rtems_status_code status; + + sh_sci_init(minor); + /* + * Disable IRQ of SCIx + */ + status = sh_set_irq_priority( Console_Port_Tbl[minor]->ulIntVector, 0); + + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + SH_SCI_REG_MASK(SCI_RIE, minor, SCI_SCR); + + /* + * Catch apropriate vectors + */ + status = rtems_interrupt_catch( + sh_sci_rx_isr, + Console_Port_Tbl[minor]->ulIntVector, + &old_isr); + + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + status = rtems_interrupt_catch( + sh_sci_tx_isr, + Console_Port_Tbl[minor]->ulDataPort, + &old_isr); + + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + /* + * Enable IRQ of SCIx + */ + SH_SCI_REG_FLAG(SCI_RIE, minor, SCI_SCR); + + status = sh_set_irq_priority( + Console_Port_Tbl[minor]->ulIntVector, + Console_Port_Tbl[minor]->ulCtrlPort2); + + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); +} + + +/* + * Open entry point + * Sets up port and pins for selected sci. + */ + +int sh_sci_first_open( + int major, + int minor, + void *arg +) +{ + char temp8; + unsigned int a ; + + /* + * check for valid minor number + */ + if (( minor > ( SCI_MINOR_DEVICES -1 )) || ( minor < 0 )) { + return RTEMS_INVALID_NUMBER; + } + + /* + * set up SCI registers + */ + /* Clear SCR - disable Tx and Rx */ + SH_SCI_REG_DATA(0x00, minor, SCI_SCR); + + /* set SMR and BRR - baudrate and format */ + sh_sci_set_attributes(minor, Console_Port_Tbl[minor]->pDeviceParams); + + for (a=0; a < 10000L; a++) { /* Delay */ + __asm__ volatile ("nop"); + } + + write8((SCI_RE | SCI_TE), /* enable async. Tx and Rx */ + Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_SCR); + + /* + * clear error flags + */ + temp8 = read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_SSR); + while(temp8 & (SCI_RDRF | SCI_ORER | SCI_FER | SCI_PER)) { + /* flush input */ + temp8 = read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_RDR); + + /* clear some flags */ + SH_SCI_REG_FLAG((SCI_RDRF|SCI_ORER|SCI_FER|SCI_PER), minor, SCI_SSR); + + /* check if everything is OK */ + temp8 = read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_SSR); + } + + /* Clear RDRF flag */ + SH_SCI_REG_DATA(0x00, minor, SCI_TDR); /* force output */ + + /* Clear the TDRE bit */ + SH_SCI_REG_FLAG(SCI_TDRE, minor, SCI_SSR); + + /* + * Interrupt setup + */ + if (Console_Port_Tbl[minor]->pDeviceFns->deviceOutputUsesInterrupts) { + SH_SCI_REG_FLAG(SCI_RIE, minor, SCI_SCR); + } + + return RTEMS_SUCCESSFUL ; +} + +/* + * Close entry point + */ + +int sh_sci_last_close( + int major, + int minor, + void *arg +) +{ + /* FIXME: Incomplete */ + + /* Shutdown interrupts if necessary */ + if (Console_Port_Tbl[minor]->pDeviceFns->deviceOutputUsesInterrupts) + { + SH_SCI_REG_MASK((SCI_TIE | SCI_RIE), minor, SCI_SCR); + } + return RTEMS_SUCCESSFUL ; +} + +/* + * Interrupt aware write routine + */ +ssize_t sh_sci_write_support_int( + int minor, + const char *buf, + size_t len +) +{ + if (!len) + return 0; + /* + * Put data into TDR and clear transmission-end-flag + */ + SH_SCI_REG_DATA(*buf, minor, SCI_TDR); + SH_SCI_REG_MASK(SCI_TDRE, minor, SCI_SSR); + /* + * Enable interrupt + */ + SH_SCI_REG_FLAG(SCI_TIE, minor, SCI_SCR); + + return 1; +} + +/* + * Polled write method + */ +ssize_t sh_sci_write_support_polled( + int minor, + const char *buf, + size_t len +) +{ + int count = 0; + + while(count < len) { + sh_sci_write_polled(minor, buf[count]); + count++; + } + /* + * Return number of bytes written + */ + return count; +} + +/* + * Polled write of one character at a time + */ +void sh_sci_write_polled( + int minor, + char c +) +{ + /* + * Wait for end of previous character + */ + while(!(read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_SSR) & SCI_TDRE)); + /* + * Send the character + */ + SH_SCI_REG_DATA(c, minor, SCI_TDR); + + /* + * Clear TDRE flag + */ + SH_SCI_REG_MASK(SCI_TDRE, minor, SCI_SSR); +} + +/* + * Non-blocking read + */ +int sh_sci_inbyte_nonblocking_polled(int minor) +{ + char inbyte; + + /* + * Check if input buffer is full + */ + if (read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_SSR) & SCI_RDRF) { + inbyte = read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_RDR); + SH_SCI_REG_MASK(SCI_RDRF, minor, SCI_SSR); + + /* + * Check for errors + */ + if (read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_SSR) & + (SCI_ORER | SCI_FER | SCI_PER)) { + SH_SCI_REG_MASK((SCI_ORER | SCI_FER | SCI_PER), minor, SCI_SSR); + return -1; + } + return (int)inbyte; + } + return -1; +} diff --git a/bsps/sh/gensh4/console/console.c b/bsps/sh/gensh4/console/console.c new file mode 100644 index 0000000000..917556df4e --- /dev/null +++ b/bsps/sh/gensh4/console/console.c @@ -0,0 +1,469 @@ +/* + * Console driver for SH-4 UART modules + * + * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia + * Author: Alexandra Kossovsky + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include +#include +#include + +#include "sh/sh4uart.h" + +/* Descriptor structures for two on-chip UART channels */ +sh4uart sh4_uarts[2]; + +/* Console operations mode: + * 0 - raw (non-termios) polled input/output + * 1 - termios-based polled input/output + * 2 - termios-based interrupt-driven input/output + * 3 - non-termios over gdb stub + */ +int console_mode = 3; +#define CONSOLE_MODE_RAW (0) +#define CONSOLE_MODE_POLL (1) +#define CONSOLE_MODE_INT (2) +#define CONSOLE_MODE_IPL (3) + +/* Wrapper functions for SH-4 UART generic driver */ + +/* console_poll_read -- + * wrapper for poll read function + * + * PARAMETERS: + * minor - minor device number + * + * RETURNS: + * character code readed from UART, or -1 if there is no characters + * available + */ +static int +console_poll_read(int minor) +{ + return sh4uart_poll_read(&sh4_uarts[minor]); +} + +/* console_interrupt_write -- + * wrapper for interrupt write function + * + * PARAMETERS: + * minor - minor device number + * buf - output buffer + * len - output buffer length + * + * RETURNS: + * result code + */ +static ssize_t +console_interrupt_write(int minor, const char *buf, size_t len) +{ + return sh4uart_interrupt_write(&sh4_uarts[minor], buf, len); +} + +/* console_poll_write -- + * wrapper for polling mode write function + * + * PARAMETERS: + * minor - minor device number + * buf - output buffer + * len - output buffer length + * + * RETURNS: + * result code + */ +static ssize_t +console_poll_write(int minor, const char *buf, size_t len) +{ + return sh4uart_poll_write(&sh4_uarts[minor], buf, len); +} + +/* console_set_attributes -- + * wrapper for hardware-dependent termios attributes setting + * + * PARAMETERS: + * minor - minor device number + * t - pointer to the termios structure + * + * RETURNS: + * result code + */ +static int +console_set_attributes(int minor, const struct termios *t) +{ + return sh4uart_set_attributes(&sh4_uarts[minor], t); +} + +/* console_stop_remote_tx -- + * wrapper for stopping data flow from remote party. + * + * PARAMETERS: + * minor - minor device number + * + * RETURNS: + * result code + */ +static int +console_stop_remote_tx(int minor) +{ + if (minor < sizeof(sh4_uarts)/sizeof(sh4_uarts[0])) + return sh4uart_stop_remote_tx(&sh4_uarts[minor]); + else + return RTEMS_INVALID_NUMBER; +} + +/* console_start_remote_tx -- + * wrapper for resuming data flow from remote party. + * + * PARAMETERS: + * minor - minor device number + * + */ +static int +console_start_remote_tx(int minor) +{ + if (minor < sizeof(sh4_uarts)/sizeof(sh4_uarts[0])) + return sh4uart_start_remote_tx(&sh4_uarts[minor]); + else + return RTEMS_INVALID_NUMBER; +} + +/* console_first_open -- + * wrapper for UART controller initialization functions + * + * PARAMETERS: + * major - major device number + * minor - minor device number + * arg - libio device open argument + * + * RETURNS: + * error code + */ +static int +console_first_open(int major, int minor, void *arg) +{ + rtems_libio_open_close_args_t *args = arg; + rtems_status_code sc; + + sc = sh4uart_init(&sh4_uarts[minor], /* uart */ + args->iop->data1, /* tty */ + minor+1, /* channel */ + (console_mode == CONSOLE_MODE_INT)); + + if (sc == RTEMS_SUCCESSFUL) + sc = sh4uart_reset(&sh4_uarts[minor]); + + return sc; +} + +/* console_last_close -- + * wrapper for UART controller close function + * + * PARAMETERS: + * major - major device number + * minor - minor device number + * arg - libio device close argument + * + * RETURNS: + * error code + */ +static int +console_last_close(int major, int minor, void *arg) +{ + if (console_mode != CONSOLE_MODE_IPL) + /* working from gdb we should not disable port operations */ + return sh4uart_disable(&sh4_uarts[minor], + !(boot_mode == SH4_BOOT_MODE_IPL)); + else + return RTEMS_SUCCESSFUL; +} + +/* console_initialize -- + * This routine initializes the console IO drivers and register devices + * in RTEMS I/O system. + * + * PARAMETERS: + * major - major console device number + * minor - minor console device number (not used) + * arg - device initialize argument + * + * RETURNS: + * RTEMS error code (RTEMS_SUCCESSFUL if device initialized successfuly) + */ +rtems_device_driver +console_initialize(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + rtems_status_code status; + +#ifdef SH4_WITH_IPL + /* booting from flash we cannot have IPL console */ + if (boot_mode != SH4_BOOT_MODE_IPL && console_mode == CONSOLE_MODE_IPL) + console_mode = CONSOLE_MODE_INT; + + /* break out from gdb if neccessary */ + if (boot_mode == SH4_BOOT_MODE_IPL && console_mode != CONSOLE_MODE_IPL) + ipl_finish(); +#endif + + /* + * Set up TERMIOS + */ + if ((console_mode != CONSOLE_MODE_RAW) && + (console_mode != CONSOLE_MODE_IPL)) + rtems_termios_initialize (); + + /* + * Register the devices + */ + status = rtems_io_register_name ("/dev/console", major, 0); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + + status = rtems_io_register_name ("/dev/aux", major, 1); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + + if (console_mode == CONSOLE_MODE_RAW) + { + rtems_status_code sc; + sc = sh4uart_init(&sh4_uarts[0], /* uart */ + NULL, /* tty */ + 1, /* UART channel number */ + 0); /* Poll-mode */ + + if (sc == RTEMS_SUCCESSFUL) + sc = sh4uart_reset(&sh4_uarts[0]); + + sc = sh4uart_init(&sh4_uarts[1], /* uart */ + NULL, /* tty */ + 2, /* UART channel number */ + 0); /* Poll-mode */ + + if (sc == RTEMS_SUCCESSFUL) + sc = sh4uart_reset(&sh4_uarts[1]); + + return sc; + } + + return RTEMS_SUCCESSFUL; +} + +/* console_open -- + * Open console device driver. Pass appropriate termios callback + * functions to termios library. + * + * PARAMETERS: + * major - major device number for console devices + * minor - minor device number for console + * arg - device opening argument + * + * RETURNS: + * RTEMS error code + */ +rtems_device_driver +console_open(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + static const rtems_termios_callbacks intr_callbacks = { + console_first_open, /* firstOpen */ + console_last_close, /* lastClose */ + NULL, /* pollRead */ + console_interrupt_write, /* write */ + console_set_attributes, /* setAttributes */ + console_stop_remote_tx, /* stopRemoteTx */ + console_start_remote_tx, /* startRemoteTx */ + 1 /* outputUsesInterrupts */ + }; + static const rtems_termios_callbacks poll_callbacks = { + console_first_open, /* firstOpen */ + console_last_close, /* lastClose */ + console_poll_read, /* pollRead */ + console_poll_write, /* write */ + console_set_attributes, /* setAttributes */ + console_stop_remote_tx, /* stopRemoteTx */ + console_start_remote_tx, /* startRemoteTx */ + 0 /* outputUsesInterrupts */ + }; + + switch (console_mode) + { + case CONSOLE_MODE_RAW: + case CONSOLE_MODE_IPL: + return RTEMS_SUCCESSFUL; + + case CONSOLE_MODE_INT: + return rtems_termios_open(major, minor, arg, &intr_callbacks); + + case CONSOLE_MODE_POLL: + return rtems_termios_open(major, minor, arg, &poll_callbacks); + + default: + rtems_fatal_error_occurred(0xC07A1310); + } + + return RTEMS_INTERNAL_ERROR; +} + +/* console_close -- + * Close console device. + * + * PARAMETERS: + * major - major device number for console devices + * minor - minor device number for console + * arg - device close argument + * + * RETURNS: + * RTEMS error code + */ +rtems_device_driver +console_close(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + if ((console_mode != CONSOLE_MODE_RAW) && + (console_mode != CONSOLE_MODE_IPL)) + return rtems_termios_close (arg); + else + return RTEMS_SUCCESSFUL; +} + +/* console_read -- + * Read from the console device + * + * PARAMETERS: + * major - major device number for console devices + * minor - minor device number for console + * arg - device read argument + * + * RETURNS: + * RTEMS error code + */ +rtems_device_driver +console_read(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + if ((console_mode != CONSOLE_MODE_RAW) && + (console_mode != CONSOLE_MODE_IPL)) + { + return rtems_termios_read (arg); + } + else + { + rtems_libio_rw_args_t *argp = arg; + char *buf = argp->buffer; + int count = argp->count; + int n = 0; + int c; + while (n < count) + { + do { + c = (console_mode == CONSOLE_MODE_RAW) ? + sh4uart_poll_read(&sh4_uarts[minor]) : + ipl_console_poll_read(minor); + } while (c == -1); + if (c == '\r') + c = '\n'; + *(buf++) = c; + n++; + if (c == '\n') + break; + } + argp->bytes_moved = n; + return RTEMS_SUCCESSFUL; + } +} + +/* console_write -- + * Write to the console device + * + * PARAMETERS: + * major - major device number for console devices + * minor - minor device number for console + * arg - device write argument + * + * RETURNS: + * RTEMS error code + */ +rtems_device_driver +console_write(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + switch (console_mode) + { + case CONSOLE_MODE_POLL: + case CONSOLE_MODE_INT: + return rtems_termios_write (arg); + case CONSOLE_MODE_RAW: + { + rtems_libio_rw_args_t *argp = arg; + char cr = '\r'; + char *buf = argp->buffer; + int count = argp->count; + int i; + + for (i = 0; i < count; i++) + { + if (*buf == '\n') + sh4uart_poll_write(&sh4_uarts[minor], &cr, 1); + sh4uart_poll_write(&sh4_uarts[minor], buf, 1); + buf++; + } + argp->bytes_moved = count; + return RTEMS_SUCCESSFUL; + } +#ifdef SH4_WITH_IPL + case CONSOLE_MODE_IPL: + { + rtems_libio_rw_args_t *argp = arg; + char *buf = argp->buffer; + int count = argp->count; + ipl_console_poll_write(minor, buf, count); + argp->bytes_moved = count; + return RTEMS_SUCCESSFUL; + } +#endif + default: /* Unreachable */ + return RTEMS_NOT_DEFINED; + } +} + +/* console_control -- + * Handle console device I/O control (IOCTL) + * + * PARAMETERS: + * major - major device number for console devices + * minor - minor device number for console + * arg - device ioctl argument + * + * RETURNS: + * RTEMS error code + */ +rtems_device_driver +console_control(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + if ((console_mode != CONSOLE_MODE_RAW) && + (console_mode != CONSOLE_MODE_IPL)) + { + return rtems_termios_ioctl (arg); + } + else + { + return RTEMS_SUCCESSFUL; + } +} diff --git a/bsps/sh/gensh4/console/sh4uart.c b/bsps/sh/gensh4/console/sh4uart.c new file mode 100644 index 0000000000..7acc1de337 --- /dev/null +++ b/bsps/sh/gensh4/console/sh4uart.c @@ -0,0 +1,910 @@ +/* + * Generic UART Serial driver for SH-4 processors + * + * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russian Fed. + * Author: Alexandra Kossovsky + * + * COPYRIGHT (c) 1989-2000. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + */ + +#include +#include +#include +#include +#include "sh/sh4uart.h" + +#ifndef SH4_UART_INTERRUPT_LEVEL +#define SH4_UART_INTERRUPT_LEVEL 4 +#endif + +/* Forward function declarations */ +static rtems_isr +sh4uart1_interrupt_transmit(rtems_vector_number vec); +static rtems_isr +sh4uart1_interrupt_receive(rtems_vector_number vec); +static rtems_isr +sh4uart2_interrupt_transmit(rtems_vector_number vec); +static rtems_isr +sh4uart2_interrupt_receive(rtems_vector_number vec); + +/* + * sh4uart_init -- + * This function verifies the input parameters and perform initialization + * of the SH-4 on-chip UART descriptor structure. + * + * PARAMETERS: + * uart - pointer to the UART channel descriptor structure + * tty - pointer to termios structure + * chn - channel number (SH4_SCI/SH4_SCIF -- 1/2) + * int_driven - interrupt-driven (1) or polled (0) I/O mode + * + * RETURNS: + * RTEMS_SUCCESSFUL if all parameters are valid, or error code + */ +rtems_status_code +sh4uart_init(sh4uart *uart, void *tty, int chn, int int_driven) +{ + if (uart == NULL) + return RTEMS_INVALID_ADDRESS; + + if ((chn != SH4_SCI) && (chn != SH4_SCIF)) + return RTEMS_INVALID_NUMBER; + + uart->chn = chn; + uart->tty = tty; + uart->int_driven = int_driven; + +#if 0 + sh4uart_poll_write(uart, "init", 4); +#endif + return RTEMS_SUCCESSFUL; +} + +/* + * sh4uart_get_Pph -- + * Get current peripheral module clock. + * + * PARAMETERS: none; + * Cpu clock is get from CPU_CLOCK_RATE_HZ marco + * (defined in bspopts.h, included from bsp.h) + * + * RETURNS: + * peripheral module clock in Hz. + */ +static uint32_t +sh4uart_get_Pph(void) +{ + uint16_t frqcr = *(volatile uint16_t*)SH7750_FRQCR; + uint32_t Pph = CPU_CLOCK_RATE_HZ; + + switch (frqcr & SH7750_FRQCR_IFC) { + case SH7750_FRQCR_IFCDIV1: break; + case SH7750_FRQCR_IFCDIV2: Pph *= 2; break; + case SH7750_FRQCR_IFCDIV3: Pph *= 3; break; + case SH7750_FRQCR_IFCDIV4: Pph *= 4; break; + case SH7750_FRQCR_IFCDIV6: Pph *= 6; break; + case SH7750_FRQCR_IFCDIV8: Pph *= 8; break; + default: /* unreachable */ + break; + } + + switch (frqcr & SH7750_FRQCR_PFC) { + case SH7750_FRQCR_PFCDIV2: Pph /= 2; break; + case SH7750_FRQCR_PFCDIV3: Pph /= 3; break; + case SH7750_FRQCR_PFCDIV4: Pph /= 4; break; + case SH7750_FRQCR_PFCDIV6: Pph /= 6; break; + case SH7750_FRQCR_PFCDIV8: Pph /= 8; break; + default: /* unreachable */ + break; + } + + return Pph; +} + +/* + * sh4uart_set_baudrate -- + * Program the UART timer to specified baudrate + * + * PARAMETERS: + * uart - pointer to UART descriptor structure + * baud - termios baud rate (B50, B9600, etc...) + * + * ALGORITHM: + * see SH7750 Hardware Manual. + * + * RETURNS: + * none + */ +static void +sh4uart_set_baudrate(sh4uart *uart, speed_t baud) +{ + uint32_t rate; + int16_t div; + int n; + uint32_t Pph = sh4uart_get_Pph(); + + switch (baud) { + case B50: rate = 50; break; + case B75: rate = 75; break; + case B110: rate = 110; break; + case B134: rate = 134; break; + case B150: rate = 150; break; + case B200: rate = 200; break; + case B300: rate = 300; break; + case B600: rate = 600; break; + case B1200: rate = 1200; break; + case B2400: rate = 2400; break; + case B4800: rate = 4800; break; + case B9600: rate = 9600; break; + case B19200: rate = 19200; break; + case B38400: rate = 38400; break; + case B57600: rate = 57600; break; +#ifdef B115200 + case B115200: rate = 115200; break; +#endif +#ifdef B230400 + case B230400: rate = 230400; break; +#endif + default: rate = 9600; break; + } + + for (n = 0; n < 4; n++) { + div = Pph / (32 * (1 << (2 * n)) * rate) - 1; + if (div < 0x100) + break; + } + + /* Set default baudrate if specified baudrate is impossible */ + if (n >= 4) + sh4uart_set_baudrate(uart, B9600); + + if ( uart->chn == 1 ) { + volatile uint8_t *smr1 = (volatile uint8_t *)SH7750_SCSMR1; + *smr1 &= ~SH7750_SCSMR_CKS; + *smr1 |= n << SH7750_SCSMR_CKS_S; + } else { + volatile uint16_t *smr2 = (volatile uint16_t *)SH7750_SCSMR2; + *smr2 &= ~SH7750_SCSMR_CKS; + *smr2 |= n << SH7750_SCSMR_CKS_S; + } + + SCBRR(uart->chn) = div; + /* Wait at least 1 bit interwal */ + rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(1000 / rate)); +} + +/* + * sh4uart_reset -- + * This function perform the hardware initialization of SH-4 + * on-chip UART controller using parameters + * filled by the sh4uart_init function. + * + * PARAMETERS: + * uart - pointer to UART channel descriptor structure + * + * RETURNS: + * RTEMS_SUCCESSFUL if channel is initialized successfully, error + * code in other case + */ +rtems_status_code +sh4uart_reset(sh4uart *uart) +{ + register int chn; + register int int_driven; + rtems_status_code rc; + uint16_t tmp; + + if (uart == NULL) + return RTEMS_INVALID_ADDRESS; + + chn = uart->chn; + int_driven = uart->int_driven; + + if ( chn == 1 ) { + volatile uint8_t *scr1 = (volatile uint8_t *)SH7750_SCSCR1; + volatile uint8_t *smr1 = (volatile uint8_t *)SH7750_SCSMR1; + *scr1 = 0x0; /* Is set properly at the end of this function */ + *smr1 = 0x0; /* 8-bit, non-parity, 1 stop bit, pf/1 clock */ + } else { + volatile uint16_t *scr2 = (volatile uint16_t *)SH7750_SCSCR2; + volatile uint16_t *smr2 = (volatile uint16_t *)SH7750_SCSMR2; + *scr2 = 0x0; /* Is set properly at the end of this function */ + *smr2 = 0x0; /* 8-bit, non-parity, 1 stop bit, pf/1 clock */ + } + + if (chn == SH4_SCIF) + SCFCR2 = SH7750_SCFCR2_TFRST | SH7750_SCFCR2_RFRST | + SH7750_SCFCR2_RTRG_1 | SH7750_SCFCR2_TTRG_4; + + if (chn == SH4_SCI) + SCSPTR1 = int_driven ? 0x0 : SH7750_SCSPTR1_EIO; + else + SCSPTR2 = SH7750_SCSPTR2_RTSDT; + + if (int_driven) { + uint16_t ipr; + + if (chn == SH4_SCI) { + ipr = IPRB; + ipr &= ~SH7750_IPRB_SCI1; + ipr |= SH4_UART_INTERRUPT_LEVEL << SH7750_IPRB_SCI1_S; + IPRB = ipr; + + rc = rtems_interrupt_catch(sh4uart1_interrupt_transmit, + SH7750_EVT_TO_NUM(SH7750_EVT_SCI_TXI), + &uart->old_handler_transmit); + if (rc != RTEMS_SUCCESSFUL) + return rc; + + rc = rtems_interrupt_catch(sh4uart1_interrupt_receive, + SH7750_EVT_TO_NUM(SH7750_EVT_SCI_RXI), + &uart->old_handler_receive); + if (rc != RTEMS_SUCCESSFUL) + return rc; + } else { + ipr = IPRC; + ipr &= ~SH7750_IPRC_SCIF; + ipr |= SH4_UART_INTERRUPT_LEVEL << SH7750_IPRC_SCIF_S; + IPRC = ipr; + + rc = rtems_interrupt_catch(sh4uart2_interrupt_transmit, + SH7750_EVT_TO_NUM(SH7750_EVT_SCIF_TXI), + &uart->old_handler_transmit); + if (rc != RTEMS_SUCCESSFUL) + return rc; + rc = rtems_interrupt_catch(sh4uart2_interrupt_receive, + SH7750_EVT_TO_NUM(SH7750_EVT_SCIF_RXI), + &uart->old_handler_receive); + if (rc != RTEMS_SUCCESSFUL) + return rc; + } + uart->tx_buf = NULL; + uart->tx_ptr = uart->tx_buf_len = 0; + } + + sh4uart_set_baudrate(uart, B38400); /* debug defaults (unfortunately, + it is differ to termios default */ + + tmp = SH7750_SCSCR_TE | SH7750_SCSCR_RE | + (chn == SH4_SCI ? 0x0 : SH7750_SCSCR2_REIE) | + (int_driven ? (SH7750_SCSCR_RIE | SH7750_SCSCR_TIE) : 0x0); + + if ( chn == 1 ) { + volatile uint8_t *scr = (volatile uint8_t *)SH7750_SCSCR1; + *scr = tmp; + } else { + volatile uint16_t *scr = (volatile uint16_t *)SH7750_SCSCR2; + *scr = tmp; + } + + return RTEMS_SUCCESSFUL; +} + +/* + * sh4uart_disable -- + * This function disable the operations on SH-4 UART controller + * + * PARAMETERS: + * uart - pointer to UART channel descriptor structure + * disable_port - disable receive and transmit on the port + * + * RETURNS: + * RTEMS_SUCCESSFUL if UART closed successfuly, or error code in + * other case + */ +rtems_status_code +sh4uart_disable(sh4uart *uart, int disable_port) +{ + rtems_status_code rc; + + if (disable_port) { + if ( uart->chn == 1 ) { + volatile uint8_t *scr = (volatile uint8_t *)SH7750_SCSCR1; + *scr &= ~(SH7750_SCSCR_TE | SH7750_SCSCR_RE); + } else { + volatile uint16_t *scr = (volatile uint16_t *)SH7750_SCSCR2; + *scr &= ~(SH7750_SCSCR_TE | SH7750_SCSCR_RE); + } + } + + if (uart->int_driven) { + rc = rtems_interrupt_catch(uart->old_handler_transmit, + uart->chn == SH4_SCI ? SH7750_EVT_SCI_TXI : SH7750_EVT_SCIF_TXI, + NULL); + if (rc != RTEMS_SUCCESSFUL) + return rc; + rc = rtems_interrupt_catch(uart->old_handler_receive, + uart->chn == SH4_SCI ? SH7750_EVT_SCI_RXI : SH7750_EVT_SCIF_RXI, + NULL); + if (rc != RTEMS_SUCCESSFUL) + return rc; + } + + return RTEMS_SUCCESSFUL; +} + +/* + * sh4uart_set_attributes -- + * This function parse the termios attributes structure and perform + * the appropriate settings in hardware. + * + * PARAMETERS: + * uart - pointer to the UART descriptor structure + * t - pointer to termios parameters + * + * RETURNS: + * RTEMS_SUCCESSFUL + */ +rtems_status_code +sh4uart_set_attributes(sh4uart *uart, const struct termios *t) +{ + int level; + speed_t baud; + uint16_t smr; + + smr = (uint16_t)(*(uint8_t*)SH7750_SCSMR(uart->chn)); + + baud = cfgetospeed(t); + + /* Set flow control XXX*/ + if ((t->c_cflag & CRTSCTS) != 0) { + } + + /* Set character size -- only 7 or 8 bit */ + switch (t->c_cflag & CSIZE) { + case CS5: + case CS6: + case CS7: smr |= SH7750_SCSMR_CHR_7; break; + case CS8: smr &= ~SH7750_SCSMR_CHR_7; break; + } + + /* Set number of stop bits */ + if ((t->c_cflag & CSTOPB) != 0) + smr |= SH7750_SCSMR_STOP_2; + else + smr &= ~SH7750_SCSMR_STOP_2; + + /* Set parity mode */ + if ((t->c_cflag & PARENB) != 0) { + smr |= SH7750_SCSMR_PE; + if ((t->c_cflag & PARODD) != 0) + smr |= SH7750_SCSMR_PM_ODD; + else + smr &= ~SH7750_SCSMR_PM_ODD; + } else + smr &= ~SH7750_SCSMR_PE; + + rtems_interrupt_disable(level); + /* wait untill all data is transmitted */ + /* XXX JOEL says this is broken -- interrupts are OFF so NO ticks */ + rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(100)); + + if ( uart->chn == 1 ) { + volatile uint8_t *scrP = (volatile uint8_t *)SH7750_SCSCR1; + volatile uint8_t *smrP = (volatile uint8_t *)SH7750_SCSMR1; + + *scrP &= ~(SH7750_SCSCR_TE | SH7750_SCSCR_RE); /* disable operations */ + sh4uart_set_baudrate(uart, baud); + *smrP = (uint8_t)smr; + *scrP |= SH7750_SCSCR_TE | SH7750_SCSCR_RE; /* enable operations */ + } else { + volatile uint16_t *scrP = (volatile uint16_t *)SH7750_SCSCR2; + volatile uint16_t *smrP = (volatile uint16_t *)SH7750_SCSMR2; + + *scrP &= ~(SH7750_SCSCR_TE | SH7750_SCSCR_RE); /* disable operations */ + sh4uart_set_baudrate(uart, baud); + *smrP = (uint8_t)smr; + *scrP |= SH7750_SCSCR_TE | SH7750_SCSCR_RE; /* enable operations */ + } + + rtems_interrupt_enable(level); + + return RTEMS_SUCCESSFUL; +} + +/* + * sh4uart_handle_error -- + * Perfoms error (Overrun, Framing & Parity) handling + * + * PARAMETERS: + * uart - pointer to UART descriptor structure + * + * RETURNS: + * nothing + */ +static void +sh4uart_handle_error(sh4uart *uart) +{ + if (uart->chn == SH4_SCI) { + volatile uint8_t *scr = (volatile uint8_t *)SH7750_SCSCR1; + *scr &= ~(SH7750_SCSSR1_ORER | SH7750_SCSSR1_FER | SH7750_SCSSR1_PER); + } else { + volatile uint16_t *scr = (volatile uint16_t *)SH7750_SCSCR2; + *scr &= ~(SH7750_SCSSR2_ER | SH7750_SCSSR2_BRK | SH7750_SCSSR2_FER); + *scr &= ~(SH7750_SCLSR2_ORER); + } +} + +/* + * sh4uart_poll_read -- + * This function tried to read character from SH-4 UART and perform + * error handling. When parity or framing error occured, return + * value dependent on termios input mode flags: + * - received character, if IGNPAR == 1 + * - 0, if IGNPAR == 0 and PARMRK == 0 + * - 0xff and 0x00 on next poll_read invocation, if IGNPAR == 0 and + * PARMRK == 1 + * + * PARAMETERS: + * uart - pointer to UART descriptor structure + * + * RETURNS: + * code of received character or -1 if no characters received. + */ +int +sh4uart_poll_read(sh4uart *uart) +{ + int chn = uart->chn; + int parity_error = 0; + int break_occured = 0; + int ch; + + if (uart->parerr_mark_flag == true) { + uart->parerr_mark_flag = false; + return 0; + } + + if (chn == SH4_SCI) { + if ((SCSSR1 & (SH7750_SCSSR1_PER | SH7750_SCSSR1_FER | + SH7750_SCSSR1_ORER)) != 0) { + if (SCSSR1 & (SH7750_SCSSR1_PER | SH7750_SCSSR1_FER)) + parity_error = 1; + sh4uart_handle_error(uart); + } + if ((SCSSR1 & SH7750_SCSSR1_RDRF) == 0) + return -1; + } else { + if ((SCSSR2 & (SH7750_SCSSR2_ER | SH7750_SCSSR2_DR | + SH7750_SCSSR2_BRK)) != 0 || + (SCLSR2 & SH7750_SCLSR2_ORER) != 0) { + if (SCSSR2 & (SH7750_SCSSR1_PER | SH7750_SCSSR1_FER)) + parity_error = 1; + if (SCSSR2 & SH7750_SCSSR2_BRK) + break_occured = 1; + sh4uart_handle_error(uart); + } + if ((SCSSR2 & SH7750_SCSSR2_RDF) == 0) + return -1; + } + + if (parity_error && !(uart->c_iflag & IGNPAR)) { + if (uart->c_iflag & PARMRK) { + uart->parerr_mark_flag = true; + return 0xff; + } else + return 0; + } + + if (break_occured && !(uart->c_iflag & BRKINT)) { + if (uart->c_iflag & IGNBRK) + return 0; + else + return 0; /* XXX -- SIGINT */ + } + + ch = SCRDR(chn); + + if (uart->chn == SH4_SCI) { + volatile uint8_t *scr = (volatile uint8_t *)SH7750_SCSCR1; + *scr &= ~SH7750_SCSSR1_RDRF; + } else { + volatile uint16_t *scr = (volatile uint16_t *)SH7750_SCSCR2; + *scr &= ~SH7750_SCSSR2_RDF; + } + + return ch; +} + +/* + * sh4uart_poll_write -- + * This function transmit buffer byte-by-byte in polling mode. + * + * PARAMETERS: + * uart - pointer to the UART descriptor structure + * buf - pointer to transmit buffer + * len - transmit buffer length + * + * RETURNS: + * 0 + */ +int +sh4uart_poll_write(sh4uart *uart, const char *buf, int len) +{ + volatile uint8_t *ssr1 = (volatile uint8_t *)SH7750_SCSSR1; + volatile uint16_t *ssr2 = (volatile uint16_t *)SH7750_SCSSR2; + + while (len) { + if (uart->chn == SH4_SCI) { + while ((SCSSR1 & SH7750_SCSSR1_TDRE) != 0) { + SCTDR1 = *buf++; + len--; + *ssr1 &= ~SH7750_SCSSR1_TDRE; + } + } else { + while ((SCSSR2 & SH7750_SCSSR2_TDFE) != 0) { + int i; + for (i = 0; + i < 16 - TRANSMIT_TRIGGER_VALUE(SCFCR2 & + SH7750_SCFCR2_TTRG); + i++) { + SCTDR2 = *buf++; + len--; + } + while ((SCSSR2 & SH7750_SCSSR2_TDFE) == 0 || + (SCSSR2 & SH7750_SCSSR2_TEND) == 0); + *ssr2 &= ~(SH7750_SCSSR1_TDRE | SH7750_SCSSR2_TEND); + } + } + } + return 0; +} + +/********************************** + * Functions to handle interrupts * + **********************************/ +/* sh4uart1_interrupt_receive -- + * UART interrupt handler routine -- SCI + * Receiving data + * + * PARAMETERS: + * vec - interrupt vector number + * + * RETURNS: + * none + */ +static rtems_isr +sh4uart1_interrupt_receive(rtems_vector_number vec) +{ + register int bp = 0; + char buf[32]; + volatile uint8_t *ssr1 = (volatile uint8_t *)SH7750_SCSSR1; + + + /* Find UART descriptor from vector number */ + sh4uart *uart = &sh4_uarts[0]; + + while (1) { + if ((bp < sizeof(buf) - 1) && ((SCSSR1 & SH7750_SCSSR1_RDRF) != 0)) { + /* Receive character and handle frame/parity errors */ + if ((SCSSR1 & (SH7750_SCSSR1_PER | SH7750_SCSSR1_FER | + SH7750_SCSSR1_ORER)) != 0) { + if (SCSSR1 & (SH7750_SCSSR1_PER | SH7750_SCSSR1_FER)) { + if (!(uart->c_iflag & IGNPAR)) { + if (uart->c_iflag & PARMRK) { + buf[bp++] = 0xff; + buf[bp++] = 0x00; + } else + buf[bp++] = 0x00; + } else + buf[bp++] = SCRDR1; + } + sh4uart_handle_error(uart); + } else + buf[bp++] = SCRDR1; + *ssr1 &= ~SH7750_SCSSR1_RDRF; + } else { + if (bp != 0) + rtems_termios_enqueue_raw_characters(uart->tty, buf, bp); + break; + } + } +} + +/* sh4uart2_interrupt_receive -- + * UART interrupt handler routine -- SCIF + * Receiving data + * + * PARAMETERS: + * vec - interrupt vector number + * + * RETURNS: + * none + */ +static rtems_isr +sh4uart2_interrupt_receive(rtems_vector_number vec) +{ + register int bp = 0; + char buf[32]; + volatile uint16_t *ssr2 = (volatile uint16_t *)SH7750_SCSSR2; + + + /* Find UART descriptor from vector number */ + sh4uart *uart = &sh4_uarts[1]; + + while (1) { + if ((bp < sizeof(buf) - 1) && ((SCSSR2 & SH7750_SCSSR2_RDF) != 0)) { + if ((SCSSR2 & (SH7750_SCSSR2_ER | SH7750_SCSSR2_DR | + SH7750_SCSSR2_BRK)) != 0 || + (SH7750_SCLSR2 & SH7750_SCLSR2_ORER) != 0) { + if (SCSSR2 & SH7750_SCSSR2_ER) { + if (!(uart->c_iflag & IGNPAR)) { + if (uart->c_iflag & PARMRK) { + buf[bp++] = 0xff; + buf[bp++] = 0x00; + } else + buf[bp++] = 0x00; + } else + buf[bp++] = SCRDR1; + } + + if (SCSSR2 & SH7750_SCSSR2_BRK) { + if (uart->c_iflag & IGNBRK) + buf[bp++] = 0x00; + else + buf[bp++] = 0x00; /* XXX -- SIGINT */ + } + + sh4uart_handle_error(uart); + } else + buf[bp++] = SCRDR1; + *ssr2 &= ~SH7750_SCSSR2_RDF; + } else { + if (bp != 0) + rtems_termios_enqueue_raw_characters(uart->tty, buf, bp); + break; + } + } +} + + +/* sh4uart1_interrupt_transmit -- + * UART interrupt handler routine -- SCI + * It continues transmit data when old part of data is transmitted + * + * PARAMETERS: + * vec - interrupt vector number + * + * RETURNS: + * none + */ +static rtems_isr +sh4uart1_interrupt_transmit(rtems_vector_number vec) +{ + volatile uint8_t *scr1 = (volatile uint8_t *)SH7750_SCSCR1; + volatile uint8_t *ssr1 = (volatile uint8_t *)SH7750_SCSSR1; + + /* Find UART descriptor from vector number */ + sh4uart *uart = &sh4_uarts[0]; + + if (uart->tx_buf != NULL && uart->tx_ptr < uart->tx_buf_len) { + while ((SCSSR1 & SH7750_SCSSR1_TDRE) != 0 && + uart->tx_ptr < uart->tx_buf_len) { + SCTDR1 = uart->tx_buf[uart->tx_ptr++]; + *ssr1 &= ~SH7750_SCSSR1_TDRE; + } + } else { + register int dequeue = uart->tx_buf_len; + + uart->tx_buf = NULL; + uart->tx_ptr = uart->tx_buf_len = 0; + + /* Disable interrupts while we do not have any data to transmit */ + *scr1 &= ~SH7750_SCSCR_TIE; + + rtems_termios_dequeue_characters(uart->tty, dequeue); + } +} + +/* sh4uart2_interrupt_transmit -- + * UART interrupt handler routine -- SCI + * It continues transmit data when old part of data is transmitted + * + * PARAMETERS: + * vec - interrupt vector number + * + * RETURNS: + * none + */ +static rtems_isr +sh4uart2_interrupt_transmit(rtems_vector_number vec) +{ + volatile uint8_t *ssr1 = (volatile uint8_t *)SH7750_SCSSR1; + volatile uint16_t *scr2 = (volatile uint16_t *)SH7750_SCSCR2; + + /* Find UART descriptor from vector number */ + sh4uart *uart = &sh4_uarts[1]; + + if (uart->tx_buf != NULL && uart->tx_ptr < uart->tx_buf_len) { + while ((SCSSR2 & SH7750_SCSSR2_TDFE) != 0) { + int i; + for (i = 0; + i < 16 - TRANSMIT_TRIGGER_VALUE(SCFCR2 & SH7750_SCFCR2_TTRG); + i++) + SCTDR2 = uart->tx_buf[uart->tx_ptr++]; + while ((SCSSR1 & SH7750_SCSSR1_TDRE) == 0 || + (SCSSR1 & SH7750_SCSSR1_TEND) == 0); + *ssr1 &= ~(SH7750_SCSSR1_TDRE | SH7750_SCSSR2_TEND); + } + } else { + register int dequeue = uart->tx_buf_len; + + uart->tx_buf = NULL; + uart->tx_ptr = uart->tx_buf_len = 0; + + /* Disable interrupts while we do not have any data to transmit */ + *scr2 &= ~SH7750_SCSCR_TIE; + + rtems_termios_dequeue_characters(uart->tty, dequeue); + } +} + +/* sh4uart_interrupt_write -- + * This function initiate transmitting of the buffer in interrupt mode. + * + * PARAMETERS: + * uart - pointer to the UART descriptor structure + * buf - pointer to transmit buffer + * len - transmit buffer length + * + * RETURNS: + * 0 + */ +rtems_status_code +sh4uart_interrupt_write(sh4uart *uart, const char *buf, int len) +{ + if (len > 0) { + volatile uint8_t *scr1 = (volatile uint8_t *)SH7750_SCSCR1; + volatile uint16_t *scr2 = (volatile uint16_t *)SH7750_SCSCR2; + + while ((SCSSR1 & SH7750_SCSSR1_TEND) == 0); + + uart->tx_buf = buf; + uart->tx_buf_len = len; + uart->tx_ptr = 0; + + if (uart->chn == SH4_SCI) + *scr1 |= SH7750_SCSCR_TIE; + else + *scr2 |= SH7750_SCSCR_TIE; + } + + return RTEMS_SUCCESSFUL; +} + +/* sh4uart_stop_remote_tx -- + * This function stop data flow from remote device. + * + * PARAMETERS: + * uart - pointer to the UART descriptor structure + * + * RETURNS: + * RTEMS_SUCCESSFUL + */ +rtems_status_code +sh4uart_stop_remote_tx(sh4uart *uart) +{ + if ( uart->chn == 1 ) { + volatile uint8_t *scr = (volatile uint8_t *)SH7750_SCSCR1; + *scr &= ~(SH7750_SCSCR_RIE | SH7750_SCSCR_RE); + } else { + volatile uint16_t *scr = (volatile uint16_t *)SH7750_SCSCR2; + *scr &= ~(SH7750_SCSCR_RIE | SH7750_SCSCR_RE); + } + + return RTEMS_SUCCESSFUL; +} + +/* sh4uart_start_remote_tx -- + * This function resume data flow from remote device. + * + * PARAMETERS: + * uart - pointer to the UART descriptor structure + * + * RETURNS: + * RTEMS_SUCCESSFUL + */ +rtems_status_code +sh4uart_start_remote_tx(sh4uart *uart) +{ + if ( uart->chn == 1 ) { + volatile uint8_t *scr = (volatile uint8_t *)SH7750_SCSCR1; + *scr |= SH7750_SCSCR_RIE | SH7750_SCSCR_RE; + } else { + volatile uint16_t *scr = (volatile uint16_t *)SH7750_SCSCR2; + *scr |= SH7750_SCSCR_RIE | SH7750_SCSCR_RE; + } + + return RTEMS_SUCCESSFUL; +} + +#ifdef SH4_WITH_IPL +/********************************* + * Functions for SH-IPL gdb stub * + *********************************/ + +/* + * ipl_finish -- + * Says gdb that program finished to get out from it. + */ +extern void ipl_finish(void); +__asm__ ( +" .global _ipl_finish\n" +"_ipl_finish:\n" +" mov.l __ipl_finish_value, r0\n" +" trapa #0x3f\n" +" nop\n" +" rts\n" +" nop\n" +" .align 4\n" +"__ipl_finish_value:\n" +" .long 255" +); + +extern int ipl_serial_input(int poll_count); +__asm__ ( +" .global _ipl_serial_input\n" +"_ipl_serial_input:\n" +" mov #1,r0\n" +" trapa #0x3f\n" +" nop\n" +" rts\n" +" nop\n"); + +extern void ipl_serial_output(const char *buf, int len); +__asm__ ( +" .global _ipl_serial_output\n" +"_ipl_serial_output:\n" +" mov #0,r0\n" +" trapa #0x3f\n" +" nop\n" +" rts\n" +" nop\n"); + +/* ipl_console_poll_read -- + * poll read operation for simulator console through ipl mechanism. + * + * PARAMETERS: + * minor - minor device number + * + * RETURNS: + * character code red from UART, or -1 if there is no characters + * available + */ +int +ipl_console_poll_read(int minor) +{ + unsigned char buf; + buf = ipl_serial_input(0x100000); + return buf; +} + +/* ipl_console_poll_write -- + * wrapper for polling mode write function + * + * PARAMETERS: + * minor - minor device number + * buf - output buffer + * len - output buffer length + * + * RETURNS: + * result code (0) + */ +int +ipl_console_poll_write(int minor, const char *buf, int len) +{ + int c; + while (len > 0) { + c = (len < 64 ? len : 64); + ipl_serial_output(buf, c); + len -= c; + buf += c; + } + return 0; +} +#endif diff --git a/bsps/sh/shsim/console/console-debugio.c b/bsps/sh/shsim/console/console-debugio.c new file mode 100644 index 0000000000..0a81dbe45b --- /dev/null +++ b/bsps/sh/shsim/console/console-debugio.c @@ -0,0 +1,33 @@ +/** + * @file + * @brief Stub printk() support + */ + +/* + * COPYRIGHT (c) 1989-2014. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +/* + * To support printk + */ + +#include +#include + +void console_outbyte_polled( + int port, + char ch +); + +static void BSP_output_char_f(char c) +{ + console_outbyte_polled( 0, c ); +} + +BSP_output_char_function_type BSP_output_char = BSP_output_char_f; +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/sh/shsim/console/console-io.c b/bsps/sh/shsim/console/console-io.c new file mode 100644 index 0000000000..71b089fdf7 --- /dev/null +++ b/bsps/sh/shsim/console/console-io.c @@ -0,0 +1,57 @@ +/* + * This file contains the hardware specific portions of the TTY driver + * for the simulators stdin/out. + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include + +#include + +/* + * console_initialize_hardware + * + * This routine initializes the console hardware. + */ +void console_initialize_hardware(void) +{ +} + +/* + * console_outbyte_polled + * + * This routine transmits a character using polling. + */ +void console_outbyte_polled( + int port, + char ch +) +{ + __trap34 (SYS_write, 1, &ch, 1); +} + +/* + * console_inbyte_nonblocking + * + * This routine polls for a character. + */ +int console_inbyte_nonblocking( + int port +) +{ + unsigned char c; + + return __trap34 (SYS_read, 0, &c, 1); +} diff --git a/bsps/sh/shsim/console/console-support.S b/bsps/sh/shsim/console/console-support.S new file mode 100644 index 0000000000..63f72f794b --- /dev/null +++ b/bsps/sh/shsim/console/console-support.S @@ -0,0 +1,18 @@ +/* + * newlib-1.8.2/newlib/libc/sys/sh/trap.S + */ + .text + .global ___trap34 +___trap34: + trapa #34 + tst r1,r1 ! r1 is errno + bt ret + mov.l perrno,r2 + mov.l r1,@r2 +ret: + rts + nop + + .align 2 +perrno: + .long _errno diff --git a/bsps/shared/dev/serial/console-output-char.c b/bsps/shared/dev/serial/console-output-char.c new file mode 100644 index 0000000000..fec204663a --- /dev/null +++ b/bsps/shared/dev/serial/console-output-char.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include + +static void output_char(char c) +{ + int minor = (int) Console_Port_Minor; + const console_tbl *ct = Console_Port_Tbl != NULL ? + Console_Port_Tbl[minor] : &Console_Configuration_Ports[minor]; + const console_fns *cf = ct->pDeviceFns; + + (*cf->deviceWritePolled)(minor, c); +} + +static void output_char_init(char c) +{ + if (Console_Port_Tbl == NULL) { + int minor = (int) Console_Port_Minor; + const console_fns *cf = Console_Configuration_Ports[minor].pDeviceFns; + + (*cf->deviceInitialize)(minor); + } + + BSP_output_char = output_char; + output_char(c); +} + +BSP_output_char_function_type BSP_output_char = output_char_init; + +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/shared/dev/serial/console-polled.c b/bsps/shared/dev/serial/console-polled.c new file mode 100644 index 0000000000..26c9817bdb --- /dev/null +++ b/bsps/shared/dev/serial/console-polled.c @@ -0,0 +1,143 @@ +/* + * This file contains the hardware independent portion of a polled + * console device driver. If a BSP chooses to use this, then it + * only has to provide a few board dependent routines. + */ + +/* + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include + +#include +#include +#include + +/* + * Prototypes + */ +ssize_t console_write_support(int, const char *, size_t); + +/* + * Console Termios Support Entry Points + * + */ +ssize_t console_write_support ( + int minor, + const char *bufarg, + size_t len +) +{ + int nwrite = 0; + const char *buf = bufarg; + + while (nwrite < len) { + console_outbyte_polled( minor, *buf++ ); + nwrite++; + } + return nwrite; +} + +/* + * Console Device Driver Entry Points + * + */ + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + + /* + * Ensure Termios is initialized + */ + rtems_termios_initialize(); + + /* + * Make sure the hardware is initialized. + */ + console_initialize_hardware(); + + /* + * Register Device Names + */ + status = rtems_io_register_name( "/dev/console", major, 0 ); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(BSP_FATAL_CONSOLE_REGISTER_DEV_2); + + return RTEMS_SUCCESSFUL; +} + +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + static const rtems_termios_callbacks pollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + console_inbyte_nonblocking, /* pollRead */ + console_write_support, /* write */ + NULL, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + 0 /* outputUsesInterrupts */ + }; + + assert( minor == 0 ); + if ( minor != 0 ) + return RTEMS_INVALID_NUMBER; + + rtems_termios_open( major, minor, arg, &pollCallbacks ); + + return RTEMS_SUCCESSFUL; +} + +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_close( arg ); +} + +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_read( arg ); +} + +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_write( arg ); +} + +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_ioctl( arg ); +} diff --git a/bsps/shared/dev/serial/console-termios-init.c b/bsps/shared/dev/serial/console-termios-init.c new file mode 100644 index 0000000000..a01a75abf2 --- /dev/null +++ b/bsps/shared/dev/serial/console-termios-init.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2014, 2016 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include + +#include + +#include + +bool console_device_probe_default(rtems_termios_device_context *context) +{ + (void) context; + + return true; +} + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + bool console_device_done = false; + + rtems_termios_initialize(); + + for ( minor = 0; minor < console_device_count; ++minor ) { + const console_device *ctx = &console_device_table[ minor ]; + rtems_status_code sc; + + if ( ( *ctx->probe )( ctx->context ) ) { + sc = rtems_termios_device_install( + ctx->device_file, + ctx->handler, + ctx->flow, + ctx->context + ); + if ( sc != RTEMS_SUCCESSFUL ) { + bsp_fatal( BSP_FATAL_CONSOLE_INSTALL_0 ); + } + + if ( !console_device_done ) { + console_device_done = true; + + if ( link( ctx->device_file, CONSOLE_DEVICE_NAME ) != 0 ) { + bsp_fatal( BSP_FATAL_CONSOLE_INSTALL_1 ); + } + } + } + } + + return RTEMS_SUCCESSFUL; +} diff --git a/bsps/shared/dev/serial/console-termios.c b/bsps/shared/dev/serial/console-termios.c new file mode 100644 index 0000000000..1e755d91c9 --- /dev/null +++ b/bsps/shared/dev/serial/console-termios.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2014, 2016 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include + +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + (void) major; + (void) minor; + (void) arg; + + return RTEMS_INTERNAL_ERROR; +} + +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + (void) major; + (void) minor; + (void) arg; + + return RTEMS_INTERNAL_ERROR; +} + +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + (void) major; + (void) minor; + (void) arg; + + return RTEMS_INTERNAL_ERROR; +} + +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + (void) major; + (void) minor; + (void) arg; + + return RTEMS_INTERNAL_ERROR; +} + +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + (void) major; + (void) minor; + (void) arg; + + return RTEMS_INTERNAL_ERROR; +} diff --git a/bsps/shared/dev/serial/getserialmouseps2.c b/bsps/shared/dev/serial/getserialmouseps2.c new file mode 100644 index 0000000000..dc30deecbf --- /dev/null +++ b/bsps/shared/dev/serial/getserialmouseps2.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +bool bsp_get_serial_mouse_device( + const char **name, + const char **type +) +{ + *name = SERIAL_MOUSE_DEVICE_PS2; + *type = "ps2"; + + return true; +} diff --git a/bsps/shared/dev/serial/printk-dummy.c b/bsps/shared/dev/serial/printk-dummy.c new file mode 100644 index 0000000000..8273edb83a --- /dev/null +++ b/bsps/shared/dev/serial/printk-dummy.c @@ -0,0 +1,31 @@ +/** + * @file + * @brief Stub printk() support + * + * This file contains a stub for the required printk() support. + * It is NOT functional!!! + */ + +/* + * COPYRIGHT (c) 1989-2014. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +/* + * To support printk + */ + +#include +#include + +static void BSP_output_char_f(char c) +{ + /* the character just needs to disappear */ +} + +BSP_output_char_function_type BSP_output_char = BSP_output_char_f; +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/sparc/erc32/console/debugputs.c b/bsps/sparc/erc32/console/debugputs.c new file mode 100644 index 0000000000..57c00048a5 --- /dev/null +++ b/bsps/sparc/erc32/console/debugputs.c @@ -0,0 +1,83 @@ +/* + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include + +/* + * console_outbyte_polled + * + * This routine transmits a character using polling. + */ +void console_outbyte_polled( + int port, + unsigned char ch +) +{ + if ( port == 0 ) { + while ( (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEA) == 0 ); + ERC32_MEC.UART_Channel_A = (unsigned int) ch; + return; + } + + while ( (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEB) == 0 ); + ERC32_MEC.UART_Channel_B = (unsigned int) ch; +} + +/* + * console_inbyte_nonblocking + * + * This routine polls for a character. + */ +int console_inbyte_nonblocking( int port ) +{ + int UStat; + + UStat = ERC32_MEC.UART_Status; + + switch (port) { + + case 0: + if (UStat & ERC32_MEC_UART_STATUS_ERRA) { + ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRA; + ERC32_MEC.Control = ERC32_MEC.Control; + } + + if ((UStat & ERC32_MEC_UART_STATUS_DRA) == 0) + return -1; + return (int) ERC32_MEC.UART_Channel_A; + + case 1: + if (UStat & ERC32_MEC_UART_STATUS_ERRB) { + ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRB; + ERC32_MEC.Control = ERC32_MEC.Control; + } + + if ((UStat & ERC32_MEC_UART_STATUS_DRB) == 0) + return -1; + return (int) ERC32_MEC.UART_Channel_B; + + default: + rtems_fatal_error_occurred( 'D' << 8 | (port & 0xffffff) ); + } + + return -1; +} + +/* + * To support printk + */ + +#include + +static void BSP_output_char_f(char c) { console_outbyte_polled( 0, c ); } + +BSP_output_char_function_type BSP_output_char = BSP_output_char_f; +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/bsps/sparc/erc32/console/erc32_console.c b/bsps/sparc/erc32/console/erc32_console.c new file mode 100644 index 0000000000..81dfe026fb --- /dev/null +++ b/bsps/sparc/erc32/console/erc32_console.c @@ -0,0 +1,337 @@ +/** + * @file + * + * @brief Driver for serial ports on the ERC32. + */ + +/* + * Copyright (c) 2010 Tiemen Schut + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#define CONSOLE_BUF_SIZE (16) + +#define CONSOLE_UART_A_TRAP ERC32_TRAP_TYPE(ERC32_INTERRUPT_UART_A_RX_TX) +#define CONSOLE_UART_B_TRAP ERC32_TRAP_TYPE(ERC32_INTERRUPT_UART_B_RX_TX) + +static uint8_t erc32_console_get_register(uintptr_t addr, uint8_t i) +{ + volatile uint32_t *reg = (volatile uint32_t *)addr; + return (uint8_t) reg [i]; +} + +static void erc32_console_set_register(uintptr_t addr, uint8_t i, uint8_t val) +{ + volatile uint32_t *reg = (volatile uint32_t *)addr; + reg [i] = val; +} + +static int erc32_console_first_open(int major, int minor, void *arg); + +#if (CONSOLE_USE_INTERRUPTS) + static ssize_t erc32_console_write_support_int( + int minor, const char *buf, size_t len); +#else + int console_inbyte_nonblocking( int port ); + static ssize_t erc32_console_write_support_polled( + int minor, const char *buf, size_t len); +#endif +static void erc32_console_initialize(int minor); + +#if (CONSOLE_USE_INTERRUPTS) + const console_fns erc32_fns = { + libchip_serial_default_probe, /* deviceProbe */ + erc32_console_first_open, /* deviceFirstOpen */ + NULL, /* deviceLastClose */ + NULL, /* deviceRead */ + erc32_console_write_support_int, /* deviceWrite */ + erc32_console_initialize, /* deviceInitialize */ + NULL, /* deviceWritePolled */ + NULL, /* deviceSetAttributes */ + TERMIOS_IRQ_DRIVEN /* deviceOutputUsesInterrupts */ + }; +#else + const console_fns erc32_fns = { + libchip_serial_default_probe, /* deviceProbe */ + erc32_console_first_open, /* deviceFirstOpen */ + NULL, /* deviceLastClose */ + console_inbyte_nonblocking, /* deviceRead */ + erc32_console_write_support_polled, /* deviceWrite */ + erc32_console_initialize, /* deviceInitialize */ + NULL, /* deviceWritePolled */ + NULL, /* deviceSetAttributes */ + TERMIOS_POLLED /* deviceOutputUsesInterrupts */ + }; +#endif + +console_tbl Console_Configuration_Ports [] = { + { + .sDeviceName = "/dev/console_a", + .deviceType = SERIAL_CUSTOM, + .pDeviceFns = &erc32_fns, + .deviceProbe = NULL, + .pDeviceFlow = NULL, + .ulMargin = 16, + .ulHysteresis = 8, + .pDeviceParams = (void *) -1, /* could be baud rate */ + .ulCtrlPort1 = 0, + .ulCtrlPort2 = 0, + .ulDataPort = 0, + .getRegister = erc32_console_get_register, + .setRegister = erc32_console_set_register, + .getData = NULL, + .setData = NULL, + .ulClock = 16, + .ulIntVector = ERC32_INTERRUPT_UART_A_RX_TX + }, + { + .sDeviceName = "/dev/console_b", + .deviceType = SERIAL_CUSTOM, + .pDeviceFns = &erc32_fns, + .deviceProbe = NULL, + .pDeviceFlow = NULL, + .ulMargin = 16, + .ulHysteresis = 8, + .pDeviceParams = (void *) -1, /* could be baud rate */ + .ulCtrlPort1 = 0, + .ulCtrlPort2 = 0, + .ulDataPort = 0, + .getRegister = erc32_console_get_register, + .setRegister = erc32_console_set_register, + .getData = NULL, + .setData = NULL, + .ulClock = 16, + .ulIntVector = ERC32_INTERRUPT_UART_B_RX_TX + }, +}; + +/* always exactly two uarts for erc32 */ +#define ERC32_UART_COUNT (2) + +unsigned long Console_Configuration_Count = ERC32_UART_COUNT; + +static int erc32_console_first_open(int major, int minor, void *arg) +{ + /* Check minor number */ + if (minor < 0 || minor > 1) { + return -1; + } + + rtems_libio_open_close_args_t *oca = arg; + struct rtems_termios_tty *tty = oca->iop->data1; + console_tbl *ct = Console_Port_Tbl [minor]; + console_data *cd = &Console_Port_Data [minor]; + + cd->termios_data = tty; + rtems_termios_set_initial_baud(tty, (int32_t)ct->pDeviceParams); + + return 0; +} + +#if (CONSOLE_USE_INTERRUPTS) +static ssize_t erc32_console_write_support_int( + int minor, const char *buf, size_t len) +{ + if (len > 0) { + console_data *cd = &Console_Port_Data[minor]; + int k = 0; + + if (minor == 0) { /* uart a */ + for (k = 0; + k < len && (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEA); + k ++) { + ERC32_MEC.UART_Channel_A = (unsigned char)buf[k]; + } + ERC32_Force_interrupt(ERC32_INTERRUPT_UART_A_RX_TX); + } else { /* uart b */ + for (k = 0; + k < len && (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEB); + k ++) { + ERC32_MEC.UART_Channel_B = (unsigned char)buf[k]; + } + ERC32_Force_interrupt(ERC32_INTERRUPT_UART_B_RX_TX); + } + + cd->pDeviceContext = (void *)k; + cd->bActive = true; + } + + return 0; +} + +static void erc32_console_isr_error( + rtems_vector_number vector +) +{ + int UStat; + + UStat = ERC32_MEC.UART_Status; + + if (UStat & ERC32_MEC_UART_STATUS_ERRA) { + ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRA; + ERC32_MEC.Control = ERC32_MEC.Control; + } + + if (UStat & ERC32_MEC_UART_STATUS_ERRB) { + ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRB; + ERC32_MEC.Control = ERC32_MEC.Control; + } + + ERC32_Clear_interrupt( ERC32_INTERRUPT_UART_ERROR ); +} + +static void erc32_console_isr_a( + rtems_vector_number vector +) +{ + console_data *cd = &Console_Port_Data[0]; + + /* check for error */ + if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_ERRA) { + ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRA; + ERC32_MEC.Control = ERC32_MEC.Control; + } + + do { + int chars_to_dequeue = (int)cd->pDeviceContext; + int rv = 0; + int i = 0; + char buf[CONSOLE_BUF_SIZE]; + + /* enqueue received chars */ + while (i < CONSOLE_BUF_SIZE) { + if (!(ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_DRA)) + break; + buf[i] = ERC32_MEC.UART_Channel_A; + ++i; + } + if ( i ) + rtems_termios_enqueue_raw_characters(cd->termios_data, buf, i); + + /* dequeue transmitted chars */ + if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEA) { + rv = rtems_termios_dequeue_characters( + cd->termios_data, chars_to_dequeue); + if ( !rv ) { + cd->pDeviceContext = 0; + cd->bActive = false; + } + ERC32_Clear_interrupt (ERC32_INTERRUPT_UART_A_RX_TX); + } + } while (ERC32_Is_interrupt_pending (ERC32_INTERRUPT_UART_A_RX_TX)); +} + +static void erc32_console_isr_b( + rtems_vector_number vector +) +{ + console_data *cd = &Console_Port_Data[1]; + + /* check for error */ + if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_ERRB) { + ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRB; + ERC32_MEC.Control = ERC32_MEC.Control; + } + + do { + int chars_to_dequeue = (int)cd->pDeviceContext; + int rv = 0; + int i = 0; + char buf[CONSOLE_BUF_SIZE]; + + /* enqueue received chars */ + while (i < CONSOLE_BUF_SIZE) { + if (!(ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_DRB)) + break; + buf[i] = ERC32_MEC.UART_Channel_B; + ++i; + } + if ( i ) + rtems_termios_enqueue_raw_characters(cd->termios_data, buf, i); + + /* dequeue transmitted chars */ + if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEB) { + rv = rtems_termios_dequeue_characters( + cd->termios_data, chars_to_dequeue); + if ( !rv ) { + cd->pDeviceContext = 0; + cd->bActive = false; + } + ERC32_Clear_interrupt (ERC32_INTERRUPT_UART_B_RX_TX); + } + } while (ERC32_Is_interrupt_pending (ERC32_INTERRUPT_UART_B_RX_TX)); +} +#else + +extern void console_outbyte_polled( int port, unsigned char ch ); + +static ssize_t erc32_console_write_support_polled( + int minor, + const char *buf, + size_t len +) +{ + int nwrite = 0; + + while (nwrite < len) { + console_outbyte_polled( minor, *buf++ ); + nwrite++; + } + return nwrite; +} + +#endif + + +/* + * Console Device Driver Entry Points + * + */ + +static void erc32_console_initialize( + int minor +) +{ + console_data *cd = &Console_Port_Data [minor]; + + cd->bActive = false; + cd->pDeviceContext = 0; + + /* + * Initialize the Termios infrastructure. If Termios has already + * been initialized by another device driver, then this call will + * have no effect. + */ + rtems_termios_initialize(); + + /* + * Initialize Hardware + */ + #if (CONSOLE_USE_INTERRUPTS) + set_vector(erc32_console_isr_a, CONSOLE_UART_A_TRAP, 1); + set_vector(erc32_console_isr_b, CONSOLE_UART_B_TRAP, 1); + set_vector(erc32_console_isr_error, CONSOLE_UART_ERROR_TRAP, 1); + #endif + + /* Clear any previous error flags */ + ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRA; + ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRB; +} diff --git a/bsps/sparc/leon2/console/console.c b/bsps/sparc/leon2/console/console.c new file mode 100644 index 0000000000..611dbfa5f3 --- /dev/null +++ b/bsps/sparc/leon2/console/console.c @@ -0,0 +1,437 @@ +/** + * @file + * @ingroup sparc_leon2 + * @brief TTY driver driver for the serial ports on the LEON console + * + * This file contains the TTY driver for the serial ports on the LEON. + */ + +/* + * COPYRIGHT (c) 1989-2014. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include + +#include +#include +#include +#include + +/* + * console_outbyte_polled + * + * This routine transmits a character using polling. + */ +void console_outbyte_polled( + int port, + unsigned char ch +); + +/* body is in debugputs.c */ + +/* + * console_inbyte_nonblocking + * + * This routine polls for a character. + */ + +int console_inbyte_nonblocking( int port ); + +/* body is in debugputs.c */ + +/* + * Interrupt driven console IO + */ + +#if (CONSOLE_USE_INTERRUPTS) + +/* + * Buffers between task and ISRs + */ + +#include + +Ring_buffer_t TX_Buffer[ 2 ]; +bool Is_TX_active[ 2 ]; + +void *console_termios_data[ 2 ]; + +/* + * console_isr_a + * + * This routine is the console interrupt handler for Channel 1. + * + * Input parameters: + * vector - vector number + * + * Output parameters: NONE + * + * Return values: NONE + */ + +rtems_isr console_isr_a( + rtems_vector_number vector +) +{ + char ch; + int UStat; + + if ( (UStat = LEON_REG.UART_Status_1) & LEON_REG_UART_STATUS_DR ) { + if (UStat & LEON_REG_UART_STATUS_ERR) { + LEON_REG.UART_Status_1 = LEON_REG_UART_STATUS_CLR; + } + ch = LEON_REG.UART_Channel_1; + + rtems_termios_enqueue_raw_characters( console_termios_data[ 0 ], &ch, 1 ); + } + + if ( LEON_REG.UART_Status_1 & LEON_REG_UART_STATUS_THE ) { + if ( !Ring_buffer_Is_empty( &TX_Buffer[ 0 ] ) ) { + Ring_buffer_Remove_character( &TX_Buffer[ 0 ], ch ); + LEON_REG.UART_Channel_1 = (uint32_t) ch; + } else + Is_TX_active[ 0 ] = false; + } + + LEON_Clear_interrupt( LEON_INTERRUPT_UART_1_RX_TX ); +} + +/* + * console_isr_b + * + * This routine is the console interrupt handler for Channel 2. + * + * Input parameters: + * vector - vector number + * + * Output parameters: NONE + * + * Return values: NONE + */ + +rtems_isr console_isr_b( + rtems_vector_number vector +) +{ + char ch; + int UStat; + + if ( (UStat = LEON_REG.UART_Status_2) & LEON_REG_UART_STATUS_DR ) { + if (UStat & LEON_REG_UART_STATUS_ERR) { + LEON_REG.UART_Status_2 = LEON_REG_UART_STATUS_CLR; + } + ch = LEON_REG.UART_Channel_2; + rtems_termios_enqueue_raw_characters( console_termios_data[ 1 ], &ch, 1 ); + + } + + if ( LEON_REG.UART_Status_2 & LEON_REG_UART_STATUS_THE ) { + if ( !Ring_buffer_Is_empty( &TX_Buffer[ 1 ] ) ) { + Ring_buffer_Remove_character( &TX_Buffer[ 1 ], ch ); + LEON_REG.UART_Channel_2 = (uint32_t) ch; + } else + Is_TX_active[ 1 ] = false; + } + + LEON_Clear_interrupt( LEON_INTERRUPT_UART_2_RX_TX ); +} + +/* + * console_exit + * + * This routine allows the console to exit by masking its associated interrupt + * vectors. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: NONE + */ + +void console_exit() +{ + uint32_t port; + uint32_t ch; + + /* + * Although the interrupts for the UART are unmasked, the PIL is set to + * disable all external interrupts. So we might as well do this first. + */ + + LEON_Mask_interrupt( LEON_INTERRUPT_UART_1_RX_TX ); + LEON_Mask_interrupt( LEON_INTERRUPT_UART_2_RX_TX ); + + for ( port=0 ; port <= 1 ; port++ ) { + while ( !Ring_buffer_Is_empty( &TX_Buffer[ port ] ) ) { + Ring_buffer_Remove_character( &TX_Buffer[ port ], ch ); + console_outbyte_polled( port, ch ); + } + } + + /* + * Now wait for all the data to actually get out ... the send register + * should be empty. + */ + + while ( (LEON_REG.UART_Status_1 & LEON_REG_UART_STATUS_THE) != + LEON_REG_UART_STATUS_THE ); + + while ( (LEON_REG.UART_Status_2 & LEON_REG_UART_STATUS_THE) != + LEON_REG_UART_STATUS_THE ); + + LEON_REG.UART_Control_1 = 0; + LEON_REG.UART_Control_2 = 0; + LEON_REG.UART_Status_1 = 0; + LEON_REG.UART_Status_2 = 0; + + +} + +#define CONSOLE_UART_1_TRAP LEON_TRAP_TYPE( LEON_INTERRUPT_UART_1_RX_TX ) +#define CONSOLE_UART_2_TRAP LEON_TRAP_TYPE( LEON_INTERRUPT_UART_2_RX_TX ) + +/* + * console_initialize_interrupts + * + * This routine initializes the console's receive and transmit + * ring buffers and loads the appropriate vectors to handle the interrupts. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: NONE + */ + +#ifdef RDB_BREAK_IN + extern uint32_t trap_table[]; +#endif + +void console_initialize_interrupts( void ) +{ + Ring_buffer_Initialize( &TX_Buffer[ 0 ] ); + Ring_buffer_Initialize( &TX_Buffer[ 1 ] ); + + Is_TX_active[ 0 ] = false; + Is_TX_active[ 1 ] = false; + + atexit( console_exit ); + + LEON_REG.UART_Control_1 |= LEON_REG_UART_CTRL_RI | LEON_REG_UART_CTRL_TI; + LEON_REG.UART_Control_2 |= LEON_REG_UART_CTRL_RI | LEON_REG_UART_CTRL_TI; + + set_vector( console_isr_a, CONSOLE_UART_1_TRAP, 1 ); +#ifdef RDB_BREAK_IN + if (trap_table[0x150/4] == 0x91d02000) +#endif + set_vector( console_isr_b, CONSOLE_UART_2_TRAP, 1 ); +} + +/* + * console_outbyte_interrupt + * + * This routine transmits a character out. + * + * Input parameters: + * port - port to transmit character to + * ch - character to be transmitted + * + * Output parameters: NONE + * + * Return values: NONE + */ + +void console_outbyte_interrupt( + int port, + char ch +) +{ + /* + * If this is the first character then we need to prime the pump + */ + + if ( Is_TX_active[ port ] == false ) { + Is_TX_active[ port ] = true; + console_outbyte_polled( port, ch ); + return; + } + + while ( Ring_buffer_Is_full( &TX_Buffer[ port ] ) ); + + Ring_buffer_Add_character( &TX_Buffer[ port ], ch ); +} + +#endif /* CONSOLE_USE_INTERRUPTS */ + +/* + * Console Termios Support Entry Points + * + */ + +static ssize_t console_write_support (int minor, const char *buf, size_t len) +{ + int nwrite = 0; + + while (nwrite < len) { +#if (CONSOLE_USE_INTERRUPTS) + console_outbyte_interrupt( minor, *buf++ ); +#else + console_outbyte_polled( minor, *buf++ ); +#endif + nwrite++; + } + return nwrite; +} + +/* + * Console Device Driver Entry Points + * + */ + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + + rtems_termios_initialize(); + + /* + * Register Device Names + */ + + status = rtems_io_register_name( "/dev/console", major, 0 ); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + status = rtems_io_register_name( "/dev/console_b", major, 1 ); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + /* + * Initialize Hardware + */ + + LEON_REG.UART_Control_1 |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE; + LEON_REG.UART_Control_2 |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE | + LEON_REG_UART_CTRL_RI; /* rx irq default enable for remote debugger */ + LEON_REG.UART_Status_1 = 0; + LEON_REG.UART_Status_2 = 0; +#if (CONSOLE_USE_INTERRUPTS) + console_initialize_interrupts(); +#endif + + return RTEMS_SUCCESSFUL; +} + +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_status_code sc; +#if (CONSOLE_USE_INTERRUPTS) + rtems_libio_open_close_args_t *args = arg; + static const rtems_termios_callbacks intrCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + NULL, /* pollRead */ + console_write_support, /* write */ + NULL, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + 0 /* outputUsesInterrupts */ + }; +#else + static const rtems_termios_callbacks pollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + console_inbyte_nonblocking, /* pollRead */ + console_write_support, /* write */ + NULL, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + 0 /* outputUsesInterrupts */ + }; +#endif + + assert( minor <= 1 ); + if ( minor > 2 ) + return RTEMS_INVALID_NUMBER; + +#if (CONSOLE_USE_INTERRUPTS) + sc = rtems_termios_open (major, minor, arg, &intrCallbacks); + + console_termios_data[ minor ] = args->iop->data1; +#else + sc = rtems_termios_open (major, minor, arg, &pollCallbacks); +#endif + (void) sc; /* avoid set but not used warning */ + + return RTEMS_SUCCESSFUL; +} + +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_close (arg); +} + +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_read (arg); +} + +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_write (arg); +} + +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_ioctl (arg); +} + +/* putchar/getchar for printk */ + +static void bsp_out_char (char c) +{ + console_outbyte_polled(0, c); +} + +BSP_output_char_function_type BSP_output_char = bsp_out_char; + +static int bsp_in_char(void) +{ + int tmp; + + while ((tmp = console_inbyte_nonblocking(0)) < 0); + return tmp; +} + +BSP_polling_getchar_function_type BSP_poll_char = bsp_in_char; diff --git a/bsps/sparc/leon2/console/debugputs.c b/bsps/sparc/leon2/console/debugputs.c new file mode 100644 index 0000000000..c5919f275e --- /dev/null +++ b/bsps/sparc/leon2/console/debugputs.c @@ -0,0 +1,87 @@ +/** + * @file + * @ingroup sparc_leon2 + * @brief TTY driver for the serial ports on the LEON + */ + +/* + * This file contains the TTY driver for the serial ports on the LEON. + * + * This driver uses the termios pseudo driver. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include + +/* + * Method is shared with console.c + */ +void console_outbyte_polled( int port, unsigned char ch ); +int console_inbyte_nonblocking( int port ); + +/* + * console_outbyte_polled + * + * This routine transmits a character using polling. + */ + +void console_outbyte_polled( + int port, + unsigned char ch +) +{ + if ( port == 0 ) { + while ( (LEON_REG.UART_Status_1 & LEON_REG_UART_STATUS_THE) == 0 ); + LEON_REG.UART_Channel_1 = (unsigned int) ch; + return; + } + + while ( (LEON_REG.UART_Status_2 & LEON_REG_UART_STATUS_THE) == 0 ); + LEON_REG.UART_Channel_2 = (unsigned int) ch; +} + +/* + * console_inbyte_nonblocking + * + * This routine polls for a character. + */ + +int console_inbyte_nonblocking( int port ) +{ + + switch (port) { + + case 0: + if (LEON_REG.UART_Status_1 & LEON_REG_UART_STATUS_ERR) { + LEON_REG.UART_Status_1 = ~LEON_REG_UART_STATUS_ERR; + } + + if ((LEON_REG.UART_Status_1 & LEON_REG_UART_STATUS_DR) == 0) + return -1; + return (int) LEON_REG.UART_Channel_1; + return 1; + + case 1: + if (LEON_REG.UART_Status_2 & LEON_REG_UART_STATUS_ERR) { + LEON_REG.UART_Status_2 = ~LEON_REG_UART_STATUS_ERR; + } + + if ((LEON_REG.UART_Status_2 & LEON_REG_UART_STATUS_DR) == 0) + return -1; + return (int) LEON_REG.UART_Channel_2; + + default: + assert( 0 ); + } + + return -1; +} diff --git a/bsps/sparc/leon3/console/console.c b/bsps/sparc/leon3/console/console.c new file mode 100644 index 0000000000..acab893399 --- /dev/null +++ b/bsps/sparc/leon3/console/console.c @@ -0,0 +1,160 @@ +/* + * This file contains the TTY driver for the serial ports on the LEON. + * + * This driver uses the termios pseudo driver. + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * + * Modified for LEON3 BSP. + * COPYRIGHT (c) 2004. + * Gaisler Research. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +/* Define CONSOLE_USE_INTERRUPTS to enable APBUART interrupt handling instead + * of polling mode. + * + * Note that it is not possible to use the interrupt mode of the driver + * together with the "old" APBUART and -u to GRMON. However the new + * APBUART core (from GRLIB 1.0.17-b2710) has the GRMON debug bit and can + * handle interrupts. + * + * NOTE: This can be defined in the make/custom/leon3.cfg file. + */ + +#include +#include +#include +#include +#include + +/* The LEON3 BSP UART driver can rely on the Driver Manager if the + * DrvMgr is initialized during startup. Otherwise the classic driver + * must be used. + * + * The DrvMgr APBUART driver is located in the shared/uart directory + */ +#ifndef RTEMS_DRVMGR_STARTUP + +int syscon_uart_index __attribute__((weak)) = 0; + +/* body is in debugputs.c */ +static struct apbuart_context apbuarts[BSP_NUMBER_OF_TERMIOS_PORTS]; +static int uarts = 0; + +static rtems_termios_device_context *leon3_console_get_context(int index) +{ + struct apbuart_context *uart = &apbuarts[index]; + + rtems_termios_device_context_initialize(&uart->base, "APBUART"); + + return &uart->base; +} + +/* AMBA PP find routine. Extract AMBA PnP information into data structure. */ +static int find_matching_apbuart(struct ambapp_dev *dev, int index, void *arg) +{ + struct ambapp_apb_info *apb = (struct ambapp_apb_info *)dev->devinfo; + + /* Extract needed information of one APBUART */ + apbuarts[uarts].regs = (struct apbuart_regs *)apb->start; + apbuarts[uarts].irq = apb->irq; + /* Get APBUART core frequency, it is assumed that it is the same + * as Bus frequency where the UART is situated + */ + apbuarts[uarts].freq_hz = ambapp_freq_get(&ambapp_plb, dev); + uarts++; + + if (uarts >= BSP_NUMBER_OF_TERMIOS_PORTS) + return 1; /* Satisfied number of UARTs, stop search */ + else + return 0; /* Continue searching for more UARTs */ +} + +/* Find all UARTs */ +static void leon3_console_scan_uarts(void) +{ + memset(apbuarts, 0, sizeof(apbuarts)); + + /* Find APBUART cores */ + ambapp_for_each(&ambapp_plb, (OPTIONS_ALL|OPTIONS_APB_SLVS), VENDOR_GAISLER, + GAISLER_APBUART, find_matching_apbuart, NULL); +} + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + const rtems_termios_device_handler *handler = +#if CONSOLE_USE_INTERRUPTS + &apbuart_handler_interrupt; +#else + &apbuart_handler_polled; +#endif + rtems_status_code status; + int i; + char console_name[16]; + + rtems_termios_initialize(); + + /* Find UARTs */ + leon3_console_scan_uarts(); + + /* Update syscon_uart_index to index used as /dev/console + * Let user select System console by setting syscon_uart_index. If the + * BSP is to provide the default UART (syscon_uart_index==0): + * non-MP: APBUART[0] is system console + * MP: LEON CPU index select UART + */ + if (syscon_uart_index == 0) { +#if defined(RTEMS_MULTIPROCESSING) + syscon_uart_index = LEON3_Cpu_Index; +#else + syscon_uart_index = 0; +#endif + } else { + syscon_uart_index = syscon_uart_index - 1; /* User selected sys-console */ + } + + /* Register Device Names + * + * 0 /dev/console - APBUART[USER-SELECTED, DEFAULT=APBUART[0]] + * 1 /dev/console_a - APBUART[0] (by default not present because is console) + * 2 /dev/console_b - APBUART[1] + * ... + * + * On a MP system one should not open UARTs that other OS instances use. + */ + if (syscon_uart_index < uarts) { + status = rtems_termios_device_install( + CONSOLE_DEVICE_NAME, + handler, + NULL, + leon3_console_get_context(syscon_uart_index) + ); + if (status != RTEMS_SUCCESSFUL) + bsp_fatal(LEON3_FATAL_CONSOLE_REGISTER_DEV); + } + strcpy(console_name,"/dev/console_a"); + for (i = 0; i < uarts; i++) { + if (i == syscon_uart_index) + continue; /* skip UART that is registered as /dev/console */ + console_name[13] = 'a' + i; + rtems_termios_device_install( + console_name, + handler, + NULL, + leon3_console_get_context(i) + ); + } + + return RTEMS_SUCCESSFUL; +} + +#endif diff --git a/bsps/sparc/leon3/console/printk_support.c b/bsps/sparc/leon3/console/printk_support.c new file mode 100644 index 0000000000..f7e1fb683f --- /dev/null +++ b/bsps/sparc/leon3/console/printk_support.c @@ -0,0 +1,119 @@ +/* + * This file contains the TTY driver for the serial ports on the LEON. + * + * This driver uses the termios pseudo driver. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * Modified for LEON3 BSP. + * COPYRIGHT (c) 2011. + * Aeroflex Gaisler. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int leon3_debug_uart_index __attribute__((weak)) = 0; +struct apbuart_regs *leon3_debug_uart = NULL; + +/* Before UART driver has registered (or when no UART is available), calls to + * printk that gets to bsp_out_char() will be filling data into the + * pre_printk_dbgbuf[] buffer, hopefully the buffer can help debugging the + * early BSP boot.. At least the last printk() will be caught. + */ +static char pre_printk_dbgbuf[32] = {0}; +static int pre_printk_pos = 0; + +/* Initialize the BSP system debug console layer. It will scan AMBA Plu&Play + * for a debug APBUART and enable RX/TX for that UART. + */ +static void bsp_debug_uart_init(void) +{ + int i; + struct ambapp_dev *adev; + struct ambapp_apb_info *apb; + + /* Update leon3_debug_uart_index to index used as debug console. Let user + * select Debug console by setting leon3_debug_uart_index. If the BSP is to + * provide the default UART (leon3_debug_uart_index==0): + * non-MP: APBUART[0] is debug console + * MP: LEON CPU index select UART + */ + if (leon3_debug_uart_index == 0) { +#if defined(RTEMS_MULTIPROCESSING) + leon3_debug_uart_index = LEON3_Cpu_Index; +#else + leon3_debug_uart_index = 0; +#endif + } else { + leon3_debug_uart_index--; /* User selected dbg-console */ + } + + /* Find APBUART core for System Debug Console */ + i = leon3_debug_uart_index; + adev = (void *)ambapp_for_each(&ambapp_plb, (OPTIONS_ALL|OPTIONS_APB_SLVS), + VENDOR_GAISLER, GAISLER_APBUART, + ambapp_find_by_idx, (void *)&i); + if (adev) { + /* Found a matching debug console, initialize debug uart if present + * for printk + */ + apb = (struct ambapp_apb_info *)adev->devinfo; + leon3_debug_uart = (struct apbuart_regs *)apb->start; + leon3_debug_uart->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; + leon3_debug_uart->status = 0; + } +} + +RTEMS_SYSINIT_ITEM( + bsp_debug_uart_init, + RTEMS_SYSINIT_BSP_START, + RTEMS_SYSINIT_ORDER_FOURTH +); + +/* putchar/getchar for printk */ +static void bsp_out_char(char c) +{ + if (leon3_debug_uart == NULL) { + /* Local debug buffer when UART driver has not registered */ + pre_printk_dbgbuf[pre_printk_pos++] = c; + pre_printk_pos = pre_printk_pos & (sizeof(pre_printk_dbgbuf)-1); + return; + } + + apbuart_outbyte_polled(leon3_debug_uart, c, 1, 1); +} + +/* + * To support printk + */ + +#include + +BSP_output_char_function_type BSP_output_char = bsp_out_char; + +static int bsp_in_char(void) +{ + int tmp; + + if (leon3_debug_uart == NULL) + return EOF; + + while ((tmp = apbuart_inbyte_nonblocking(leon3_debug_uart)) < 0) + ; + return tmp; +} + +BSP_polling_getchar_function_type BSP_poll_char = bsp_in_char; diff --git a/bsps/sparc64/shared/console/conscfg.c b/bsps/sparc64/shared/console/conscfg.c new file mode 100644 index 0000000000..560bdc05bf --- /dev/null +++ b/bsps/sparc64/shared/console/conscfg.c @@ -0,0 +1,115 @@ +/* + * COPYRIGHT (c) 2010 Eugen Leontie. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include + +#include + +#include + +#include + +static int sun4v_console_device_first_open(int major, int minor, void *arg) +{ + return 0; +} + +static ssize_t sun4v_console_poll_write(int minor, const char *buf, size_t n) +{ + ofw_write(buf, n); + return 0; +} + +static void sun4v_console_deviceInitialize (int minor) +{ + +} + +static int sun4v_console_poll_read(int minor){ + int a; + ofw_read(&a,1); + if ( a != 0 ) { + return a>>24; + } + return -1; +} + +static bool sun4v_console_deviceProbe (int minor){ + return true; +} + +/* + * Polled mode functions + */ +const console_fns pooled_functions={ + sun4v_console_deviceProbe, /* deviceProbe */ + sun4v_console_device_first_open, /* deviceFirstOpen */ + NULL, /* deviceLastClose */ + sun4v_console_poll_read, /* deviceRead */ + sun4v_console_poll_write, /* deviceWrite */ + sun4v_console_deviceInitialize, /* deviceInitialize */ + NULL, /* deviceWritePolled */ + NULL, /* deviceSetAttributes */ + NULL /* deviceOutputUsesInterrupts */ +}; + +const console_flow sun4v_console_console_flow = { + NULL, /* deviceStopRemoteTx */ + NULL /* deviceStartRemoteTx */ +}; + +console_tbl Console_Configuration_Ports[] = { + { + "/dev/ttyS0", /* sDeviceName */ + SERIAL_CUSTOM, /* deviceType */ + &pooled_functions, /* pDeviceFns */ + NULL, /* deviceProbe, assume it is there */ + &sun4v_console_console_flow, /* pDeviceFlow */ + 0, /* ulMargin */ + 0, /* ulHysteresis */ + (void *) NULL, /* pDeviceParams */ + 0, /* ulCtrlPort1 */ + 0, /* ulCtrlPort2 */ + 1, /* ulDataPort */ + NULL, /* getRegister */ + NULL, /* setRegister */ + NULL, /* unused */ /* getData */ + NULL, /* unused */ /* setData */ + 0, /* ulClock */ + 0 /* ulIntVector -- base for port */ + }, +}; + +/* + * Declare some information used by the console driver + */ + +#define NUM_CONSOLE_PORTS 1 + +unsigned long Console_Configuration_Count = NUM_CONSOLE_PORTS; + +/* putchar/getchar for printk */ + +static void bsp_out_char (char c) +{ + ofw_write(&c, 1); +} + +BSP_output_char_function_type BSP_output_char = bsp_out_char; + +static int bsp_in_char( void ){ + int tmp; + ofw_read( &tmp, 1 ); /* blocks */ + if( tmp != 0 ) { + return tmp>>24; + } + return -1; +} + +BSP_polling_getchar_function_type BSP_poll_char = bsp_in_char; + diff --git a/bsps/v850/gdbv850sim/console/console-io.c b/bsps/v850/gdbv850sim/console/console-io.c new file mode 100644 index 0000000000..c1f51a34d7 --- /dev/null +++ b/bsps/v850/gdbv850sim/console/console-io.c @@ -0,0 +1,62 @@ +/* + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include + +/* + * console_initialize_hardware + * + * This routine initializes the console hardware. + */ +void console_initialize_hardware(void) +{ +} + +/* + * console_outbyte_polled + * + * This routine transmits a character using polling. + */ +void console_outbyte_polled( + int port, + char ch +) +{ + TRAP0(SYS_write, 1, &ch, 1); +} + +/* + * console_inbyte_nonblocking + * + * This routine polls for a character. + */ + +int console_inbyte_nonblocking( + int port +) +{ + char ch; + int rc; + + rc = TRAP0 (SYS_read, 0, &ch, 1); + + if ( rc != 1 ) + return -1; + return ch; +} + +#include + +static void console_output_char(char c) { console_outbyte_polled( 0, c ); } + +BSP_output_char_function_type BSP_output_char = console_output_char; +BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/Makefile.am b/c/src/lib/libbsp/arm/altera-cyclone-v/Makefile.am index 8fff55e7c8..63449347ad 100644 --- a/c/src/lib/libbsp/arm/altera-cyclone-v/Makefile.am +++ b/c/src/lib/libbsp/arm/altera-cyclone-v/Makefile.am @@ -106,9 +106,9 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c librtemsbsp_a_SOURCES += ../shared/arm-gic-irq.c # Console -librtemsbsp_a_SOURCES += ../../shared/console-termios-init.c -librtemsbsp_a_SOURCES += ../../shared/console-termios.c -librtemsbsp_a_SOURCES += console/console-config.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios-init.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/altera-cyclone-v/console/console-config.c # Clock librtemsbsp_a_SOURCES += ../shared/arm-a9mpcore-clock-config.c diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/console/console-config.c b/c/src/lib/libbsp/arm/altera-cyclone-v/console/console-config.c deleted file mode 100644 index e4dfec9f62..0000000000 --- a/c/src/lib/libbsp/arm/altera-cyclone-v/console/console-config.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef BSP_USE_UART_INTERRUPTS - #define DEVICE_FNS &ns16550_handler_interrupt -#else - #define DEVICE_FNS &ns16550_handler_polled -#endif - -static uint8_t altera_cyclone_v_uart_get_register(uintptr_t addr, uint8_t i) -{ - volatile uint32_t *reg = (volatile uint32_t *) addr; - - return (uint8_t) reg [i]; -} - -static void altera_cyclone_v_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val) -{ - volatile uint32_t *reg = (volatile uint32_t *) addr; - - reg [i] = val; -} - -static bool altera_cyclone_v_uart_probe( - rtems_termios_device_context *base, - uint32_t uart_set_mask -) -{ - ns16550_context *ctx = (ns16550_context *) base; - bool ret = true; - uint32_t ucr; - ALT_STATUS_CODE sc; - void* location = (void *) ctx->port; - - /* The ALT_CLK_L4_SP is required for all SoCFPGA UARTs. - * Check that it's enabled. */ - if ( alt_clk_is_enabled(ALT_CLK_L4_SP) != ALT_E_TRUE ) { - ret = false; - } - - if ( ret ) { - sc = alt_clk_freq_get(ALT_CLK_L4_SP, &ctx->clock); - if ( sc != ALT_E_SUCCESS ) { - ret = false; - } - } - - if ( ret ) { - // Bring UART out of reset. - alt_clrbits_word(ALT_RSTMGR_PERMODRST_ADDR, uart_set_mask); - - // Verify the UCR (UART Component Version) - ucr = alt_read_word( ALT_UART_UCV_ADDR( location ) ); - if ( ucr != ALT_UART_UCV_UART_COMPONENT_VER_RESET ) { - ret = false; - } - } - - if ( ret ) { - // Write SRR::UR (Shadow Reset Register :: UART Reset) - alt_write_word( ALT_UART_SRR_ADDR( location ), ALT_UART_SRR_UR_SET_MSK ); - - // Read the MSR to work around case:119085. - (void)alt_read_word( ALT_UART_MSR_ADDR( location ) ); - - ret = ns16550_probe( base ); - } - - return ret; -} - -#ifdef CYCLONE_V_CONFIG_CONSOLE -static bool altera_cyclone_v_uart_probe_0(rtems_termios_device_context *base) -{ - return altera_cyclone_v_uart_probe(base, ALT_RSTMGR_PERMODRST_UART0_SET_MSK); -} - -static ns16550_context altera_cyclone_v_uart_context_0 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"), - .get_reg = altera_cyclone_v_uart_get_register, - .set_reg = altera_cyclone_v_uart_set_register, - .port = (uintptr_t) ALT_UART0_ADDR, - .irq = ALT_INT_INTERRUPT_UART0, - .initial_baud = CYCLONE_V_UART_BAUD -}; -#endif - -#ifdef CYCLONE_V_CONFIG_UART_1 -static bool altera_cyclone_v_uart_probe_1(rtems_termios_device_context *base) -{ - return altera_cyclone_v_uart_probe(base, ALT_RSTMGR_PERMODRST_UART1_SET_MSK); -} - -static ns16550_context altera_cyclone_v_uart_context_1 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"), - .get_reg = altera_cyclone_v_uart_get_register, - .set_reg = altera_cyclone_v_uart_set_register, - .port = (uintptr_t) ALT_UART1_ADDR, - .irq = ALT_INT_INTERRUPT_UART1, - .initial_baud = CYCLONE_V_UART_BAUD -}; -#endif - -const console_device console_device_table[] = { - #ifdef CYCLONE_V_CONFIG_CONSOLE - { - .device_file = "/dev/ttyS0", - .probe = altera_cyclone_v_uart_probe_0, - .handler = DEVICE_FNS, - .context = &altera_cyclone_v_uart_context_0.base - }, - #endif - #ifdef CYCLONE_V_CONFIG_UART_1 - { - .device_file = "/dev/ttyS1", - .probe = altera_cyclone_v_uart_probe_1, - .handler = DEVICE_FNS, - .context = &altera_cyclone_v_uart_context_1.base - }, - #endif -}; - -const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table); - -static void output_char(char c) -{ - rtems_termios_device_context *ctx = console_device_table[0].context; - - ns16550_polled_putchar( ctx, c ); -} - -BSP_output_char_function_type BSP_output_char = output_char; - -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/arm/atsam/Makefile.am b/c/src/lib/libbsp/arm/atsam/Makefile.am index 4472869d5c..758b84b343 100644 --- a/c/src/lib/libbsp/arm/atsam/Makefile.am +++ b/c/src/lib/libbsp/arm/atsam/Makefile.am @@ -113,9 +113,9 @@ librtemsbsp_a_SOURCES += ../shared/armv7m/irq/armv7m-irq.c librtemsbsp_a_SOURCES += ../shared/armv7m/irq/armv7m-irq-dispatch.c # Console -librtemsbsp_a_SOURCES += ../../shared/console-termios.c -librtemsbsp_a_SOURCES += console/console.c -librtemsbsp_a_SOURCES += console/debug-console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/console/debug-console.c # Clock librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/clock/clock-armv7m.c diff --git a/c/src/lib/libbsp/arm/atsam/console/console.c b/c/src/lib/libbsp/arm/atsam/console/console.c deleted file mode 100644 index d51d2ace7d..0000000000 --- a/c/src/lib/libbsp/arm/atsam/console/console.c +++ /dev/null @@ -1,526 +0,0 @@ -/* - * Copyright (c) 2016 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include - -#include - -#include - -#include - -typedef struct { - rtems_termios_device_context base; - Usart *regs; - rtems_vector_number irq; - uint32_t id; - bool console; -#ifdef ATSAM_CONSOLE_USE_INTERRUPTS - bool transmitting; -#endif -} atsam_usart_context; - -static atsam_usart_context atsam_usart_instances[] = { - { - .regs = USART0, - .irq = USART0_IRQn, - .id = ID_USART0 - } -#ifdef USART1 - , { - .regs = USART1, - .irq = USART1_IRQn, - .id = ID_USART1 - } -#endif -#ifdef USART2 - , { - .regs = USART2, - .irq = USART2_IRQn, - .id = ID_USART2 - } -#endif -}; - -#ifdef ATSAM_CONSOLE_USE_INTERRUPTS -static void atsam_usart_interrupt(void *arg) -{ - rtems_termios_tty *tty = arg; - atsam_usart_context *ctx = rtems_termios_get_device_context(tty); - Usart *regs = ctx->regs; - uint32_t csr = regs->US_CSR; - - while ((csr & US_CSR_RXRDY) != 0) { - char c = (char) regs->US_RHR; - - rtems_termios_enqueue_raw_characters(tty, &c, 1); - - csr = regs->US_CSR; - } - - if (ctx->transmitting && (csr & US_CSR_TXEMPTY) != 0) { - rtems_termios_dequeue_characters(tty, 1); - } -} -#endif - -static bool atsam_usart_set_attributes( - rtems_termios_device_context *base, - const struct termios *term -) -{ - atsam_usart_context *ctx = (atsam_usart_context *) base; - Usart *regs = ctx->regs; - rtems_termios_baud_t baud; - uint32_t mr; - - baud = rtems_termios_baud_to_number(term->c_ospeed); - regs->US_BRGR = (BOARD_MCK / baud) / 16; - - if ((term->c_cflag & CREAD) != 0) { - regs->US_CR = US_CR_RXEN | US_CR_TXEN; - } else { - regs->US_CR = US_CR_TXEN; - } - - mr = US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK; - - switch (term->c_cflag & CSIZE) { - case CS5: - mr |= US_MR_CHRL_5_BIT; - break; - case CS6: - mr |= US_MR_CHRL_6_BIT; - break; - case CS7: - mr |= US_MR_CHRL_7_BIT; - break; - default: - mr |= US_MR_CHRL_8_BIT; - break; - } - - if ((term->c_cflag & PARENB) != 0) { - if ((term->c_cflag & PARODD) != 0) { - mr |= US_MR_PAR_ODD; - } else { - mr |= US_MR_PAR_EVEN; - } - } else { - mr |= US_MR_PAR_NO; - } - - if ((term->c_cflag & CSTOPB) != 0) { - mr |= US_MR_NBSTOP_2_BIT; - } else { - mr |= US_MR_NBSTOP_1_BIT; - } - - regs->US_MR = mr; - - return true; -} - -static bool atsam_usart_first_open( - rtems_termios_tty *tty, - rtems_termios_device_context *base, - struct termios *term, - rtems_libio_open_close_args_t *args -) -{ - atsam_usart_context *ctx = (atsam_usart_context *) base; - Usart *regs = ctx->regs; -#ifdef ATSAM_CONSOLE_USE_INTERRUPTS - rtems_status_code sc; -#endif - - regs->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RSTSTA; - regs->US_IDR = 0xffffffff; - - PMC_EnablePeripheral(ctx->id); - - rtems_termios_set_initial_baud(tty, ATSAM_CONSOLE_BAUD); - atsam_usart_set_attributes(base, term); - -#ifdef ATSAM_CONSOLE_USE_INTERRUPTS - regs->US_IER = US_IDR_RXRDY; - sc = rtems_interrupt_handler_install( - ctx->irq, - "USART", - RTEMS_INTERRUPT_SHARED, - atsam_usart_interrupt, - tty - ); - if (sc != RTEMS_SUCCESSFUL) { - return false; - } -#endif - - return true; -} - -static void atsam_usart_last_close( - rtems_termios_tty *tty, - rtems_termios_device_context *base, - rtems_libio_open_close_args_t *args -) -{ - atsam_usart_context *ctx = (atsam_usart_context *) base; - -#ifdef ATSAM_CONSOLE_USE_INTERRUPTS - rtems_interrupt_handler_remove(ctx->irq, atsam_usart_interrupt, tty); -#endif - - if (!ctx->console) { - PMC_DisablePeripheral(ctx->id); - } -} - -static void atsam_usart_write( - rtems_termios_device_context *base, - const char *buf, - size_t len -) -{ - atsam_usart_context *ctx = (atsam_usart_context *) base; - Usart *regs = ctx->regs; - -#ifdef ATSAM_CONSOLE_USE_INTERRUPTS - if (len > 0) { - ctx->transmitting = true; - regs->US_THR = buf[0]; - regs->US_IER = US_IDR_TXEMPTY; - } else { - ctx->transmitting = false; - regs->US_IDR = US_IDR_TXEMPTY; - } -#else - size_t i; - - for (i = 0; i < len; ++i) { - while ((regs->US_CSR & US_CSR_TXEMPTY) == 0) { - /* Wait */ - } - - regs->US_THR = buf[i]; - } -#endif -} - -#ifndef ATSAM_CONSOLE_USE_INTERRUPTS -static int atsam_usart_read(rtems_termios_device_context *base) -{ - atsam_usart_context *ctx = (atsam_usart_context *) base; - Usart *regs = ctx->regs; - - if ((regs->US_CSR & US_CSR_RXRDY) != 0) { - return (char) regs->US_RHR; - } else { - return -1; - } -} -#endif - -static const rtems_termios_device_handler atsam_usart_handler = { - .first_open = atsam_usart_first_open, - .last_close = atsam_usart_last_close, - .write = atsam_usart_write, - .set_attributes = atsam_usart_set_attributes, -#ifdef ATSAM_CONSOLE_USE_INTERRUPTS - .mode = TERMIOS_IRQ_DRIVEN -#else - .poll_read = atsam_usart_read, - .mode = TERMIOS_POLLED -#endif -}; - -typedef struct { - rtems_termios_device_context base; - Uart *regs; - rtems_vector_number irq; - uint32_t id; - bool console; -#ifdef ATSAM_CONSOLE_USE_INTERRUPTS - bool transmitting; -#endif -} atsam_uart_context; - -static atsam_uart_context atsam_uart_instances[] = { - { - .regs = UART0, - .irq = UART0_IRQn, - .id = ID_UART0 - } -#ifdef UART1 - , { - .regs = UART1, - .irq = UART1_IRQn, - .id = ID_UART1 - } -#endif -#ifdef UART2 - , { - .regs = UART2, - .irq = UART2_IRQn, - .id = ID_UART2 - } -#endif -#ifdef UART3 - , { - .regs = UART3, - .irq = UART3_IRQn, - .id = ID_UART3 - } -#endif -#ifdef UART4 - , { - .regs = UART4, - .irq = UART4_IRQn, - .id = ID_UART4 - } -#endif -}; - -#ifdef ATSAM_CONSOLE_USE_INTERRUPTS -static void atsam_uart_interrupt(void *arg) -{ - rtems_termios_tty *tty = arg; - atsam_uart_context *ctx = rtems_termios_get_device_context(tty); - Uart *regs = ctx->regs; - uint32_t sr = regs->UART_SR; - - while ((sr & UART_SR_RXRDY) != 0) { - char c = (char) regs->UART_RHR; - - rtems_termios_enqueue_raw_characters(tty, &c, 1); - - sr = regs->UART_SR; - } - - if (ctx->transmitting && (sr & UART_SR_TXEMPTY) != 0) { - rtems_termios_dequeue_characters(tty, 1); - } -} -#endif - -static bool atsam_uart_set_attributes( - rtems_termios_device_context *base, - const struct termios *term -) -{ - atsam_uart_context *ctx = (atsam_uart_context *) base; - Uart *regs = ctx->regs; - rtems_termios_baud_t baud; - uint32_t mr; - - baud = rtems_termios_baud_to_number(term->c_ospeed); - regs->UART_BRGR = (BOARD_MCK / baud) / 16; - - if ((term->c_cflag & CREAD) != 0) { - regs->UART_CR = UART_CR_RXEN | UART_CR_TXEN; - } else { - regs->UART_CR = UART_CR_TXEN; - } - - mr = UART_MR_FILTER_DISABLED | UART_MR_BRSRCCK_PERIPH_CLK; - - if ((term->c_cflag & CSIZE) != CS8) { - return false; - } - - if ((term->c_cflag & PARENB) != 0) { - if ((term->c_cflag & PARODD) != 0) { - mr |= UART_MR_PAR_ODD; - } else { - mr |= UART_MR_PAR_EVEN; - } - } else { - mr |= UART_MR_PAR_NO; - } - - if ((term->c_cflag & CSTOPB) != 0) { - return false; - } - - regs->UART_MR = mr; - - return true; -} - -static bool atsam_uart_first_open( - rtems_termios_tty *tty, - rtems_termios_device_context *base, - struct termios *term, - rtems_libio_open_close_args_t *args -) -{ - atsam_uart_context *ctx = (atsam_uart_context *) base; - Uart *regs = ctx->regs; -#ifdef ATSAM_CONSOLE_USE_INTERRUPTS - rtems_status_code sc; -#endif - - regs->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RSTSTA; - regs->UART_IDR = 0xffffffff; - - PMC_EnablePeripheral(ctx->id); - - rtems_termios_set_initial_baud(tty, ATSAM_CONSOLE_BAUD); - atsam_uart_set_attributes(base, term); - -#ifdef ATSAM_CONSOLE_USE_INTERRUPTS - regs->UART_IER = UART_IDR_RXRDY; - sc = rtems_interrupt_handler_install( - ctx->irq, - "UART", - RTEMS_INTERRUPT_SHARED, - atsam_uart_interrupt, - tty - ); - if (sc != RTEMS_SUCCESSFUL) { - return false; - } -#endif - - return true; -} - -static void atsam_uart_last_close( - rtems_termios_tty *tty, - rtems_termios_device_context *base, - rtems_libio_open_close_args_t *args -) -{ - atsam_uart_context *ctx = (atsam_uart_context *) base; - -#ifdef ATSAM_CONSOLE_USE_INTERRUPTS - rtems_interrupt_handler_remove(ctx->irq, atsam_uart_interrupt, tty); -#endif - - if (!ctx->console) { - PMC_DisablePeripheral(ctx->id); - } -} - -static void atsam_uart_write( - rtems_termios_device_context *base, - const char *buf, - size_t len -) -{ - atsam_uart_context *ctx = (atsam_uart_context *) base; - Uart *regs = ctx->regs; - -#ifdef ATSAM_CONSOLE_USE_INTERRUPTS - if (len > 0) { - ctx->transmitting = true; - regs->UART_THR = buf[0]; - regs->UART_IER = UART_IDR_TXEMPTY; - } else { - ctx->transmitting = false; - regs->UART_IDR = UART_IDR_TXEMPTY; - } -#else - size_t i; - - for (i = 0; i < len; ++i) { - while ((regs->UART_SR & UART_SR_TXEMPTY) == 0) { - /* Wait */ - } - - regs->UART_THR = buf[i]; - } -#endif -} - -#ifndef ATSAM_CONSOLE_USE_INTERRUPTS -static int atsam_uart_read(rtems_termios_device_context *base) -{ - atsam_uart_context *ctx = (atsam_uart_context *) base; - Uart *regs = ctx->regs; - - if ((regs->UART_SR & UART_SR_RXRDY) != 0) { - return (char) regs->UART_RHR; - } else { - return -1; - } -} -#endif - -static const rtems_termios_device_handler atsam_uart_handler = { - .first_open = atsam_uart_first_open, - .last_close = atsam_uart_last_close, - .write = atsam_uart_write, - .set_attributes = atsam_uart_set_attributes, -#ifdef ATSAM_CONSOLE_USE_INTERRUPTS - .mode = TERMIOS_IRQ_DRIVEN -#else - .poll_read = atsam_uart_read, - .mode = TERMIOS_POLLED -#endif -}; - -rtems_status_code console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - size_t i; - - rtems_termios_initialize(); - - for (i = 0; i < RTEMS_ARRAY_SIZE(atsam_usart_instances); ++i) { - char usart[] = "/dev/ttyUSARTX"; - - usart[sizeof(usart) - 2] = (char) ('0' + i); - rtems_termios_device_install( - &usart[0], - &atsam_usart_handler, - NULL, - &atsam_usart_instances[i].base - ); - -#if ATSAM_CONSOLE_DEVICE_TYPE == 0 - if (i == ATSAM_CONSOLE_DEVICE_INDEX) { - atsam_usart_instances[i].console = true; - link(&usart[0], CONSOLE_DEVICE_NAME); - } -#endif - } - - for (i = 0; i < RTEMS_ARRAY_SIZE(atsam_uart_instances); ++i) { - char uart[] = "/dev/ttyUARTX"; - - uart[sizeof(uart) - 2] = (char) ('0' + i); - rtems_termios_device_install( - &uart[0], - &atsam_uart_handler, - NULL, - &atsam_uart_instances[i].base - ); - -#if ATSAM_CONSOLE_DEVICE_TYPE == 1 - if (i == ATSAM_CONSOLE_DEVICE_INDEX) { - atsam_uart_instances[i].console = true; - link(&uart[0], CONSOLE_DEVICE_NAME); - } -#endif - } - - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/lib/libbsp/arm/atsam/console/debug-console.c b/c/src/lib/libbsp/arm/atsam/console/debug-console.c deleted file mode 100644 index a405fe9665..0000000000 --- a/c/src/lib/libbsp/arm/atsam/console/debug-console.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2016 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include - -#include -#include -#include - -static void atsam_debug_console_out(char c) -{ - DBG_PutChar((uint8_t) c); -} - -static void atsam_debug_console_init(void) -{ - DBG_Configure(115200, BOARD_MCK); - BSP_output_char = atsam_debug_console_out; -} - -static void atsam_debug_console_early_init(char c) -{ - atsam_debug_console_init(); - atsam_debug_console_out(c); -} - -static int atsam_debug_console_in(void) -{ - return (int) DBG_GetChar(); -} - -BSP_output_char_function_type BSP_output_char = atsam_debug_console_early_init; - -BSP_polling_getchar_function_type BSP_poll_char = atsam_debug_console_in; - -RTEMS_SYSINIT_ITEM( - atsam_debug_console_init, - RTEMS_SYSINIT_BSP_START, - RTEMS_SYSINIT_ORDER_LAST -); diff --git a/c/src/lib/libbsp/arm/beagle/Makefile.am b/c/src/lib/libbsp/arm/beagle/Makefile.am index 079bc3d342..9e351295a3 100644 --- a/c/src/lib/libbsp/arm/beagle/Makefile.am +++ b/c/src/lib/libbsp/arm/beagle/Makefile.am @@ -65,7 +65,7 @@ librtemsbsp_a_SOURCES += irq.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c -librtemsbsp_a_SOURCES += console/console-config.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/beagle/console/console-config.c # I2C librtemsbsp_a_SOURCES += i2c/bbb-i2c.c diff --git a/c/src/lib/libbsp/arm/beagle/console/console-config.c b/c/src/lib/libbsp/arm/beagle/console/console-config.c deleted file mode 100644 index 78af5f6a93..0000000000 --- a/c/src/lib/libbsp/arm/beagle/console/console-config.c +++ /dev/null @@ -1,152 +0,0 @@ -/** - * @file - * - * @ingroup arm_beagle - * - * @brief Console configuration. - */ - -/* - * Copyright (c) 2012 Claas Ziemke. All rights reserved. - * - * Claas Ziemke - * Kernerstrasse 11 - * 70182 Stuttgart - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - * Modified by Ben Gras to make - * interrupt-driven uart i/o work for beagleboards; beaglebone support added. - */ - -#include -#include - -#include - -#include -#include -#include - -#define CONSOLE_UART_THR (*(volatile unsigned int *)BSP_CONSOLE_UART_BASE) -#define CONSOLE_UART_RHR (*(volatile unsigned int *)BSP_CONSOLE_UART_BASE) -#define CONSOLE_UART_LSR (*(volatile unsigned int *)(BSP_CONSOLE_UART_BASE+0x14)) -#define CONSOLE_SYSC (*(volatile uint32_t *) (BSP_CONSOLE_UART_BASE + 0x54)) -#define CONSOLE_SYSS (*(volatile uint32_t *) (BSP_CONSOLE_UART_BASE + 0x58)) - -#define TX_FIFO_E (1<<5) -#define RX_FIFO_E (1<<0) - -static uint8_t beagle_uart_get_register(uintptr_t addr, uint8_t i) -{ - uint8_t v; - volatile uint32_t *reg_r = (volatile uint32_t *) addr + i; - - if(reg_r == (uint32_t*) BSP_CONSOLE_UART_BASE /* reading RHR */ ) { - /* check there should be anything in the RHR before accessing it */ - if(!(CONSOLE_UART_LSR & 0x01)) { - return 0; - } - } - - v = (uint8_t) *reg_r; - - return v; -} - -static void beagle_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val) -{ - volatile uint32_t *reg = (volatile uint32_t *) addr; - - reg [i] = val; -} - -console_tbl Console_Configuration_Ports [] = { - { - .sDeviceName = "/dev/ttyS0", - .deviceType = SERIAL_NS16550, -#if CONSOLE_POLLED /* option to facilitate running the tests */ - .pDeviceFns = &ns16550_fns_polled, -#else - .pDeviceFns = &ns16550_fns, -#endif - .ulMargin = 16, - .ulHysteresis = 8, - .pDeviceParams = (void *) CONSOLE_BAUD, - .ulCtrlPort1 = BSP_CONSOLE_UART_BASE, - .ulDataPort = BSP_CONSOLE_UART_BASE, - .ulIntVector = BSP_CONSOLE_UART_IRQ, - .getRegister = beagle_uart_get_register, - .setRegister = beagle_uart_set_register, - .ulClock = UART_CLOCK, /* 48MHz base clock */ - }, -}; - -unsigned long Console_Configuration_Count = 1; - -static int init_needed = 1; // don't rely on bss being 0 - -static void beagle_console_init(void) -{ - if(init_needed) { - const uint32_t div = UART_CLOCK / 16 / CONSOLE_BAUD; - CONSOLE_SYSC = 2; - while ((CONSOLE_SYSS & 1) == 0) - ; - if ((CONSOLE_LSR & (CONSOLE_LSR_THRE | CONSOLE_LSR_TEMT)) == CONSOLE_LSR_THRE) { - CONSOLE_LCR = 0x83; - CONSOLE_DLL = div; - CONSOLE_DLM = (div >> 8) & 0xff; - CONSOLE_LCR = 0x03; - CONSOLE_ACR = 0x00; - } - - while ((CONSOLE_LSR & CONSOLE_LSR_TEMT) == 0) - ; - - CONSOLE_LCR = 0x80 | 0x03; - CONSOLE_DLL = 0x00; - CONSOLE_DLM = 0x00; - CONSOLE_LCR = 0x03; - CONSOLE_MCR = 0x03; - CONSOLE_FCR = 0x07; - CONSOLE_LCR = 0x83; - CONSOLE_DLL = div; - CONSOLE_DLM = (div >> 8) & 0xff; - CONSOLE_LCR = 0x03; - CONSOLE_ACR = 0x00; - init_needed = 0; - } -} - -#define CONSOLE_THR8 (*(volatile uint8_t *) (BSP_CONSOLE_UART_BASE + 0x00)) - -static void uart_write_polled( char c ) -{ - if(init_needed) beagle_console_init(); - - while( ( CONSOLE_LSR & TX_FIFO_E ) == 0 ) - ; - CONSOLE_THR8 = c; -} - -static void _BSP_put_char( char c ) { - uart_write_polled( c ); -} - -static int _BSP_get_char(void) -{ - if ((CONSOLE_LSR & CONSOLE_LSR_RDR) != 0) { - return CONSOLE_RBR; - } else { - return -1; - } -} - -BSP_output_char_function_type BSP_output_char = _BSP_put_char; - -BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char; diff --git a/c/src/lib/libbsp/arm/csb336/Makefile.am b/c/src/lib/libbsp/arm/csb336/Makefile.am index 04deee4f90..45f9ce342e 100644 --- a/c/src/lib/libbsp/arm/csb336/Makefile.am +++ b/c/src/lib/libbsp/arm/csb336/Makefile.am @@ -30,7 +30,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/cpucounter/cpucounter librtemsbsp_a_SOURCES +=../../../../../../bsps/arm/csb336/clock/clockdrv.c librtemsbsp_a_SOURCES += timer/timer.c # console -librtemsbsp_a_SOURCES += console/uart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/csb336/console/uart.c # IRQ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c librtemsbsp_a_SOURCES += irq/irq.c diff --git a/c/src/lib/libbsp/arm/csb336/console/uart.c b/c/src/lib/libbsp/arm/csb336/console/uart.c deleted file mode 100644 index 8d8a0c1ed0..0000000000 --- a/c/src/lib/libbsp/arm/csb336/console/uart.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Console driver for MC9328XML UARTs. - * - * Written Jay Monkman - * Copyright (c) 2005 by Loping Dog Embedded Systems - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Define this to use interrupt driver UART driver */ -#define USE_INTERRUPTS 1 - -/* How many serial ports? */ -#define NUM_DEVS 2 -#define poll_write(c) imx_uart_poll_write_char(0, c) -#define poll_read() imx_uart_poll_read_char(0) - -static int imx_uart_first_open(int, int, void *); -static int imx_uart_last_close(int, int, void *); -static int imx_uart_poll_read(int); -static int imx_uart_set_attrs(int, const struct termios *); -static void imx_uart_init(int minor); -static void imx_uart_set_baud(int, int); -static ssize_t imx_uart_poll_write(int, const char *, size_t); -static int imx_uart_poll_read_char(int minor); -static void imx_uart_poll_write_char(int minor, char c); -static void _BSP_output_char(char c); -static int _BSP_poll_char(void); - -#if USE_INTERRUPTS -static void imx_uart_tx_isr(void *); -static void imx_uart_rx_isr(void *); -static void imx_uart_isr_on(rtems_vector_number); -static void imx_uart_isr_off(rtems_vector_number); -static ssize_t imx_uart_intr_write(int, const char *, size_t); -static rtems_vector_number imx_uart_name_transmit(int minor); -static rtems_vector_number imx_uart_name_receive(int minor); -#endif - -/* TERMIOS callbacks */ -#if USE_INTERRUPTS -rtems_termios_callbacks imx_uart_cbacks = { - .firstOpen = imx_uart_first_open, - .lastClose = imx_uart_last_close, - .pollRead = NULL, - .write = imx_uart_intr_write, - .setAttributes = imx_uart_set_attrs, - .stopRemoteTx = NULL, - .startRemoteTx = NULL, - .outputUsesInterrupts = 1, -}; -#else -rtems_termios_callbacks imx_uart_cbacks = { - .firstOpen = imx_uart_first_open, - .lastClose = imx_uart_last_close, - .pollRead = imx_uart_poll_read, - .write = imx_uart_poll_write, - .setAttributes = imx_uart_set_attrs, - .stopRemoteTx = NULL, - .startRemoteTx = NULL, - .outputUsesInterrupts = 0, -}; -#endif - -typedef struct { - int minor; - mc9328mxl_uart_regs_t * regs; - volatile const char *buf; - volatile int len; - volatile int idx; - void *tty; -} imx_uart_data_t; - -static imx_uart_data_t imx_uart_data[NUM_DEVS]; - -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - int i; - - for (i = 0; i < NUM_DEVS; i++) { - imx_uart_init(i); - } - - rtems_termios_initialize(); - - /* /dev/console and /dev/tty0 are the same */ - status = rtems_io_register_name("/dev/console", major, 0); - if (status != RTEMS_SUCCESSFUL) { - rtems_panic("%s:%d Error registering /dev/console :: %d\n", - __FUNCTION__, __LINE__, status); - } - - status = rtems_io_register_name("/dev/tty0", major, 0); - if (status != RTEMS_SUCCESSFUL) { - rtems_panic("%s:%d Error registering /dev/tty0 :: %d\n", - __FUNCTION__, __LINE__, status); - } - - status = rtems_io_register_name("/dev/tty1", major, 1); - if (status != RTEMS_SUCCESSFUL) { - rtems_panic("%s:%d Error registering /dev/tty1 :: %d\n", - __FUNCTION__, __LINE__, status); - } - return RTEMS_SUCCESSFUL; -} - -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_status_code rc; - - if (minor > (NUM_DEVS - 1)) { - return RTEMS_INVALID_NUMBER; - } - - rc = rtems_termios_open(major, minor, arg, &imx_uart_cbacks); - - return rc; -} - -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_close(arg); -} - -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_read(arg); -} - -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_write(arg); -} - -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_ioctl(arg); -} - -static void imx_uart_init(int minor) -{ - imx_uart_data[minor].minor = minor; - imx_uart_data[minor].buf = NULL; - imx_uart_data[minor].len = 0; - imx_uart_data[minor].idx = 0; - - if (minor == 0) { - imx_uart_data[minor].regs = - (mc9328mxl_uart_regs_t *) MC9328MXL_UART1_BASE; - } else if (minor == 1) { - imx_uart_data[minor].regs = - (mc9328mxl_uart_regs_t *) MC9328MXL_UART2_BASE; - } else { - rtems_panic("%s:%d Unknown UART minor number %d\n", - __FUNCTION__, __LINE__, minor); - } - - imx_uart_data[minor].regs->cr1 = ( - MC9328MXL_UART_CR1_UARTCLKEN | - MC9328MXL_UART_CR1_UARTEN); - - imx_uart_data[minor].regs->cr2 = ( - MC9328MXL_UART_CR2_IRTS | - MC9328MXL_UART_CR2_WS | - MC9328MXL_UART_CR2_TXEN | - MC9328MXL_UART_CR2_RXEN | - MC9328MXL_UART_CR2_SRST); - - imx_uart_data[minor].regs->cr3 = 0; - - imx_uart_data[minor].regs->cr4 = 0; - - imx_uart_data[minor].regs->fcr = ( - MC9328MXL_UART_FCR_TXTL(32) | - MC9328MXL_UART_FCR_RFDIV_1 | - MC9328MXL_UART_FCR_RXTL(1)); - - imx_uart_set_baud(minor, 38400); - -} - -static int imx_uart_first_open(int major, int minor, void *arg) -{ - rtems_libio_open_close_args_t *args = arg; - rtems_status_code status = RTEMS_SUCCESSFUL; - - imx_uart_data[minor].tty = args->iop->data1; - -#if USE_INTERRUPTS - status = rtems_interrupt_handler_install( - imx_uart_name_transmit(minor), - "UART", - RTEMS_INTERRUPT_UNIQUE, - imx_uart_tx_isr, - &imx_uart_data[minor] - ); - assert(status == RTEMS_SUCCESSFUL); - imx_uart_isr_on(imx_uart_name_transmit(minor)); - - status = rtems_interrupt_handler_install( - imx_uart_name_receive(minor), - "UART", - RTEMS_INTERRUPT_UNIQUE, - imx_uart_rx_isr, - &imx_uart_data[minor] - ); - assert(status == RTEMS_SUCCESSFUL); - imx_uart_isr_on(imx_uart_name_receive(minor)); - - imx_uart_data[minor].regs->cr1 |= MC9328MXL_UART_CR1_RRDYEN; -#endif - - return 0; -} - -static int imx_uart_last_close(int major, int minor, void *arg) -{ -#if USE_INTERRUPTS - rtems_status_code status = RTEMS_SUCCESSFUL; - - imx_uart_isr_off(imx_uart_name_transmit(minor)); - status = rtems_interrupt_handler_remove( - imx_uart_name_transmit(minor), - imx_uart_tx_isr, - &imx_uart_data[minor] - ); - assert(status == RTEMS_SUCCESSFUL); - - imx_uart_isr_off(imx_uart_name_receive(minor)); - status = rtems_interrupt_handler_remove( - imx_uart_name_receive(minor), - imx_uart_rx_isr, - &imx_uart_data[minor] - ); - assert(status == RTEMS_SUCCESSFUL); -#endif - - return 0; -} - -static int imx_uart_poll_read(int minor) -{ - if (imx_uart_data[minor].regs->sr2 & MC9328MXL_UART_SR2_RDR) { - return imx_uart_data[minor].regs->rxd & 0xff; - } else { - return -1; - } -} - - -static ssize_t imx_uart_poll_write(int minor, const char *buf, size_t len) -{ - int i; - for (i = 0; i < len; i++) { - /* Wait for there to be room in the fifo */ - while (!(imx_uart_data[minor].regs->sr2 & MC9328MXL_UART_SR2_TXDC)) { - continue; - } - - imx_uart_data[minor].regs->txd = buf[i]; - } - return 1; - -} - -#if USE_INTERRUPTS -static ssize_t imx_uart_intr_write(int minor, const char *buf, size_t len) -{ - if (len > 0) { - imx_uart_data[minor].buf = buf; - imx_uart_data[minor].len = len; - imx_uart_data[minor].idx = 0; - - imx_uart_data[minor].regs->cr1 |= MC9328MXL_UART_CR1_TXMPTYEN; - } - - return 1; -} -#endif - - -/* This is for setting baud rate, bits, etc. */ -static int imx_uart_set_attrs(int minor, const struct termios *t) -{ - int baud; - - baud = rtems_termios_baud_to_number(t->c_ospeed); - imx_uart_set_baud(minor, baud); - - return 0; -} - -#if USE_INTERRUPTS -static void imx_uart_isr_on(rtems_vector_number name) -{ - MC9328MXL_AITC_INTENNUM = name; -} -static void imx_uart_isr_off(rtems_vector_number name) -{ - MC9328MXL_AITC_INTDISNUM = name; -} - -static void imx_uart_rx_isr(void * param) -{ - imx_uart_data_t *uart_data = param; - char buf[32]; - int i=0; - - while (uart_data->regs->sr2 & MC9328MXL_UART_SR2_RDR) { - buf[i] = uart_data->regs->rxd & 0xff; - i++; - } - - rtems_termios_enqueue_raw_characters(uart_data->tty, buf, i); -} - -static void imx_uart_tx_isr(void * param) -{ - imx_uart_data_t *uart_data = param; - int len; - int minor = uart_data->minor; - - - if (uart_data->idx < uart_data->len) { - while ( (uart_data->regs->sr1 & MC9328MXL_UART_SR1_TRDY) && - (uart_data->idx < uart_data->len)) { - uart_data->regs->txd = uart_data->buf[uart_data->idx]; - uart_data->idx++; - } - } else { - len = uart_data->len; - uart_data->len = 0; - imx_uart_data[minor].regs->cr1 &= ~MC9328MXL_UART_CR1_TXMPTYEN; - rtems_termios_dequeue_characters(uart_data->tty, len); - } -} - -static rtems_vector_number imx_uart_name_transmit(int minor) -{ - if (minor == 0) { - return BSP_INT_UART1_TX; - } else if (minor == 1) { - return BSP_INT_UART2_TX; - } - - assert(0); -} - -static rtems_vector_number imx_uart_name_receive(int minor) -{ - if (minor == 0) { - return BSP_INT_UART1_RX; - } else if (minor == 1) { - return BSP_INT_UART2_RX; - } - - assert(0); -} -#endif - -/* - * Set the UART's baud rate. The calculation is: - * (baud * 16) / ref_freq = num/demom - * - * ref_freq = perclk1 / RFDIV[2:0] - * BIR = num - 1 - * BMR = demom - 1 - * - * Setting 'num' to 16 yields this equation: - * demom = ref_freq / baud - */ -static void imx_uart_set_baud(int minor, int baud) -{ - unsigned int perclk1; - unsigned int denom; - unsigned int ref_freq = 0; - uint32_t fcr; - - perclk1 = get_perclk1_freq(); - fcr = imx_uart_data[minor].regs->fcr; - - switch(fcr & MC9328MXL_UART_FCR_RFDIV_MASK) { - case MC9328MXL_UART_FCR_RFDIV_1: ref_freq = perclk1/1; break; - case MC9328MXL_UART_FCR_RFDIV_2: ref_freq = perclk1/2; break; - case MC9328MXL_UART_FCR_RFDIV_3: ref_freq = perclk1/3; break; - case MC9328MXL_UART_FCR_RFDIV_4: ref_freq = perclk1/4; break; - case MC9328MXL_UART_FCR_RFDIV_5: ref_freq = perclk1/5; break; - case MC9328MXL_UART_FCR_RFDIV_6: ref_freq = perclk1/6; break; - case MC9328MXL_UART_FCR_RFDIV_7: ref_freq = perclk1/7; break; - default: - rtems_panic("%s:%d Unknown RFDIV: 0x%" PRIx32, - __FUNCTION__, __LINE__, - fcr & MC9328MXL_UART_FCR_RFDIV_MASK); - break; - } - - denom = ref_freq / baud; - - imx_uart_data[minor].regs->bir = 0xf; - imx_uart_data[minor].regs->bmr = denom; -} - - -/* - * Polled, non-blocking read from UART - */ -static int imx_uart_poll_read_char(int minor) -{ - return imx_uart_poll_read(minor); -} - -/* - * Polled, blocking write from UART - */ -static void imx_uart_poll_write_char(int minor, char c) -{ - imx_uart_poll_write(minor, &c, 1); -} - -/* - * Functions for printk() and friends. - */ -static void _BSP_output_char(char c) -{ - poll_write(c); -} - -BSP_output_char_function_type BSP_output_char = _BSP_output_char; - -static int _BSP_poll_char(void) -{ - return poll_read(); -} - -BSP_polling_getchar_function_type BSP_poll_char = _BSP_poll_char; - - diff --git a/c/src/lib/libbsp/arm/csb337/Makefile.am b/c/src/lib/libbsp/arm/csb337/Makefile.am index 23a87975bb..523f4a5523 100644 --- a/c/src/lib/libbsp/arm/csb337/Makefile.am +++ b/c/src/lib/libbsp/arm/csb337/Makefile.am @@ -43,15 +43,15 @@ librtemsbsp_a_SOURCES += timer/timer.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c -librtemsbsp_a_SOURCES += console/uarts.c -librtemsbsp_a_SOURCES += console/dbgu.c -librtemsbsp_a_SOURCES += console/usart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/csb337/console/uarts.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/csb337/console/dbgu.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/csb337/console/usart.c # IRQ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c librtemsbsp_a_SOURCES += irq/irq.c if ENABLE_LCD -librtemsbsp_a_SOURCES += console/sed1356.c -librtemsbsp_a_SOURCES += console/fbcons.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/csb337/console/sed1356.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/csb337/console/fbcons.c endif # umon if ENABLE_UMON diff --git a/c/src/lib/libbsp/arm/csb337/console/dbgu.c b/c/src/lib/libbsp/arm/csb337/console/dbgu.c deleted file mode 100644 index 1a16762e32..0000000000 --- a/c/src/lib/libbsp/arm/csb337/console/dbgu.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Console driver for AT91RM9200 DBGU port - * - * This driver uses the shared console driver in - * ...../libbsp/shared/console.c - * - * Copyright (c) 2003 by Cogent Computer Systems - * Written by Mike Kelly - * and Jay Monkman - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -volatile int dbg_dly; - -/* static function prototypes */ -static int dbgu_first_open(int major, int minor, void *arg); -static int dbgu_last_close(int major, int minor, void *arg); -static int dbgu_read(int minor); -static ssize_t dbgu_write(int minor, const char *buf, size_t len); -static void dbgu_init(int minor); -static void dbgu_write_polled(int minor, char c); -static int dbgu_set_attributes(int minor, const struct termios *t); - -/* Pointers to functions for handling the UART. */ -const console_fns dbgu_fns = -{ - libchip_serial_default_probe, - dbgu_first_open, - dbgu_last_close, - dbgu_read, - dbgu_write, - dbgu_init, - dbgu_write_polled, /* not used in this driver */ - dbgu_set_attributes, - FALSE /* TRUE if interrupt driven, FALSE if not. */ -}; -/*********************************************************************/ -/* Functions called via callbacks (i.e. the ones in uart_fns */ -/*********************************************************************/ - -/* - * This is called the first time each device is opened. Since - * the driver is polled, we don't have to do anything. If the driver - * were interrupt driven, we'd enable interrupts here. - */ -static int dbgu_first_open(int major, int minor, void *arg) -{ - return 0; -} - - -/* - * This is called the last time each device is closed. Since - * the driver is polled, we don't have to do anything. If the driver - * were interrupt driven, we'd disable interrupts here. - */ -static int dbgu_last_close(int major, int minor, void *arg) -{ - return 0; -} - - -/* - * Read one character from UART. - * - * return -1 if there's no data, otherwise return - * the character in lowest 8 bits of returned int. - */ -static int dbgu_read(int minor) -{ - char c; - console_tbl *console_entry; - at91rm9200_dbgu_regs_t *dbgu; - - console_entry = BSP_get_uart_from_minor(minor); - - if (console_entry == NULL) { - return -1; - } - - dbgu = (at91rm9200_dbgu_regs_t *)console_entry->ulCtrlPort1; - - if (!(dbgu->sr & DBGU_INT_RXRDY)) { - return -1; - } - - c = dbgu->rhr & 0xff; - - return c; -} - - -/* - * Write buffer to UART - * - * return 1 on success, -1 on error - */ -static ssize_t dbgu_write(int minor, const char *buf, size_t len) -{ - int i, x; - char c; - console_tbl *console_entry; - at91rm9200_dbgu_regs_t *dbgu; - - console_entry = BSP_get_uart_from_minor(minor); - - if (console_entry == NULL) { - return -1; - } - - dbgu = (at91rm9200_dbgu_regs_t *)console_entry->ulCtrlPort1; - - for (i = 0; i < len; i++) { - /* Wait for fifo to have room */ - while(1) { - if (dbgu->sr & DBGU_INT_TXRDY) { - break; - } - } - - c = (char) buf[i]; - dbgu->thr = c; - - /* the TXRDY flag does not seem to update right away (is this true?) */ - /* so we wait a bit before continuing */ - for (x = 0; x < 100; x++) { - dbg_dly++; /* using a global so this doesn't get optimized out */ - } - } - - return 1; -} - - -/* Set up the UART. */ -static void dbgu_init(int minor) -{ - console_tbl *console_entry; - at91rm9200_dbgu_regs_t *dbgu; - - console_entry = BSP_get_uart_from_minor(minor); - - if (console_entry == NULL) { - return; - } - - dbgu = (at91rm9200_dbgu_regs_t *)console_entry->ulCtrlPort1; - - /* Clear error bits, and reset */ - dbgu->cr = (DBGU_CR_RSTSTA | DBGU_CR_RSTTX | DBGU_CR_RSTRX); - - /* Clear pending interrupts */ - dbgu->idr = DBGU_INT_ALL; - dbgu->imr = 0; - - /* Set port to no parity, no loopback */ - dbgu->mr = DBGU_MR_PAR_NONE | DBGU_MR_CHMODE_NORM; - - /* Set the baud rate */ - dbgu->brgr = (at91rm9200_get_mck() / 16) / BSP_get_baud(); - - /* Enable the DBGU */ - dbgu->cr = (DBGU_CR_TXEN | DBGU_CR_RXEN); -} - -/* This is used for getchark support */ -static void dbgu_write_polled(int minor, char c) -{ - dbgu_write(minor, &c, 1); -} - -/* This is for setting baud rate, bits, etc. */ -static int dbgu_set_attributes(int minor, const struct termios *t) -{ - return 0; -} - -/***********************************************************************/ -/* - * The following functions are not used by TERMIOS, but other RTEMS - * functions use them instead. - */ -/***********************************************************************/ -/* - * Read from UART. This is used in the exit code, and can't - * rely on interrupts. - */ -static int dbgu_poll_read(int minor) -{ - return dbgu_read(minor); -} - - -/* - * Write a character to the console. This is used by printk() and - * maybe other low level functions. It should not use interrupts or any - * RTEMS system calls. It needs to be very simple - */ -static void _BSP_put_char( char c ) { - dbgu_write_polled(0, c); -} - -BSP_output_char_function_type BSP_output_char = _BSP_put_char; - -static int _BSP_poll_char(void) -{ - return dbgu_poll_read(0); -} - -BSP_polling_getchar_function_type BSP_poll_char = _BSP_poll_char; diff --git a/c/src/lib/libbsp/arm/csb337/console/fbcons.c b/c/src/lib/libbsp/arm/csb337/console/fbcons.c deleted file mode 100644 index 62e840938d..0000000000 --- a/c/src/lib/libbsp/arm/csb337/console/fbcons.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * LCD Console Output Driver for CSBx37 - */ - -/* - * COPYRIGHT (c) 1989-2014. - * On-Line Applications Research Corporation (OAR). - * - * Modified by Fernando Nicodemos - * from NCB - Sistemas Embarcados Ltda. (Brazil) - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include - -#include -#include -#include -#include "sed1356.h" - -/* static function prototypes */ -static int fbcons_first_open(int major, int minor, void *arg); -static int fbcons_last_close(int major, int minor, void *arg); -static int fbcons_read(int minor); -static ssize_t fbcons_write(int minor, const char *buf, size_t len); -static void fbcons_init(int minor); -static void fbcons_write_polled(int minor, char c); -static int fbcons_set_attributes(int minor, const struct termios *t); - -/* Pointers to functions for handling the UART. */ -const console_fns fbcons_fns = -{ - libchip_serial_default_probe, - fbcons_first_open, - fbcons_last_close, - fbcons_read, - fbcons_write, - fbcons_init, - fbcons_write_polled, /* not used in this driver */ - fbcons_set_attributes, - FALSE /* TRUE if interrupt driven, FALSE if not. */ -}; -/*********************************************************************/ -/* Functions called via callbacks (i.e. the ones in uart_fns */ -/*********************************************************************/ - -/* - * This is called the first time each device is opened. Since - * the driver is polled, we don't have to do anything. If the driver - * were interrupt driven, we'd enable interrupts here. - */ -static int fbcons_first_open(int major, int minor, void *arg) -{ - /* printk( "Frame buffer -- first open\n" ); */ - return 0; -} - - -/* - * This is called the last time each device is closed. Since - * the driver is polled, we don't have to do anything. If the driver - * were interrupt driven, we'd disable interrupts here. - */ -static int fbcons_last_close(int major, int minor, void *arg) -{ - /* printk( "Frame buffer -- last close\n" ); */ - return 0; -} - - -/* - * Read one character from UART. - * - * return -1 if there's no data, otherwise return - * the character in lowest 8 bits of returned int. - */ -static int fbcons_read(int minor) -{ - /* printk( "Frame buffer -- read\n" ); */ - return -1; -} - - -/* - * Write buffer to LCD - * - * return 1 on success, -1 on error - */ -static ssize_t fbcons_write(int minor, const char *buf, size_t len) -{ - int i; - - /* printk( "Frame buffer -- write\n" ); */ - for ( i=0 ; i from NCB - Sistemas - * Embarcados Ltda. (Brazil) to be more compliant with RTEMS coding - * standards and to eliminate C++ style comments. - */ - -#include - -#include -#include -#include "sed1356.h" -#include "font8x16.h" - -int mode900lq; -long PIXELS_PER_ROW; -long PIXELS_PER_COL; -long COLS_PER_SCREEN; -long ROWS_PER_SCREEN; -long SED_HOR_PULSE_WIDTH_LCD; -long SED_VER_PULSE_START_LCD; -long SED_HOR_PULSE_START_LCD; -long SED_HOR_NONDISP_LCD; -long SED_VER_NONDISP_LCD; -long SED_VER_PULSE_WIDTH_LCD; - -/* globals to keep track of foreground, background colors and x,y position */ -int sed_color_depth; /* 4, 8 or 16 */ -int sed_fg_color; /* 0 to 15, used as lookup into VGA color table */ -int sed_bg_color; /* 0 to 15, used as lookup into VGA color table */ -int sed_col; /* current column, 0 to COLS_PER_SCREEN - 1 */ -int sed_row; /* current row, 0 to (ROWS_PER_SCREEN * 2) - 1 */ -int sed_disp_mode_crt; /* CRT=1, LCD=0 */ -int sed135x_ok; -int sed135x_tst; -uint32_t sed_fb_offset; /* current offset into frame buffer for sed_putchar */ - -void sed_writechar(uint8_t c); -void sed_scroll(void); - -#define SED_REG_BASE 0x30000000 /* *CS2 */ -#define SED_MEM_BASE (SED_REG_BASE + 0x00200000) -#define SED_STEP 1 /* 16-bit port on 16-bit boundry */ - -#define SED_REG16(_x_) *(volatile uint16_t *)((uint32_t)SED_REG_BASE + (((uint32_t)_x_ * SED_STEP) ^ 0)) /* Control/Status Registers, 16-bit mode */ -#define RD_FB16(_reg_,_val_) ((_val_) = *((volatile uint16_t *)(((uint32_t)SED_MEM_BASE + ((uint32_t)(_reg_ * SED_STEP) ^ 0))))) -#define WR_FB16(_reg_,_val_) (*((volatile uint16_t *)(((uint32_t)SED_MEM_BASE + ((uint32_t)(_reg_ * SED_STEP) ^ 0)))) = (_val_)) - -#if 0 -#define SED1356_REG_LCD_HOR_DISP SED_REG16(0x32) -#define SED1356_REG_LCD_HOR_NONDISP_and_START SED_REG16(0x34) -#define SED1356_REG_LCD_HOR_PULSE SED_REG16(0x36) -#define SED1356_REG_LCD_VER_DISP_HT_LO_and_HI SED_REG16(0x38) -#define SED1356_REG_LCD_VER_NONDISP_and_START SED_REG16(0x3a) -#define SED1356_REG_LCD_VER_PULSE SED_REG16(0x3c) -#define SED1356_REG_LCD_DISP_MODE_and_MISC SED_REG16(0x40) -#define SED1356_REG_LCD_DISP_START_LO_and_MID SED_REG16(0x42) -#define SED1356_REG_LCD_DISP_START_HI SED_REG16(0x44) -#define SED1356_REG_LCD_ADD_OFFSET_LO_and_HI SED_REG16(0x46) -#define SED1356_REG_LCD_PIXEL_PAN SED_REG16(0x48) -#define SED1356_REG_LCD_FIFO_THRESH_LO_and_HI SED_REG16(0x4a) -#endif - - -#define H2SED(_x_) (_x_) - -#define FB_SIZE (640 * 480) -#define SED_ROW_SIZE(_depth_) ((PIXELS_PER_ROW * _depth_) / 8) -#define SED_FB_SIZE(_depth_) (((PIXELS_PER_COL * PIXELS_PER_ROW) * _depth_) / 8) - -#define FONT_WIDTH 8 -#define FONT_HEIGHT 16 - -#define SED_GET_ADD(_row_, _col_, _depth_) \ - (((((_row_ * PIXELS_PER_ROW) * FONT_HEIGHT) \ - + (_col_ * FONT_WIDTH)) \ - * _depth_) / 8) - - -#define SED_GET_PHYS_ADD(_reg_) \ - (volatile unsigned long)(SED_MEM_BASE + ((_reg_ * SED_STEP) ^ 0)) - - -#include "sed1356_16bit.h" - -/* #define SED_DBG */ -int sed135x_tst = 0; - -void sed_write_frame_buffer( - uint32_t i, - uint16_t wr16 -) -{ - WR_FB16(i, wr16); -} - -int sed_frame_buffer_size(void) -{ - return SED_FB_SIZE(sed_color_depth); -} - -void sed_clr_row(int char_row) -{ - unsigned long sed_mem_add; - int i; - uint16_t wr16; - - /* clear the desired row */ - sed_mem_add = SED_GET_ADD(char_row, 0, sed_color_depth); - -#ifdef SED_DBG - sed135x_tst = 1; - printf("SED Clear Row %d, FB Add 0x%08lx, CPU Add 0x%08lx.\n ", char_row, sed_mem_add, SED_GET_PHYS_ADD(sed_mem_add)); - sed135x_tst = 0; -#endif - - switch (sed_color_depth) - { - case 4: - wr16 = ((sed_bg_color << 12) | (sed_bg_color << 8) | (sed_bg_color << 4) | (sed_bg_color << 0)); -#ifdef SED_DBG - sed135x_tst = 1; - printf("SED Clear Row %d, FB Add 0x%08lx to 0x%08lx.\n ", char_row, sed_mem_add, sed_mem_add + ((PIXELS_PER_ROW * FONT_HEIGHT) / 2)); - sed135x_tst = 0; -#endif - for (i = 0; i < ((PIXELS_PER_ROW * FONT_HEIGHT) / 2); i += 2){ - WR_FB16(sed_mem_add, wr16); - sed_mem_add += 2; - } /* for font_row */ - break; - case 8: - wr16 = ((sed_bg_color << 8) | (sed_bg_color << 0)); - for (i = 0; i < (PIXELS_PER_ROW * FONT_HEIGHT); i += 2){ - WR_FB16(sed_mem_add, wr16); - sed_mem_add += 2; - } /* for font_row */ - break; - case 16: - wr16 = ((vga_lookup[sed_bg_color])); - for (i = 0; i < ((PIXELS_PER_ROW * FONT_HEIGHT) * 2); i += 2){ - WR_FB16(sed_mem_add, wr16); - sed_mem_add += 2; - } /* for font_row */ - break; - } /* switch sed_color_depth */ -} /* sed_clr_row */ - -void sed_init(void) -{ - mode900lq = 0; - PIXELS_PER_ROW = 640; - PIXELS_PER_COL = 480; - COLS_PER_SCREEN = 80; - ROWS_PER_SCREEN = 30; - SED_HOR_PULSE_WIDTH_LCD = 0x0b; - SED_HOR_NONDISP_LCD = 0x13; - SED_VER_PULSE_WIDTH_LCD = 0x01; - SED_VER_PULSE_START_LCD = 0x09; - SED_VER_NONDISP_LCD = 0x2c; - - sed_color_depth = 16; /* 16 => vga lookup */ - sed_fg_color = 14; /* Bright Yellow */ - sed_bg_color = 1; /* Blue */ - sed_disp_mode_crt = 0; /* default to LCD */ - sed_fb_offset = 0x00; - sed_row = 0; - sed_col = 0; - - sed135x_ok = 1; - sed135x_tst = 0; - sed_clearscreen(); -} - -/* - * sed_putchar() - * - * This routine parses the character and calls sed_writechar if it is a - * printable character - */ -void sed_putchar(char c) -{ - - if ((sed135x_ok == 0) || (sed135x_tst == 1)) return; - - /* First parse the character to see if it printable or an - * acceptable control character. - */ - switch (c) { - case '\r': - sed_col = 0; - return; - case '\n': - sed_col = 0; - sed_scroll(); - return; - case '\b': - sed_col--; - if (sed_col < 0) { - sed_row--; - if (sed_row < 0) - sed_row = 0; - sed_col = COLS_PER_SCREEN - 1; - } - c = 0; /* erase the character */ - sed_writechar(c); - break; - default: - if (((uint8_t)c < FIRST_CHAR) || ((uint8_t)c > LAST_CHAR)) - return; /* drop anything we can't print */ - c -= FIRST_CHAR; /* get aligned to the first printable character */ - sed_writechar(c); - /* advance to next column */ - sed_col++; - if (sed_col == COLS_PER_SCREEN) { - sed_col = 0; - sed_scroll(); - } - break; - } - -} /* sed_putchar() */ - -/* - * sed_writechar() - * - * This routine writes the character to the screen at the current cursor - * location. - */ -void sed_writechar(uint8_t c) -{ - uint32_t sed_mem_add; - int font_row, font_col; - uint8_t font_data8; - uint16_t wr16; - - /* Convert the current row,col and color depth values - * into an address - */ - sed_mem_add = SED_GET_ADD(sed_row, sed_col, sed_color_depth); - -#ifdef SED_DBG - sed135x_tst = 1; - printf("SED writechar at row %d, col %d, FB Add 0x%08lx, CPU Add 0x%08lx.\n ", sed_row, sed_col, sed_mem_add, SED_GET_PHYS_ADD(sed_mem_add)); - sed135x_tst = 0; -#endif - - if (FONT_WIDTH == 8) { - switch (sed_color_depth) { - case 4: - /* Now render the font by painting one font row at a time */ - for (font_row = 0; font_row < FONT_HEIGHT; font_row++) { - /* get the font row of data */ - font_data8 = font8x16[(c * FONT_HEIGHT) + font_row]; - - - for (font_col = 0; font_col < 8; font_col += 4) - { - /* get a words worth of pixels */ - wr16 = (((font_data8 & 0x80) ? sed_fg_color << 12 : sed_bg_color << 12) - | ((font_data8 & 0x40) ? sed_fg_color << 8 : sed_bg_color << 8) - | ((font_data8 & 0x20) ? sed_fg_color << 4 : sed_bg_color << 4) - | ((font_data8 & 0x10) ? sed_fg_color << 0 : sed_bg_color << 0)); - font_data8 = font_data8 << 4; - WR_FB16(sed_mem_add, wr16); - /* if we are in the 2nd frame buffer, write to the 1st - * frame buffer also - */ - if (sed_row > (ROWS_PER_SCREEN - 1)) { - WR_FB16((sed_mem_add - SED_FB_SIZE(sed_color_depth)), wr16); - } - sed_mem_add += 2; - } /* for font_col */ - /* go to the next pixel row */ - sed_mem_add += (SED_ROW_SIZE(sed_color_depth) - ((FONT_WIDTH * sed_color_depth) / 8)); - } /* for font_row */ - break; - - case 8: - /* Now render the font by painting one font row at a time */ - for (font_row = 0; font_row < FONT_HEIGHT; font_row++) { - /* get the font row of data */ - font_data8 = font8x16[(c * FONT_HEIGHT) + font_row]; - for (font_col = 0; font_col < 8; font_col += 2) - { - /* get a words worth of pixels */ - wr16 = (((font_data8 & 0x80) ? sed_fg_color << 8 : sed_bg_color << 8) - | ((font_data8 & 0x40) ? sed_fg_color << 0 : sed_bg_color << 0)); - font_data8 = font_data8 << 2; - WR_FB16(sed_mem_add, wr16); - /* if we are in the 2nd frame buffer, write to the 1st - * frame buffer also - */ - if (sed_row > (ROWS_PER_SCREEN - 1)) { - WR_FB16((sed_mem_add - SED_FB_SIZE(sed_color_depth)), wr16); - } - sed_mem_add += 2; - } /* for font_col */ - /* go to the next pixel row */ - sed_mem_add += (SED_ROW_SIZE(sed_color_depth) - ((FONT_WIDTH * sed_color_depth) / 8)); - } /* for font_row */ - break; - - case 16: - /* Now render the font by painting one font row at a time */ - for (font_row = 0; font_row < FONT_HEIGHT; font_row++) { - /* get the font row of data */ - font_data8 = font8x16[(c * FONT_HEIGHT) + font_row]; - for (font_col = 0; font_col < 8; font_col++) - { - /* get a words worth of pixels */ - wr16 = ((font_data8 & 0x80) ? - vga_lookup[sed_fg_color] : vga_lookup[sed_bg_color]); - font_data8 = font_data8 << 1; - WR_FB16(sed_mem_add, wr16); - /* if we are in the 2nd frame buffer, write to the 1st - * frame buffer also. - */ - if (sed_row > (ROWS_PER_SCREEN - 1)) { - WR_FB16((sed_mem_add - SED_FB_SIZE(sed_color_depth)), wr16); - } - sed_mem_add += 2; - } /* for font_col */ - /* go to the next pixel row */ - sed_mem_add += (SED_ROW_SIZE(sed_color_depth) - ((FONT_WIDTH * sed_color_depth) / 8)); - } /* for font_row */ - break; - - } /* switch sed_color depth */ - } /* FONT_WIDTH == 8 */ - else - { - return; - } -} /* sed_writechar() */ - -static void sed_update_fb_offset(void) -{ - /* write the new sed_fb_offset value */ - if (sed_disp_mode_crt) { - /* before we change the address offset, wait for the display to - * go from active to non-active, unless the display is not enabled - */ - if (SED1356_REG_DISP_MODE & H2SED(SED1356_DISP_MODE_CRT)) { /* CRT is on */ - while ((SED1356_REG_CRT_VER_NONDISP_and_START & H2SED(SED1356_VER_NONDISP)) == 0) {} - while ((SED1356_REG_CRT_VER_NONDISP_and_START & H2SED(SED1356_VER_NONDISP)) == 1) {} - } - SED1356_REG_CRT_DISP_START_LO_and_MID = H2SED(((sed_fb_offset & 0x00ffff) >> 0)); - SED1356_REG_CRT_DISP_START_HI = H2SED(((sed_fb_offset & 0x070000) >> 16)); - } - else /* LCD */ - { - if (SED1356_REG_DISP_MODE & H2SED(SED1356_DISP_MODE_LCD)) { /* LCD is on */ - while ((SED1356_REG_LCD_VER_NONDISP_and_START & H2SED(SED1356_VER_NONDISP)) == 0) {} - while ((SED1356_REG_LCD_VER_NONDISP_and_START & H2SED(SED1356_VER_NONDISP)) == 1) {} - } - SED1356_REG_LCD_DISP_START_LO_and_MID = H2SED(((sed_fb_offset & 0x00ffff) >> 0)); - SED1356_REG_LCD_DISP_START_HI = H2SED(((sed_fb_offset & 0x070000) >> 16)); - } -} - -/* sed_scroll() - * - * Because we are most likely running out of FLASH and probably also with - * cache disabled, a brute force memcpy of the whole screen would be very - * slow, even with reduced color depths. Instead, we define a frame buffer - * that is twice the size of our actual display. This does limit us to a - * 1Mbyte active display size, but 640 x 480 @ 16-bits/pixel = 614K so it - * works just fine. 800 x 600 can be had by reducing the color depth to - * 8-bits/pixel and using the look up tables. - * - * With the double buffering, we always write to the first buffer, even - * when the second buffer is active. This allows us to scroll by adjusting - * the starting and ending addresses in the SED135x by one row. When we - * reach the end of our virtual buffer, we reset the starting and ending - * addresses to the first buffer. Note that we can not adjust the SED135x - * registers until it is in vertical retrace. That means we have to wait - * until it is in active display, then goes to non-display, unless the - * screen is blanked, in which case we can update immediately. - */ -void sed_scroll(void) -{ - sed_row++; - - /* clear the new row(s) */ - sed_clr_row(sed_row); - if (sed_row > (ROWS_PER_SCREEN - 1)) { - sed_clr_row(sed_row - ROWS_PER_SCREEN); - } - /* when sed_y_pos is greater than ROWS_PER_SCREEN we just adjust the - * start and end addresses in the SED135x. If it is equal to 2 * - * ROWS_PER_SCREEN, we reset the start and end addresses to SED_MEM_BASE. - */ - if (sed_row > (ROWS_PER_SCREEN - 1)) { - if (sed_row > ((ROWS_PER_SCREEN * 2) - 1)) { - sed_fb_offset = 0x00; - sed_row = 0; - sed_clearscreen(); - } else { - /* calculate the new offset address of the frame buffer in words */ - sed_fb_offset += (SED_GET_ADD(1, 0, sed_color_depth) / 2); - } - sed_update_fb_offset(); - } /* if (sed_row > (ROWS_PER_SCREEN - 1)) */ -} - -void sed_putstring(char *s) -{ - char *p = s; - while (*p) - sed_putchar(*p++); -} - -void sed_clearscreen(void) -{ - int i; - uint16_t wr16; - int bg = sed_bg_color; - int fbsize = sed_frame_buffer_size(); - - /* we double buffer so clear ALL of memory */ - fbsize *= 2; - - /* fill the frame buffer with incrementing color values */ - switch (sed_color_depth){ - case 4: wr16 = bg | bg << 4 | bg << 8 | bg << 12; break; - case 8: wr16 = bg | bg << 8; break; - /* 16-bits bypasses the lookup table */ - default: wr16 = vga_lookup[bg]; break; - } - for (i = 0; i < fbsize; i += 2){ - sed_write_frame_buffer(i, wr16); - } -} diff --git a/c/src/lib/libbsp/arm/csb337/console/uarts.c b/c/src/lib/libbsp/arm/csb337/console/uarts.c deleted file mode 100644 index b705a477b7..0000000000 --- a/c/src/lib/libbsp/arm/csb337/console/uarts.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Console driver for for KIT637_V6 (CSB637) - * - * This driver uses the shared console driver in - * ...../libbsp/shared/console.c - * - * Copyright (c) 2003 by Cogent Computer Systems - * Written by Jay Monkman - * - * Modified by Fernando Nicodemos - * from NCB - Sistemas Embarcados Ltda. (Brazil) - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - * Modified and FrameBuffer Console Device Support added by - * Joel Sherrill, 2009. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -extern const console_fns dbgu_fns; - -#if ENABLE_LCD - extern const console_fns fbcons_fns; - #define LCD_DEV 1 -#else - #define LCD_DEV 0 -#endif - -#if (ENABLE_UMON && ENABLE_UMON_CONSOLE) - extern const console_fns umoncons_fns; - #define UMON_CONS_DEV 1 -#else - #define UMON_CONS_DEV 0 -#endif - -#if ENABLE_USART0 || ENABLE_USART1 || ENABLE_USART2 || ENABLE_USART3 - extern const console_fns usart_polling_fns; -#endif - -#if ENABLE_USART0 - #define USART0_DEV 1 -#else - #define USART0_DEV 0 -#endif - -#if ENABLE_USART1 - #define USART1_DEV 1 -#else - #define USART1_DEV 0 -#endif - -#if ENABLE_USART2 - #define USART2_DEV 1 -#else - #define USART2_DEV 0 -#endif - -#if ENABLE_USART3 - #define USART3_DEV 1 -#else - #define USART3_DEV 0 -#endif - -#define NUM_DEVS \ - (1 + LCD_DEV + UMON_CONS_DEV + \ - USART0_DEV + USART1_DEV + USART2_DEV + USART3_DEV) - -/* These are used by code in console.c */ -unsigned long Console_Configuration_Count = NUM_DEVS; - -/* - * There's one item in array for each UART. - * - * Some of these fields are marked "NOT USED". They are not used - * by console.c, but may be used by drivers in libchip - * - * when we add other types of UARTS we will need to move this - * structure to a generic uart.c file with only this in it - */ -console_tbl Console_Configuration_Ports[] = { - { - "/dev/com0", /* sDeviceName */ - SERIAL_CUSTOM, /* deviceType */ - &dbgu_fns, /* pDeviceFns */ - NULL, /* deviceProbe */ - NULL, /* pDeviceFlow */ - 0, /* ulMargin - NOT USED */ - 0, /* ulHysteresis - NOT USED */ - NULL, /* pDeviceParams */ - DBGU_BASE, /* ulCtrlPort1 - Pointer to DBGU regs */ - 0, /* ulCtrlPort2 - NOT USED */ - 0, /* ulDataPort - NOT USED */ - NULL, /* getRegister - NOT USED */ - NULL, /* setRegister - NOT USED */ - NULL, /* getData - NOT USED */ - NULL, /* setData - NOT USED */ - 0, /* ulClock - NOT USED */ - 0 /* ulIntVector - NOT USED */ - }, -#if ENABLE_LCD - { - "/dev/fbcons", /* sDeviceName */ - SERIAL_CUSTOM, /* deviceType */ - &fbcons_fns, /* pDeviceFns */ - NULL, /* deviceProbe */ - NULL, /* pDeviceFlow */ - 0, /* ulMargin - NOT USED */ - 0, /* ulHysteresis - NOT USED */ - NULL, /* pDeviceParams */ - 0, /* ulCtrlPort1 - Pointer to DBGU regs */ - 0, /* ulCtrlPort2 - NOT USED */ - 0, /* ulDataPort - NOT USED */ - NULL, /* getRegister - NOT USED */ - NULL, /* setRegister - NOT USED */ - NULL, /* getData - NOT USED */ - NULL, /* setData - NOT USED */ - 0, /* ulClock - NOT USED */ - 0 /* ulIntVector - NOT USED */ - }, -#endif -#if (ENABLE_UMON && ENABLE_UMON_CONSOLE) - { - "/dev/umon", /* sDeviceName */ - SERIAL_CUSTOM, /* deviceType */ - &umoncons_fns, /* pDeviceFns */ - NULL, /* deviceProbe */ - NULL, /* pDeviceFlow */ - 0, /* ulMargin - NOT USED */ - 0, /* ulHysteresis - NOT USED */ - NULL, /* pDeviceParams */ - 0, /* ulCtrlPort1 - Pointer to UMON regs */ - 0, /* ulCtrlPort2 - NOT USED */ - 0, /* ulDataPort - NOT USED */ - NULL, /* getRegister - NOT USED */ - NULL, /* setRegister - NOT USED */ - NULL, /* getData - NOT USED */ - NULL, /* setData - NOT USED */ - 0, /* ulClock - NOT USED */ - 0 /* ulIntVector - NOT USED */ - }, -#endif -#if ENABLE_USART0 - { - "/dev/com1", /* sDeviceName */ - SERIAL_CUSTOM, /* deviceType */ - &usart_polling_fns,/* pDeviceFns */ - NULL, /* deviceProbe */ - NULL, /* pDeviceFlow */ - 0, /* ulMargin - NOT USED */ - 0, /* ulHysteresis - NOT USED */ - NULL, /* pDeviceParams */ - USART0_BASE, /* ulCtrlPort1 - Pointer to USART 0 regs */ - 0, /* ulCtrlPort2 - NOT USED */ - 0, /* ulDataPort - NOT USED */ - NULL, /* getRegister - NOT USED */ - NULL, /* setRegister - NOT USED */ - NULL, /* getData - NOT USED */ - NULL, /* setData - NOT USED */ - 0, /* ulClock - NOT USED */ - 0 /* ulIntVector - NOT USED */ - }, -#endif -#if ENABLE_USART1 - { - "/dev/com2", /* sDeviceName */ - SERIAL_CUSTOM, /* deviceType */ - &usart_polling_fns,/* pDeviceFns */ - NULL, /* deviceProbe */ - NULL, /* pDeviceFlow */ - 0, /* ulMargin - NOT USED */ - 0, /* ulHysteresis - NOT USED */ - NULL, /* pDeviceParams */ - USART1_BASE, /* ulCtrlPort1 - Pointer to USART 1 regs */ - 0, /* ulCtrlPort2 - NOT USED */ - 0, /* ulDataPort - NOT USED */ - NULL, /* getRegister - NOT USED */ - NULL, /* setRegister - NOT USED */ - NULL, /* getData - NOT USED */ - NULL, /* setData - NOT USED */ - 0, /* ulClock - NOT USED */ - 0 /* ulIntVector - NOT USED */ - }, -#endif -#if ENABLE_USART2 - { - "/dev/com3", /* sDeviceName */ - SERIAL_CUSTOM, /* deviceType */ - &usart_polling_fns,/* pDeviceFns */ - NULL, /* deviceProbe */ - NULL, /* pDeviceFlow */ - 0, /* ulMargin - NOT USED */ - 0, /* ulHysteresis - NOT USED */ - NULL, /* pDeviceParams */ - USART2_BASE, /* ulCtrlPort1 - Pointer to USART 2 regs */ - 0, /* ulCtrlPort2 - NOT USED */ - 0, /* ulDataPort - NOT USED */ - NULL, /* getRegister - NOT USED */ - NULL, /* setRegister - NOT USED */ - NULL, /* getData - NOT USED */ - NULL, /* setData - NOT USED */ - 0, /* ulClock - NOT USED */ - 0 /* ulIntVector - NOT USED */ - }, -#endif -#if ENABLE_USART3 - { - "/dev/com4", /* sDeviceName */ - SERIAL_CUSTOM, /* deviceType */ - &usart_polling_fns,/* pDeviceFns */ - NULL, /* deviceProbe */ - NULL, /* pDeviceFlow */ - 0, /* ulMargin - NOT USED */ - 0, /* ulHysteresis - NOT USED */ - NULL, /* pDeviceParams */ - USART3_BASE, /* ulCtrlPort1 - Pointer to USART 3 regs */ - 0, /* ulCtrlPort2 - NOT USED */ - 0, /* ulDataPort - NOT USED */ - NULL, /* getRegister - NOT USED */ - NULL, /* setRegister - NOT USED */ - NULL, /* getData - NOT USED */ - NULL, /* setData - NOT USED */ - 0, /* ulClock - NOT USED */ - 0 /* ulIntVector - NOT USED */ - } -#endif -}; - -console_tbl *BSP_get_uart_from_minor(int minor) -{ - return Console_Port_Tbl[minor]; -} diff --git a/c/src/lib/libbsp/arm/csb337/console/usart.c b/c/src/lib/libbsp/arm/csb337/console/usart.c deleted file mode 100644 index 23b877ce64..0000000000 --- a/c/src/lib/libbsp/arm/csb337/console/usart.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Driver for AT91RM9200 USART ports - */ - -/* - * COPYRIGHT (c) 2006-2009. - * NCB - Sistemas Embarcados Ltda. (Brazil) - * Fernando Nicodemos - * - * and - * - * COPYRIGHT (c) 1989-2009. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. -*/ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -/* static function prototypes */ -static int usart_first_open(int major, int minor, void *arg); -static int usart_last_close(int major, int minor, void *arg); -static int usart_read_polled(int minor); -static ssize_t usart_write_polled_support(int minor, const char *buf, size_t len); -static void usart_init(int minor); -static void usart_write_polled(int minor, char c); -static int usart_set_attributes(int minor, const struct termios *t); -at91rm9200_usart_regs_t *usart_get_base(int minor); - -/* Pointers to functions for handling the UART polled. */ -const console_fns usart_polling_fns = { - libchip_serial_default_probe, /* deviceProbe */ - usart_first_open, /* deviceFirstOpen */ - usart_last_close, /* deviceLastClose */ - usart_read_polled, /* deviceRead */ - usart_write_polled_support, /* deviceWrite */ - usart_init, /* deviceInitialize */ - usart_write_polled, /* deviceWritePolled */ - usart_set_attributes, /* deviceSetAttributes */ - FALSE /* TRUE if interrupt driven, FALSE if not. */ -}; - -at91rm9200_usart_regs_t *usart_get_base(int minor) -{ - console_tbl *console_entry; - at91rm9200_usart_regs_t *port; - - console_entry = BSP_get_uart_from_minor(minor); - - if (console_entry == NULL) - return 0; - - port = (at91rm9200_usart_regs_t *) console_entry->ulCtrlPort1; - //printk( "minor=%d entry=%p port=%p\n", minor, console_entry, port ); - - return port; -} - -/* - * Functions called via callbacks (i.e. the ones in uart_fns - */ - -/* - * This is called the first time each device is opened. Since - * the driver is polled, we don't have to do anything. If the driver - * were interrupt driven, we'd enable interrupts here. - */ -static int usart_first_open(int major, int minor, void *arg) -{ - at91rm9200_usart_regs_t *usart; - - usart = usart_get_base(minor); - if ( !usart ) - return -1; - - /* XXX port isn't being initialized or enabled */ - - /* XXX I hope this is enough */ - usart->cr = (US_CR_RXEN | US_CR_TXEN); - return 0; -} - -/* - * This is called the last time each device is closed. Since - * the driver is polled, we don't have to do anything. If the driver - * were interrupt driven, we'd disable interrupts here. - */ -static int usart_last_close(int major, int minor, void *arg) -{ - at91rm9200_usart_regs_t *usart; - - usart = usart_get_base(minor); - if ( !usart ) - return -1; - - return 0; -} - -/* - * Read one character from UART. - * - * return -1 if there's no data, otherwise return - * the character in lowest 8 bits of returned int. - */ -static int usart_read_polled(int minor) -{ - at91rm9200_usart_regs_t *usart; - - usart = usart_get_base(minor); - if ( !usart ) - return -1; - - /* if nothing ready return -1 */ - if ( (usart->sr & US_IER_RXRDY) == 0 ) - return -1; - - return usart->rhr; -} - - -/* - * Write character out - */ -static void usart_write_polled(int minor, char c) -{ - at91rm9200_usart_regs_t *usart; - - usart = usart_get_base(minor); - if ( !usart ) - return; - - /* delay until TX empty */ - while ( (usart->sr & US_IER_TXEMPTY) == 0 ) - ; - - usart->thr = c; -} - -/* - * Write buffer to UART - * - * return 1 on success, -1 on error - */ -static ssize_t usart_write_polled_support(int minor, const char *buf, size_t len) -{ - at91rm9200_usart_regs_t *usart; - int nwrite=0; - - /* - * Verify the minor number - */ - usart = usart_get_base(minor); - if ( !usart ) - return -1; - - /* - * poll each byte in the string out of the port. - */ - while (nwrite < len) { - usart_write_polled(minor, *buf++); - nwrite++; - } - - /* - * return the number of bytes written. - */ - return nwrite; - - return 1; -} - - -/* Set up the UART. */ -static void usart_init(int minor) -{ - at91rm9200_usart_regs_t *usart; - - usart = usart_get_base(minor); - if ( !usart ) - return; - -} - - -/* This is for setting baud rate, bits, etc. */ -static int usart_set_attributes(int minor, const struct termios *t) -{ - uint32_t brgr; - uint32_t mode, baud, baud_requested; - at91rm9200_usart_regs_t *usart; - - usart = usart_get_base(minor); - if ( !usart ) - return -1; - - /* Get current mode register */ - mode = usart->mr & ~(US_MR_USMODE | US_MR_USCLKS | US_MR_CHRL - | US_MR_PAR | US_MR_NBSTOP); - - /* Byte size */ - switch (t->c_cflag & CSIZE){ - case CS5: - mode |= US_MR_CHRL_5; - break; - case CS6: - mode |= US_MR_CHRL_6; - break; - case CS7: - mode |= US_MR_CHRL_7; - break; - default: - mode |= US_MR_CHRL_8; - break; - } - - /* Stop bits */ - if (t->c_cflag & CSTOPB){ - mode |= US_MR_NBSTOP_2; /* 2 stop bits */ - } else - mode |= US_MR_NBSTOP_1; /* 1 stop bits */ - - /* Parity */ - if (t->c_cflag & PARENB){ - /* Mark or Space parity */ - if (t->c_cflag & PARODD){ - mode |= US_MR_PAR_ODD; - } else - mode |= US_MR_PAR_EVEN; - } else - mode |= US_MR_PAR_NONE; - - baud_requested = t->c_ospeed; - - /* If not, set the dbgu console baud as USART baud default */ - if (!baud_requested) - baud_requested = BSP_get_baud(); - - baud = rtems_termios_baud_to_number(baud_requested); - - brgr = (at91rm9200_get_mck() / 16) / baud; - - if (brgr > 65535){ /* BRGR is 16-bit, so switch to slower clock */ - brgr /= 8; - mode |= US_MR_USCLKS_MCK_DIV8; - } - - usart->mr = mode; - usart->brgr = brgr; - return 0; -} diff --git a/c/src/lib/libbsp/arm/edb7312/Makefile.am b/c/src/lib/libbsp/arm/edb7312/Makefile.am index 612afe1f99..6404930f8f 100644 --- a/c/src/lib/libbsp/arm/edb7312/Makefile.am +++ b/c/src/lib/libbsp/arm/edb7312/Makefile.am @@ -32,7 +32,7 @@ librtemsbsp_a_SOURCES +=../../../../../../bsps/arm/edb7312/clock/clockdrv.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c -librtemsbsp_a_SOURCES += console/uart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/edb7312/console/uart.c # timer librtemsbsp_a_SOURCES += timer/timer.c diff --git a/c/src/lib/libbsp/arm/edb7312/console/uart.c b/c/src/lib/libbsp/arm/edb7312/console/uart.c deleted file mode 100644 index 4ba71c8cc2..0000000000 --- a/c/src/lib/libbsp/arm/edb7312/console/uart.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Cirrus EP7312 Console Driver - * - * Copyright (c) 2002 by Jay Monkman - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include /* Must be before libio.h */ -#include -#include -#include - -#include -#include -#include - -#define NUM_DEVS 1 -int uart_poll_read(int minor); - -static int uart_first_open(int major, int minor, void *arg); -static int uart_last_close(int major, int minor, void *arg); -static int uart_read(int minor); -static ssize_t uart_write(int minor, const char *buf, size_t len); -static void uart_init(int minor); -static void uart_write_polled(int minor, char c); -static int uart_set_attributes(int minor, const struct termios *t); - -unsigned long Console_Configuration_Count = NUM_DEVS; - -const console_fns uart_fns = -{ - libchip_serial_default_probe, - uart_first_open, - uart_last_close, - uart_read, - uart_write, - uart_init, - uart_write_polled, - uart_set_attributes, - FALSE -}; -console_tbl Console_Configuration_Ports[] = { - { - "/dev/com0", /* sDeviceName */ - SERIAL_CUSTOM, /* deviceType */ - &uart_fns, /* pDeviceFns */ - NULL, /* deviceProbe */ - NULL, /* pDeviceFlow */ - 16, /* ulMargin */ - 8, /* ulHysteresis */ - NULL, /* pDeviceParams */ - (uint32_t)EP7312_UARTCR1, /* ulCtrlPort1 */ - (uint32_t)EP7312_SYSFLG1, /* ulCtrlPort2 */ - (uint32_t)EP7312_UARTDR1, /* ulDataPort */ - 0, /* getRegister */ - 0, /* setRegister */ - 0, /* getData */ - 0, /* setData */ - 0, /* ulClock */ - 0 /* ulIntVector */ - }}; - -static int uart_first_open(int major, int minor, void *arg) {return 0;} -static int uart_last_close(int major, int minor, void *arg) {return 0;} -static int uart_read(int minor) -{ - return uart_poll_read(minor); -} - -static void uart_write_polled(int minor, char c) -{ - uart_write(minor, &c, 1); -} - -static int uart_set_attributes(int minor, const struct termios *t) -{ - return 0; -} - -int uart_poll_read(int minor) -{ - volatile uint32_t *data_reg; - volatile uint32_t *ctrl_reg2; - char c; - int err; - - data_reg = (uint32_t *)Console_Port_Tbl[minor]->ulDataPort; - ctrl_reg2 = (uint32_t *)Console_Port_Tbl[minor]->ulCtrlPort2; - - if ((*ctrl_reg2 & EP7312_UART_URXFE1) != 0) { - return -1; - } - - err = *data_reg; - c = err & 0xff; - err &= (EP7312_UART_FRMERR | EP7312_UART_PARERR | EP7312_UART_OVERR); - - return c; -} - -static ssize_t uart_do_write( - volatile uint32_t *uartdr, - const char *buf, - size_t len, - volatile uint32_t *sysflg -) -{ - size_t i; - - for (i = 0; i < len; i++) { - /* Wait for fifo to have room */ - while ((*sysflg & EP7312_UART_UTXFF1) != 0) { - continue; - } - - *uartdr = buf[i]; - } - - return len; -} - -static ssize_t uart_write(int minor, const char *buf, size_t len) -{ - volatile uint32_t *data_reg; - volatile uint32_t *ctrl_reg2; - - data_reg = (uint32_t *)Console_Port_Tbl[minor]->ulDataPort; - ctrl_reg2 = (uint32_t *)Console_Port_Tbl[minor]->ulCtrlPort2; - - return uart_do_write(data_reg, buf, len, ctrl_reg2); -} - -static void uart_init(int minor) -{ - volatile uint32_t *ctrl_reg1; - - ctrl_reg1 = (uint32_t *)Console_Port_Tbl[minor]->ulCtrlPort1; - - /* *ctrl_reg = (BSP_UART_DATA8 | - BSP_UART_STOP1 | - BSP_UART_PARITY_NONE | - EP7312_UART_FIFOEN | - BSP_UART_BAUD_9600); - */ - *ctrl_reg1 = (EP7312_UART_WRDLEN8 | - EP7312_UART_FIFOEN | - 0x17); /* 9600 baud */ - -} - -/* - * Debug IO support - */ -static void _BSP_null_char(char c) -{ - uart_do_write(EP7312_UARTDR1, &c, 1, EP7312_SYSFLG1); -} - -static int _BSP_get_char(void) -{ - return uart_poll_read(0); -} - -BSP_output_char_function_type BSP_output_char = _BSP_null_char; - -BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char; diff --git a/c/src/lib/libbsp/arm/gdbarmsim/Makefile.am b/c/src/lib/libbsp/arm/gdbarmsim/Makefile.am index 83bbda0094..68521ca1c2 100644 --- a/c/src/lib/libbsp/arm/gdbarmsim/Makefile.am +++ b/c/src/lib/libbsp/arm/gdbarmsim/Makefile.am @@ -28,8 +28,8 @@ librtemsbsp_a_SOURCES += startup/syscalls.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/cpucounter/cpucounterread.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/cpucounter/cpucounterdiff.c # console -librtemsbsp_a_SOURCES += ../../shared/console-polled.c -librtemsbsp_a_SOURCES += console/console-io.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-polled.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/gdbarmsim/console/console-io.c # clock librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/clock/clock-simidle.c # timer diff --git a/c/src/lib/libbsp/arm/gdbarmsim/console/console-io.c b/c/src/lib/libbsp/arm/gdbarmsim/console/console-io.c deleted file mode 100644 index 8bea74d934..0000000000 --- a/c/src/lib/libbsp/arm/gdbarmsim/console/console-io.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * COPYRIGHT (c) 1989-2009. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include - -/* - * console_initialize_hardware - * - * This routine initializes the console hardware. - * - */ -void console_initialize_hardware(void) -{ - return; -} - -/* - * console_outbyte_polled - * - * This routine transmits a character using polling. - */ -void console_outbyte_polled( - int port, - char ch -) -{ - gdbarmsim_writec(ch); -} - -/* - * console_inbyte_nonblocking - * - * This routine polls for a character. - */ - -int console_inbyte_nonblocking( - int port -) -{ - return -1; -} - -#include - -static void MyBSP_output_char(char c) { console_outbyte_polled( 0, c ); } - -BSP_output_char_function_type BSP_output_char = MyBSP_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/arm/gumstix/Makefile.am b/c/src/lib/libbsp/arm/gumstix/Makefile.am index ec5d8c910e..d262811e47 100644 --- a/c/src/lib/libbsp/arm/gumstix/Makefile.am +++ b/c/src/lib/libbsp/arm/gumstix/Makefile.am @@ -33,8 +33,8 @@ librtemsbsp_a_SOURCES += timer/timer.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c -librtemsbsp_a_SOURCES += console/uarts.c -librtemsbsp_a_SOURCES += console/ffuart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/gumstix/console/uarts.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/gumstix/console/ffuart.c # IRQ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c librtemsbsp_a_SOURCES += irq/irq.c diff --git a/c/src/lib/libbsp/arm/gumstix/console/ffuart.c b/c/src/lib/libbsp/arm/gumstix/console/ffuart.c deleted file mode 100644 index 335fc6f4de..0000000000 --- a/c/src/lib/libbsp/arm/gumstix/console/ffuart.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Console driver for pxa255 full function port by Yang Xi - * Copyright (c) 2004 by Jay Monkman - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -volatile int dbg_dly; - -/* static function prototypes */ -static int ffuart_first_open(int major, int minor, void *arg); -static int ffuart_last_close(int major, int minor, void *arg); -static int ffuart_read(int minor); -static ssize_t ffuart_write(int minor, const char *buf, size_t len); -static void ffuart_init(int minor); -static void ffuart_write_polled(int minor, char c); -static int ffuart_set_attributes(int minor, const struct termios *t); - -/* Pointers to functions for handling the UART. */ -const console_fns ffuart_fns = -{ - libchip_serial_default_probe, - ffuart_first_open, - ffuart_last_close, - ffuart_read, - ffuart_write, - ffuart_init, - ffuart_write_polled, /* not used in this driver */ - ffuart_set_attributes, - FALSE /* TRUE if interrupt driven, FALSE if not. */ -}; - - -/* - * This is called the first time each device is opened. Since - * the driver is polled, we don't have to do anything. If the driver - * were interrupt driven, we'd enable interrupts here. - */ -static int ffuart_first_open(int major, int minor, void *arg) -{ - return 0; -} - - -/* - * This is called the last time each device is closed. Since - * the driver is polled, we don't have to do anything. If the driver - * were interrupt driven, we'd disable interrupts here. - */ -static int ffuart_last_close(int major, int minor, void *arg) -{ - return 0; -} - - -/* - * Read one character from UART. - * - * return -1 if there's no data, otherwise return - * the character in lowest 8 bits of returned int. - */ -static int ffuart_read(int minor) -{ - char c; - console_tbl *console_entry; - ffuart_reg_t *ffuart; - - console_entry = BSP_get_uart_from_minor(minor); - - if (console_entry == NULL) { - return -1; - } - - ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1; - - if (!(ffuart->lsr & FULL_RECEIVE)) { - return -1; - } - - c = ffuart->rbr & 0xff; - - return c; -} - - -/* - * Write buffer to UART - * - * return 1 on success, -1 on error - */ -static ssize_t ffuart_write(int minor, const char *buf, size_t len) -{ - size_t i, x; - char c; - console_tbl *console_entry; - ffuart_reg_t *ffuart; - - console_entry = BSP_get_uart_from_minor(minor); - - if (console_entry == NULL) { - return -1; - } - - ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1; - - for (i = 0; i < len; i++) { - - while(1) { - if (ffuart->lsr & SEND_EMPTY) { - break; - } - } - - c = (char) buf[i]; -#if ON_SKYEYE != 1 - if(c=='\n'){ - ffuart->rbr = '\r'; - for (x = 0; x < 100; x++) { - dbg_dly++; /* using a global so this doesn't get optimized out */ - } - while(1){ - if(ffuart->lsr & SEND_EMPTY){ - break; - } - } - } -#endif - ffuart->rbr = c; - - /* the TXRDY flag does not seem to update right away (is this true?) */ - /* so we wait a bit before continuing */ - for (x = 0; x < 100; x++) { - dbg_dly++; /* using a global so this doesn't get optimized out */ - } - } - - return 1; -} - - -static void ffuart_init(int minor) -{ - - - console_tbl *console_entry; - ffuart_reg_t *ffuart; - unsigned int divisor; - - console_entry = BSP_get_uart_from_minor(minor); - - - - if (console_entry == NULL) { - return; - } - - ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1; - ffuart->lcr |= DLAB; - /*Set the Bound*/ - ffuart->lcr |= DLAB; - divisor = FREQUENCY_UART / (115200*16); - ffuart->rbr = divisor & 0xff; - ffuart->ier = (divisor >> 8)&0xff; - /*Disable FIFO*/ - ffuart->iir = 0; - ffuart->lcr &=~DLAB; - /*Enable UART*/ - ffuart->ier = 0x40; - ffuart->lcr = EIGHT_BITS_NOPARITY_1STOPBIT; - -} - -/* I'm not sure this is needed for the shared console driver. */ -static void ffuart_write_polled(int minor, char c) -{ - ffuart_write(minor, &c, 1); -} - -/* This is for setting baud rate, bits, etc. */ -static int ffuart_set_attributes(int minor, const struct termios *t) -{ - return 0; -} - -/***********************************************************************/ -/* - * The following functions are not used by TERMIOS, but other RTEMS - * functions use them instead. - */ -/***********************************************************************/ -/* - * Read from UART. This is used in the exit code, and can't - * rely on interrupts. - */ -static int ffuart_poll_read(int minor) -{ - return ffuart_read(minor); -} - - -/* - * Write a character to the console. This is used by printk() and - * maybe other low level functions. It should not use interrupts or any - * RTEMS system calls. It needs to be very simple - */ -static void _BSP_put_char( char c ) { - ffuart_write_polled(0, c); -} - -static int _BSP_poll_char(void) { - return ffuart_poll_read(0); -} - -BSP_output_char_function_type BSP_output_char = _BSP_put_char; -BSP_polling_getchar_function_type BSP_poll_char = _BSP_poll_char; diff --git a/c/src/lib/libbsp/arm/gumstix/console/uarts.c b/c/src/lib/libbsp/arm/gumstix/console/uarts.c deleted file mode 100644 index 08408695e0..0000000000 --- a/c/src/lib/libbsp/arm/gumstix/console/uarts.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Console driver for GUMSTIX by Yang Xi - * - * This driver uses the shared console driver in - * ...../libbsp/shared/console.c - * - * Copyright (c) 2003 by Cogent Computer Systems - * Written by Jay Monkman - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include - -#include -#include -#include - -/* How many serial ports? */ -#define NUM_DEVS 1 - -/* These are used by code in console.c */ -unsigned long Console_Configuration_Count = NUM_DEVS; - -extern const console_fns ffuart_fns; - -/* - * There's one item in array for each UART. - * - * Some of these fields are marked "NOT USED". They are not used - * by console.c, but may be used by drivers in libchip - * - * when we add other types of UARTS we will need to move this - * structure to a generic uart.c file with only this in it - */ -console_tbl Console_Configuration_Ports[] = { - { - "/dev/com0", /* sDeviceName */ - SERIAL_CUSTOM, /* deviceType */ - &ffuart_fns, /* pDeviceFns */ - NULL, /* deviceProbe */ - NULL, /* pDeviceFlow */ - 0, /* ulMargin - NOT USED */ - 0, /* ulHysteresis - NOT USED */ - NULL, /* pDeviceParams */ - FFUART_BASE, /* ulCtrlPort1 - Pointer to DBGU regs */ - 0, /* ulCtrlPort2 - NOT USED */ - 0, /* ulDataPort - NOT USED */ - NULL, /* getRegister - NOT USED */ - NULL, /* setRegister - NOT USED */ - NULL, /* getData - NOT USED */ - NULL, /* setData - NOT USED */ - 0, /* ulClock - NOT USED */ - 0 /* ulIntVector - NOT USED */ - }}; - - -console_tbl *BSP_get_uart_from_minor(int minor) -{ - return Console_Port_Tbl[minor]; -} diff --git a/c/src/lib/libbsp/arm/imx/Makefile.am b/c/src/lib/libbsp/arm/imx/Makefile.am index c02152f8ca..2d62ed445d 100644 --- a/c/src/lib/libbsp/arm/imx/Makefile.am +++ b/c/src/lib/libbsp/arm/imx/Makefile.am @@ -56,8 +56,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c librtemsbsp_a_SOURCES += ../shared/arm-gic-irq.c # Console -librtemsbsp_a_SOURCES += ../../shared/console-termios.c -librtemsbsp_a_SOURCES += console/console-config.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/imx/console/console-config.c # Clock librtemsbsp_a_SOURCES += ../shared/arm-generic-timer-clock-config.c diff --git a/c/src/lib/libbsp/arm/imx/console/console-config.c b/c/src/lib/libbsp/arm/imx/console/console-config.c deleted file mode 100644 index 0731446f08..0000000000 --- a/c/src/lib/libbsp/arm/imx/console/console-config.c +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright (c) 2017 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include - -#define IMX_UART_TX_FIFO_LEVEL 16 - -typedef struct { - rtems_termios_device_context base; - volatile imx_uart *regs; -#ifdef CONSOLE_USE_INTERRUPTS - rtems_vector_number irq; - int tx_in_progress; -#endif -} imx_uart_context; - -static imx_uart_context imx_uart_instances[7]; - -static imx_uart_context *imx_uart_console = &imx_uart_instances[0]; - -static volatile imx_uart *imx_uart_get_regs(rtems_termios_device_context *base) -{ - imx_uart_context *ctx; - - ctx = (imx_uart_context *) base; - return ctx->regs; -} - -static void imx_uart_write_polled(rtems_termios_device_context *base, char c) -{ - volatile imx_uart *regs; - - regs = imx_uart_get_regs(base); - - while ((regs->usr1 & IMX_UART_USR1_TRDY) == 0) { - /* Wait */ - } - - regs->utxd = IMX_UART_UTXD_TX_DATA(c); -} - -void imx_uart_console_drain(void) -{ - volatile imx_uart *regs; - - regs = imx_uart_get_regs(&imx_uart_console->base); - - if (regs != NULL) { - while ((regs->usr2 & IMX_UART_USR2_TXFE) == 0) { - /* Wait */ - } - } -} - -static void imx_output_char(char c) -{ - imx_uart_write_polled(&imx_uart_console->base, c); -} - -static void imx_uart_init_context( - imx_uart_context *ctx, - const char *fdt, - const char *serial -) -{ - int node; - - rtems_termios_device_context_initialize(&ctx->base, "UART"); - node = fdt_path_offset(fdt, serial); - ctx->regs = imx_get_reg_of_node(fdt, node); -#ifdef CONSOLE_USE_INTERRUPTS - ctx->irq = imx_get_irq_of_node(fdt, node, 0); -#endif -} - -static void imx_uart_probe(void) -{ - const void *fdt; - int node; - int offset; - const char *console; - size_t i; - - fdt = bsp_fdt_get(); - node = fdt_path_offset(fdt, "/chosen"); - - console = fdt_getprop(fdt, node, "stdout-path", NULL); - if (console == NULL) { - console = ""; - } - - node = fdt_path_offset(fdt, "/aliases"); - offset = fdt_first_property_offset(fdt, node); - i = 0; - - while (offset >= 0 && i < RTEMS_ARRAY_SIZE(imx_uart_instances)) { - const struct fdt_property *prop; - - prop = fdt_get_property_by_offset(fdt, offset, NULL); - - if (prop != NULL) { - const char *name; - - name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); - if (strstr(name, "serial") != NULL) { - imx_uart_context *ctx; - const char *serial; - - ctx = &imx_uart_instances[i]; - serial = prop->data; - - if (strcmp(serial, console) == 0) { - imx_uart_console = ctx; - } - - imx_uart_init_context(ctx, fdt, serial); - ++i; - } - } - - offset = fdt_next_property_offset(fdt, offset); - } - - BSP_output_char = imx_output_char; -} - -static void imx_output_char_init(char c) -{ - imx_uart_probe(); - imx_output_char(c); -} - -BSP_output_char_function_type BSP_output_char = imx_output_char_init; - -BSP_polling_getchar_function_type BSP_poll_char = NULL; - -#ifdef CONSOLE_USE_INTERRUPTS -static void imx_uart_interrupt(void *arg) -{ - rtems_termios_tty *tty; - imx_uart_context *ctx; - volatile imx_uart *regs; - uint32_t usr2; - - tty = arg; - ctx = rtems_termios_get_device_context(tty); - regs = ctx->regs; - usr2 = regs->usr2; - - regs->usr1 = IMX_UART_USR1_AGTIM; - - while ((usr2 & IMX_UART_USR2_RDR) != 0) { - char c; - - c = IMX_UART_URXD_RX_DATA_GET(regs->urxd); - rtems_termios_enqueue_raw_characters(tty, &c, 1); - usr2 = regs->usr2; - } - - if (ctx->tx_in_progress > 0 && (regs->usr1 & IMX_UART_USR1_TRDY) != 0) { - rtems_termios_dequeue_characters(tty, ctx->tx_in_progress); - } -} -#endif - -static bool imx_uart_set_attributes( - rtems_termios_device_context *base, - const struct termios *term -) -{ - imx_uart_context *ctx; - volatile imx_uart *regs; - uint32_t ufcr; - uint32_t baud; - - ctx = (imx_uart_context *) base; - regs = imx_uart_get_regs(&ctx->base); - - baud = rtems_termios_baud_to_number(term->c_ospeed); - - if (baud != 0) { - ufcr = regs->ufcr; - ufcr = IMX_UART_UFCR_RFDIV_SET(ufcr, 0x5); - regs->ufcr = ufcr; - regs->ubir = 15; - regs->ubmr = imx_ccm_uart_hz() / baud - 1; - } - - return true; -} - -static bool imx_uart_first_open( - rtems_termios_tty *tty, - rtems_termios_device_context *base, - struct termios *term, - rtems_libio_open_close_args_t *args -) -{ - imx_uart_context *ctx; - volatile imx_uart *regs; -#ifdef CONSOLE_USE_INTERRUPTS - rtems_status_code sc; - uint32_t ufcr; -#endif - - ctx = (imx_uart_context *) base; - regs = imx_uart_get_regs(&ctx->base); - - regs->ucr1 = IMX_UART_UCR1_UARTEN; - regs->ucr2 = IMX_UART_UCR2_IRTS | IMX_UART_UCR2_WS | IMX_UART_UCR2_RXEN - | IMX_UART_UCR2_TXEN | IMX_UART_UCR2_SRST; - - rtems_termios_set_initial_baud(tty, 115200); - imx_uart_set_attributes(base, term); - -#ifdef CONSOLE_USE_INTERRUPTS - ufcr = regs->ufcr; - ufcr = IMX_UART_UFCR_RXTL_SET(ufcr, 16); - ufcr = IMX_UART_UFCR_TXTL_SET(ufcr, IMX_UART_TX_FIFO_LEVEL); - regs->ufcr = ufcr; - regs->ucr1 |= IMX_UART_UCR1_RRDYEN; - regs->ucr2 |= IMX_UART_UCR2_ATEN; - sc = rtems_interrupt_handler_install( - ctx->irq, - "UART", - RTEMS_INTERRUPT_SHARED, - imx_uart_interrupt, - tty - ); - if (sc != RTEMS_SUCCESSFUL) { - return false; - } -#endif - - return true; -} - -static void imx_uart_last_close( - rtems_termios_tty *tty, - rtems_termios_device_context *base, - rtems_libio_open_close_args_t *args -) -{ -#ifdef CONSOLE_USE_INTERRUPTS - imx_uart_context *ctx; - - ctx = (imx_uart_context *) base; - rtems_interrupt_handler_remove(ctx->irq, imx_uart_interrupt, tty); -#endif -} - -static void imx_uart_write( - rtems_termios_device_context *base, - const char *buf, - size_t len -) -{ -#ifdef CONSOLE_USE_INTERRUPTS - imx_uart_context *ctx; - volatile imx_uart *regs; - int n; - uint32_t ucr1; - - ctx = (imx_uart_context *) base; - regs = imx_uart_get_regs(&ctx->base); - ucr1 = regs->ucr1; - - if (len > 0) { - int i; - - n = (int) MIN(len, IMX_UART_TX_FIFO_LEVEL); - ucr1 |= IMX_UART_UCR1_TRDYEN; - - for (i = 0; i < n; ++i) { - regs->utxd = IMX_UART_UTXD_TX_DATA(buf[i]); - } - } else { - n = 0; - ucr1 &= ~IMX_UART_UCR1_TRDYEN; - } - - regs->ucr1 = ucr1; - ctx->tx_in_progress = n; -#else - size_t i; - - for (i = 0; i < len; ++i) { - imx_uart_write_polled(base, buf[i]); - } -#endif -} - -#ifndef CONSOLE_USE_INTERRUPTS -static int imx_uart_read(rtems_termios_device_context *base) -{ - volatile imx_uart *regs; - - regs = imx_uart_get_regs(base); - - if ((regs->usr2 & IMX_UART_USR2_RDR) != 0) { - return IMX_UART_URXD_RX_DATA_GET(regs->urxd); - } else { - return -1; - } -} -#endif - -static const rtems_termios_device_handler imx_uart_handler = { - .first_open = imx_uart_first_open, - .last_close = imx_uart_last_close, - .write = imx_uart_write, - .set_attributes = imx_uart_set_attributes, -#ifdef CONSOLE_USE_INTERRUPTS - .mode = TERMIOS_IRQ_DRIVEN -#else - .poll_read = imx_uart_read, - .mode = TERMIOS_POLLED -#endif -}; - -rtems_status_code console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - char path[] = "/dev/ttyS?"; - size_t i; - - rtems_termios_initialize(); - - for (i = 0; i < RTEMS_ARRAY_SIZE(imx_uart_instances); ++i) { - imx_uart_context *ctx; - - ctx = &imx_uart_instances[i]; - path[sizeof(path) - 2] = (char) ('0' + i); - - rtems_termios_device_install( - path, - &imx_uart_handler, - NULL, - &ctx->base - ); - - if (ctx == imx_uart_console) { - link(path, CONSOLE_DEVICE_NAME); - } - } - - return RTEMS_SUCCESSFUL; -} - -RTEMS_SYSINIT_ITEM( - imx_uart_probe, - RTEMS_SYSINIT_BSP_START, - RTEMS_SYSINIT_ORDER_LAST -); diff --git a/c/src/lib/libbsp/arm/lm3s69xx/Makefile.am b/c/src/lib/libbsp/arm/lm3s69xx/Makefile.am index 31ee769f16..52bbb89ce3 100644 --- a/c/src/lib/libbsp/arm/lm3s69xx/Makefile.am +++ b/c/src/lib/libbsp/arm/lm3s69xx/Makefile.am @@ -56,8 +56,8 @@ librtemsbsp_a_SOURCES += ../shared/armv7m/irq/armv7m-irq-dispatch.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c -librtemsbsp_a_SOURCES += console/console-config.c -librtemsbsp_a_SOURCES += console/uart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lm3s69xx/console/console-config.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lm3s69xx/console/uart.c # Clock librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/clock/clock-armv7m.c diff --git a/c/src/lib/libbsp/arm/lm3s69xx/console/console-config.c b/c/src/lib/libbsp/arm/lm3s69xx/console/console-config.c deleted file mode 100644 index b702f0cd66..0000000000 --- a/c/src/lib/libbsp/arm/lm3s69xx/console/console-config.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright © 2013 Eugeniy Meshcheryakov - * - * Copyright (c) 2011 Sebastian Huber. All rights reserved. - * - * embedded brains GmbH - * Obere Lagerstr. 30 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include - -#include -#include -#include -#include - -console_tbl Console_Configuration_Ports [] = { - #ifdef LM3S69XX_ENABLE_UART_0 - { - .sDeviceName = "/dev/ttyS0", - .deviceType = SERIAL_CUSTOM, - .pDeviceFns = &lm3s69xx_uart_fns, - .ulCtrlPort1 = LM3S69XX_UART_0_BASE, - .ulClock = LM3S69XX_UART_BAUD, - .ulIntVector = LM3S69XX_IRQ_UART_0, - .pDeviceParams = (void *)0 - }, - #endif - #ifdef LM3S69XX_ENABLE_UART_1 - { - .sDeviceName = "/dev/ttyS1", - .deviceType = SERIAL_CUSTOM, - .pDeviceFns = &lm3s69xx_uart_fns, - .ulCtrlPort1 = LM3S69XX_UART_1_BASE, - .ulClock = LM3S69XX_UART_BAUD, - .ulIntVector = LM3S69XX_IRQ_UART_1, - .pDeviceParams = (void *)1 - }, - #endif - #ifdef LM3S69XX_ENABLE_UART_2 - { - .sDeviceName = "/dev/ttyS2", - .deviceType = SERIAL_CUSTOM, - .pDeviceFns = &lm3s69xx_uart_fns, - .ulCtrlPort1 = LM3S69XX_UART_2_BASE, - .ulClock = LM3S69XX_UART_BAUD, - .ulIntVector = LM3S69XX_IRQ_UART_2, - .pDeviceParams = (void *)2 - } - #endif -}; - -#define PORT_COUNT \ - (sizeof(Console_Configuration_Ports) \ - / sizeof(Console_Configuration_Ports [0])) - -unsigned long Console_Configuration_Count = PORT_COUNT; - -static void output_char(char c) -{ - const console_fns *con = - Console_Configuration_Ports [Console_Port_Minor].pDeviceFns; - - con->deviceWritePolled((int) Console_Port_Minor, c); -} - -BSP_output_char_function_type BSP_output_char = output_char; - -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/arm/lm3s69xx/console/uart.c b/c/src/lib/libbsp/arm/lm3s69xx/console/uart.c deleted file mode 100644 index 67a85f4e96..0000000000 --- a/c/src/lib/libbsp/arm/lm3s69xx/console/uart.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright © 2013 Eugeniy Meshcheryakov - * - * Copyright (c) 2011 Sebastian Huber. All rights reserved. - * - * embedded brains GmbH - * Obere Lagerstr. 30 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include -#include -#include - -#define LM3S69XX_UART_FIFO_DEPTH 16 - -static volatile lm3s69xx_uart *get_uart_regs(int minor) -{ - console_tbl *ct = Console_Port_Tbl [minor]; - - return (lm3s69xx_uart *) ct->ulCtrlPort1; -} - -static unsigned int get_uart_number(int minor) -{ - console_tbl *ct = Console_Port_Tbl [minor]; - - return (unsigned int)ct->pDeviceParams; -} - -/* - * Returns both integer and fractional parts as one number. - */ -static uint32_t get_baud_div(uint32_t baud) -{ - uint32_t clock4 = LM3S69XX_SYSTEM_CLOCK * 4; - return (clock4 + baud - 1) / baud; -} - -static void irq_handler(void *arg) -{ - int minor = (int)arg; - console_data *cd = &Console_Port_Data [minor]; - volatile lm3s69xx_uart *uart = get_uart_regs(minor); - - do { - char buf[LM3S69XX_UART_FIFO_DEPTH]; - int i = 0; - uint32_t status = uart->fr; - - while (((status & UARTFR_RXFE) == 0) && (i < LM3S69XX_UART_FIFO_DEPTH)) { - uint32_t d = uart->dr; - - if ((d & UARTDR_ERROR_MSK) == 0) { - buf[i] = UARTDR_DATA_GET(d); - i++; - } - - status = uart->fr; - } - - if (i > 0) - rtems_termios_enqueue_raw_characters(cd->termios_data, buf, i); - } while (uart->mis != 0); -} - -static void initialize(int minor) -{ - const console_tbl *ct = Console_Port_Tbl[minor]; - volatile lm3s69xx_uart *uart = get_uart_regs(minor); - unsigned int num = get_uart_number(minor); - - lm3s69xx_syscon_enable_uart_clock(num, true); - - uart->ctl = 0; - - uint32_t brd = get_baud_div(LM3S69XX_UART_BAUD); - uart->ibrd = brd / 64; - uart->fbrd = brd % 64; - - uart->lcrh = UARTLCRH_WLEN(0x3) | UARTLCRH_FEN; - uart->ctl = UARTCTL_RXE | UARTCTL_TXE | UARTCTL_UARTEN; - - int rv = rtems_interrupt_handler_install(ct->ulIntVector, "UART", - RTEMS_INTERRUPT_UNIQUE, irq_handler, (void *)minor); - assert(rv == RTEMS_SUCCESSFUL); -} - -static int first_open(int major, int minor, void *arg) -{ - rtems_libio_open_close_args_t *oc = (rtems_libio_open_close_args_t *) arg; - struct rtems_termios_tty *tty = (struct rtems_termios_tty *) oc->iop->data1; - console_data *cd = &Console_Port_Data [minor]; - volatile lm3s69xx_uart *uart = get_uart_regs(minor); - - cd->termios_data = tty; - rtems_termios_set_initial_baud(tty, LM3S69XX_UART_BAUD); - - /* Drain the RX FIFO. */ - while ((uart->fr & UARTFR_RXFE) == 0) - (void)uart->dr; - - uart->im = UARTI_RX | UARTI_RT; - - return 0; -} - -static int last_close(int major, int minor, void *arg) -{ - volatile lm3s69xx_uart *uart = get_uart_regs(minor); - uart->im = 0; - - return 0; -} - -static void write_polled(int minor, char c) -{ - volatile lm3s69xx_uart *uart = get_uart_regs(minor); - - while ((uart->fr & UARTFR_TXFF) != 0) { - /* Wait */ - } - - uart->dr = UARTDR_DATA(c); -} - -static ssize_t write_support_polled( - int minor, - const char *s, - size_t n -) -{ - ssize_t i = 0; - - for (i = 0; i < n; ++i) { - write_polled(minor, s [i]); - } - - return n; -} - -static int set_attribues(int minor, const struct termios *term) -{ - return -1; -} - -const console_fns lm3s69xx_uart_fns = { - .deviceProbe = libchip_serial_default_probe, - .deviceFirstOpen = first_open, - .deviceLastClose = last_close, - .deviceRead = NULL, - .deviceWrite = write_support_polled, - .deviceInitialize = initialize, - .deviceWritePolled = write_polled, - .deviceSetAttributes = set_attribues, - .deviceOutputUsesInterrupts = false -}; diff --git a/c/src/lib/libbsp/arm/lpc176x/Makefile.am b/c/src/lib/libbsp/arm/lpc176x/Makefile.am index 49e6620a9e..ba2475febb 100644 --- a/c/src/lib/libbsp/arm/lpc176x/Makefile.am +++ b/c/src/lib/libbsp/arm/lpc176x/Makefile.am @@ -59,9 +59,9 @@ librtemsbsp_a_SOURCES += ../shared/armv7m/irq/armv7m-irq-dispatch.c librtemsbsp_a_SOURCES += irq/irq.c # Console -librtemsbsp_a_SOURCES += ../../shared/console-termios-init.c -librtemsbsp_a_SOURCES += ../../shared/console-termios.c -librtemsbsp_a_SOURCES += console/console-config.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios-init.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc176x/console/console-config.c # Clock librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/clock/clock-nxp-lpc.c diff --git a/c/src/lib/libbsp/arm/lpc176x/console/console-config.c b/c/src/lib/libbsp/arm/lpc176x/console/console-config.c deleted file mode 100644 index c80932daf7..0000000000 --- a/c/src/lib/libbsp/arm/lpc176x/console/console-config.c +++ /dev/null @@ -1,192 +0,0 @@ -/** - * @file - * - * @ingroup lpc176x - * - * @brief Console configuration. - */ - -/* - * Copyright (c) 2008-2014 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include -#include -#include - -/** - * @brief Gets the uart register according to the current address. - * - * @param addr Register address. - * @param i Index register. - * @return Uart register. - */ -static inline uint8_t lpc176x_uart_get_register( - const uintptr_t addr, - const uint8_t i -) -{ - volatile uint32_t *reg = (volatile uint32_t *) addr; - - return (uint8_t) reg[ i ]; -} - -/** - * @brief Sets the uart register address according to the value passed. - * - * @param addr Register address. - * @param i Index register. - * @param val Value to set. - */ -static inline void lpc176x_uart_set_register( - const uintptr_t addr, - const uint8_t i, - const uint8_t val -) -{ - volatile uint32_t *reg = (volatile uint32_t *) addr; - - reg[ i ] = val; -} - -static bool lpc176x_uart1_probe(rtems_termios_device_context *ctx) -{ - (void)ctx; - - lpc176x_module_enable( LPC176X_MODULE_UART_1, LPC176X_MODULE_PCLK_DEFAULT ); - - lpc176x_pin_select( LPC176X_PIN_UART_1_TXD, LPC176X_PIN_FUNCTION_01 ); - lpc176x_pin_select( LPC176X_PIN_UART_1_RXD, LPC176X_PIN_FUNCTION_01 ); - - return true; -} - -#ifdef LPC176X_CONFIG_UART_2 -static bool lpc176x_uart2_probe(rtems_termios_device_context *ctx) -{ - (void)ctx; - - lpc176x_module_enable( LPC176X_MODULE_UART_2, LPC176X_MODULE_PCLK_DEFAULT ); - - lpc176x_pin_select( LPC176X_PIN_UART_2_TXD, LPC176X_PIN_FUNCTION_01 ); - lpc176x_pin_select( LPC176X_PIN_UART_2_RXD, LPC176X_PIN_FUNCTION_01 ); - - return true; -} -#endif - -#ifdef LPC176X_CONFIG_UART_3 -static bool lpc176x_uart3_probe(rtems_termios_device_context *ctx) -{ - (void)ctx; - - lpc176x_module_enable( LPC176X_MODULE_UART_3, LPC176X_MODULE_PCLK_DEFAULT ); - - lpc176x_pin_select( LPC176X_PIN_UART_3_TXD, LPC176X_PIN_FUNCTION_10 ); - lpc176x_pin_select( LPC176X_PIN_UART_3_RXD, LPC176X_PIN_FUNCTION_10 ); - - return true; -} -#endif - -#ifdef LPC176X_CONFIG_CONSOLE -static ns16550_context lpc176x_uart_context_0 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"), - .get_reg = lpc176x_uart_get_register, - .set_reg = lpc176x_uart_set_register, - .port = UART0_BASE_ADDR, - .irq = LPC176X_IRQ_UART_0, - .clock = LPC176X_PCLK, - .initial_baud = LPC176X_UART_BAUD, - .has_fractional_divider_register = true -}; -#endif - -#ifdef LPC176X_CONFIG_UART_1 -static ns16550_context lpc176x_uart_context_1 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"), - .get_reg = lpc176x_uart_get_register, - .set_reg = lpc176x_uart_set_register, - .port = UART1_BASE_ADDR, - .irq = LPC176X_IRQ_UART_1, - .clock = LPC176X_PCLK, - .initial_baud = LPC176X_UART_BAUD, - .has_fractional_divider_register = true -}; -#endif - -#ifdef LPC176X_CONFIG_UART_2 -static ns16550_context lpc176x_uart_context_2 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 2"), - .get_reg = lpc176x_uart_get_register, - .set_reg = lpc176x_uart_set_register, - .port = UART2_BASE_ADDR, - .irq = LPC176X_IRQ_UART_2, - .clock = LPC176X_PCLK, - .initial_baud = LPC176X_UART_BAUD, - .has_fractional_divider_register = true -}; -#endif - -#ifdef LPC176X_CONFIG_UART_3 -static ns16550_context lpc176x_uart_context_3 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 3"), - .get_reg = lpc176x_uart_get_register, - .set_reg = lpc176x_uart_set_register, - .port = UART3_BASE_ADDR, - .irq = LPC176X_IRQ_UART_3, - .clock = LPC176X_PCLK, - .initial_baud = LPC176X_UART_BAUD, - .has_fractional_divider_register = true -}; -#endif - -const console_device console_device_table[] = { - #ifdef LPC176X_CONFIG_CONSOLE - { - .device_file = "/dev/ttyS0", - .probe = console_device_probe_default, - .handler = &ns16550_handler_interrupt, - .context = &lpc176x_uart_context_0.base - }, - #endif - #ifdef LPC176X_CONFIG_UART_1 - { - .device_file = "/dev/ttyS1", - .probe = lpc176x_uart1_probe, - .handler = &ns16550_handler_interrupt, - .context = &lpc176x_uart_context_1.base - }, - #endif - #ifdef LPC176X_CONFIG_UART_2 - { - .device_file = "/dev/ttyS2", - .probe = lpc176x_uart2_probe, - .handler = &ns16550_handler_interrupt, - .context = &lpc176x_uart_context_2.base - }, - #endif - #ifdef LPC176X_CONFIG_UART_3 - { - .device_file = "/dev/ttyS3", - .probe = lpc176x_uart3_probe, - .handler = &ns16550_handler_interrupt, - .context = &lpc176x_uart_context_3.base - }, - #endif -}; - -const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table); diff --git a/c/src/lib/libbsp/arm/lpc24xx/Makefile.am b/c/src/lib/libbsp/arm/lpc24xx/Makefile.am index ee2b7b4da0..a597be7e05 100644 --- a/c/src/lib/libbsp/arm/lpc24xx/Makefile.am +++ b/c/src/lib/libbsp/arm/lpc24xx/Makefile.am @@ -71,12 +71,12 @@ librtemsbsp_a_SOURCES += irq/irq.c librtemsbsp_a_SOURCES += irq/irq-dispatch.c # Console -librtemsbsp_a_SOURCES += ../../shared/console-termios-init.c -librtemsbsp_a_SOURCES += ../../shared/console-termios.c -librtemsbsp_a_SOURCES += console/console-config.c -librtemsbsp_a_SOURCES += console/uart-probe-1.c -librtemsbsp_a_SOURCES += console/uart-probe-2.c -librtemsbsp_a_SOURCES += console/uart-probe-3.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios-init.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/console/console-config.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/console/uart-probe-1.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/console/uart-probe-2.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/console/uart-probe-3.c # Clock librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/clock/clock-nxp-lpc.c diff --git a/c/src/lib/libbsp/arm/lpc24xx/console/console-config.c b/c/src/lib/libbsp/arm/lpc24xx/console/console-config.c deleted file mode 100644 index de94552c27..0000000000 --- a/c/src/lib/libbsp/arm/lpc24xx/console/console-config.c +++ /dev/null @@ -1,134 +0,0 @@ -/** - * @file - * - * @ingroup lpc24xx - * - * @brief Console configuration. - */ - -/* - * Copyright (c) 2008-2014 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include - -#include -#include -#include -#include -#include - -static uint8_t lpc24xx_uart_get_register(uintptr_t addr, uint8_t i) -{ - volatile uint32_t *reg = (volatile uint32_t *) addr; - - return (uint8_t) reg [i]; -} - -static void lpc24xx_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val) -{ - volatile uint32_t *reg = (volatile uint32_t *) addr; - - reg [i] = val; -} - -#ifdef LPC24XX_CONFIG_CONSOLE -static ns16550_context lpc24xx_uart_context_0 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"), - .get_reg = lpc24xx_uart_get_register, - .set_reg = lpc24xx_uart_set_register, - .port = UART0_BASE_ADDR, - .irq = LPC24XX_IRQ_UART_0, - .clock = LPC24XX_PCLK, - .initial_baud = LPC24XX_UART_BAUD, - .has_fractional_divider_register = true -}; -#endif - -#ifdef LPC24XX_CONFIG_UART_1 -static ns16550_context lpc24xx_uart_context_1 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"), - .get_reg = lpc24xx_uart_get_register, - .set_reg = lpc24xx_uart_set_register, - .port = UART1_BASE_ADDR, - .irq = LPC24XX_IRQ_UART_1, - .clock = LPC24XX_PCLK, - .initial_baud = LPC24XX_UART_BAUD, - .has_fractional_divider_register = true -}; -#endif - -#ifdef LPC24XX_CONFIG_UART_2 -static ns16550_context lpc24xx_uart_context_2 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 2"), - .get_reg = lpc24xx_uart_get_register, - .set_reg = lpc24xx_uart_set_register, - .port = UART2_BASE_ADDR, - .irq = LPC24XX_IRQ_UART_2, - .clock = LPC24XX_PCLK, - .initial_baud = LPC24XX_UART_BAUD, - .has_fractional_divider_register = true -}; -#endif - -#ifdef LPC24XX_CONFIG_UART_3 -static ns16550_context lpc24xx_uart_context_3 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 3"), - .get_reg = lpc24xx_uart_get_register, - .set_reg = lpc24xx_uart_set_register, - .port = UART3_BASE_ADDR, - .irq = LPC24XX_IRQ_UART_3, - .clock = LPC24XX_PCLK, - .initial_baud = LPC24XX_UART_BAUD, - .has_fractional_divider_register = true -}; -#endif - -const console_device console_device_table[] = { - #ifdef LPC24XX_CONFIG_CONSOLE - { - .device_file = "/dev/ttyS0", - .probe = console_device_probe_default, - .handler = &ns16550_handler_interrupt, - .context = &lpc24xx_uart_context_0.base - }, - #endif - #ifdef LPC24XX_CONFIG_UART_1 - { - .device_file = "/dev/ttyS1", - .probe = lpc24xx_uart_probe_1, - .handler = &ns16550_handler_interrupt, - .context = &lpc24xx_uart_context_1.base - }, - #endif - #ifdef LPC24XX_CONFIG_UART_2 - { - .device_file = "/dev/ttyS2", - .probe = lpc24xx_uart_probe_2, - .handler = &ns16550_handler_interrupt, - .context = &lpc24xx_uart_context_2.base - }, - #endif - #ifdef LPC24XX_CONFIG_UART_3 - { - .device_file = "/dev/ttyS3", - .probe = lpc24xx_uart_probe_3, - .handler = &ns16550_handler_interrupt, - .context = &lpc24xx_uart_context_3.base - }, - #endif -}; - -const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table); diff --git a/c/src/lib/libbsp/arm/lpc24xx/console/uart-probe-1.c b/c/src/lib/libbsp/arm/lpc24xx/console/uart-probe-1.c deleted file mode 100644 index 3b5f08059f..0000000000 --- a/c/src/lib/libbsp/arm/lpc24xx/console/uart-probe-1.c +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file - * - * @ingroup lpc24xx - * - * @brief UART 1 probe. - */ - -/* - * Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include - -bool lpc24xx_uart_probe_1(rtems_termios_device_context *context) -{ - static const lpc24xx_pin_range pins [] = { - LPC24XX_PIN_UART_1_TXD_P0_15, - LPC24XX_PIN_UART_1_RXD_P0_16, - LPC24XX_PIN_TERMINAL - }; - - lpc24xx_module_enable(LPC24XX_MODULE_UART_1, LPC24XX_MODULE_PCLK_DEFAULT); - lpc24xx_pin_config(&pins [0], LPC24XX_PIN_SET_FUNCTION); - - return ns16550_probe(context); -} diff --git a/c/src/lib/libbsp/arm/lpc24xx/console/uart-probe-2.c b/c/src/lib/libbsp/arm/lpc24xx/console/uart-probe-2.c deleted file mode 100644 index d45dbb755b..0000000000 --- a/c/src/lib/libbsp/arm/lpc24xx/console/uart-probe-2.c +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file - * - * @ingroup lpc24xx - * - * @brief UART 2 probe. - */ - -/* - * Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include - -bool lpc24xx_uart_probe_2(rtems_termios_device_context *context) -{ - static const lpc24xx_pin_range pins [] = { - LPC24XX_PIN_UART_2_TXD_P0_10, - LPC24XX_PIN_UART_2_RXD_P0_11, - LPC24XX_PIN_TERMINAL - }; - - lpc24xx_module_enable(LPC24XX_MODULE_UART_2, LPC24XX_MODULE_PCLK_DEFAULT); - lpc24xx_pin_config(&pins [0], LPC24XX_PIN_SET_FUNCTION); - - return ns16550_probe(context); -} diff --git a/c/src/lib/libbsp/arm/lpc24xx/console/uart-probe-3.c b/c/src/lib/libbsp/arm/lpc24xx/console/uart-probe-3.c deleted file mode 100644 index fad932ef9e..0000000000 --- a/c/src/lib/libbsp/arm/lpc24xx/console/uart-probe-3.c +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file - * - * @ingroup lpc24xx - * - * @brief UART 3 probe. - */ - -/* - * Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include - -bool lpc24xx_uart_probe_3(rtems_termios_device_context *context) -{ - static const lpc24xx_pin_range pins [] = { - LPC24XX_PIN_UART_3_TXD_P0_0, - LPC24XX_PIN_UART_3_RXD_P0_1, - LPC24XX_PIN_TERMINAL - }; - - lpc24xx_module_enable(LPC24XX_MODULE_UART_3, LPC24XX_MODULE_PCLK_DEFAULT); - lpc24xx_pin_config(&pins [0], LPC24XX_PIN_SET_FUNCTION); - - return ns16550_probe(context); -} diff --git a/c/src/lib/libbsp/arm/lpc32xx/Makefile.am b/c/src/lib/libbsp/arm/lpc32xx/Makefile.am index 743b0722b3..d07607060d 100644 --- a/c/src/lib/libbsp/arm/lpc32xx/Makefile.am +++ b/c/src/lib/libbsp/arm/lpc32xx/Makefile.am @@ -59,10 +59,10 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c librtemsbsp_a_SOURCES += irq/irq.c # Console -librtemsbsp_a_SOURCES += ../../shared/console-termios-init.c -librtemsbsp_a_SOURCES += ../../shared/console-termios.c -librtemsbsp_a_SOURCES += console/console-config.c -librtemsbsp_a_SOURCES += console/hsu.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios-init.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc32xx/console/console-config.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc32xx/console/hsu.c # Clock librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/clock/clock-nxp-lpc.c diff --git a/c/src/lib/libbsp/arm/lpc32xx/console/console-config.c b/c/src/lib/libbsp/arm/lpc32xx/console/console-config.c deleted file mode 100644 index 17e6b0af8f..0000000000 --- a/c/src/lib/libbsp/arm/lpc32xx/console/console-config.c +++ /dev/null @@ -1,225 +0,0 @@ -/** - * @file - * - * @ingroup arm_lpc32xx - * - * @brief Console configuration. - */ - -/* - * Copyright (c) 2009-2014 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include -#include -#include -#include - -static uint8_t lpc32xx_uart_get_register(uintptr_t addr, uint8_t i) -{ - volatile uint32_t *reg = (volatile uint32_t *) addr; - - return (uint8_t) reg [i]; -} - -static void lpc32xx_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val) -{ - volatile uint32_t *reg = (volatile uint32_t *) addr; - - reg [i] = val; -} - -#ifdef LPC32XX_UART_3_BAUD - static bool lpc32xx_uart_probe_3(rtems_termios_device_context *context) - { - LPC32XX_UARTCLK_CTRL |= BSP_BIT32(0); - LPC32XX_U3CLK = LPC32XX_CONFIG_U3CLK; - LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 4, 5); - - return ns16550_probe(context); - } -#endif - -#ifdef LPC32XX_UART_4_BAUD - static bool lpc32xx_uart_probe_4(rtems_termios_device_context *context) - { - volatile lpc32xx_gpio *gpio = &lpc32xx.gpio; - - /* - * Set GPO_21/U4_TX/LCDVD[3] to U4_TX. This works only if LCD module is - * disabled. - */ - gpio->p2_mux_set = BSP_BIT32(2); - - LPC32XX_UARTCLK_CTRL |= BSP_BIT32(1); - LPC32XX_U4CLK = LPC32XX_CONFIG_U4CLK; - LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 6, 7); - - return ns16550_probe(context); - } -#endif - -#ifdef LPC32XX_UART_6_BAUD - static bool lpc32xx_uart_probe_6(rtems_termios_device_context *context) - { - /* Bypass the IrDA modulator/demodulator */ - LPC32XX_UART_CTRL |= BSP_BIT32(5); - - LPC32XX_UARTCLK_CTRL |= BSP_BIT32(3); - LPC32XX_U6CLK = LPC32XX_CONFIG_U6CLK; - LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 10, 11); - - return ns16550_probe(context); - } -#endif - -/* FIXME: Console selection */ - -#ifdef LPC32XX_UART_5_BAUD -static ns16550_context lpc32xx_uart_context_5 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 5"), - .get_reg = lpc32xx_uart_get_register, - .set_reg = lpc32xx_uart_set_register, - .port = LPC32XX_BASE_UART_5, - .irq = LPC32XX_IRQ_UART_5, - .clock = 16 * LPC32XX_UART_5_BAUD, - .initial_baud = LPC32XX_UART_5_BAUD -}; -#endif - -#ifdef LPC32XX_UART_3_BAUD -static ns16550_context lpc32xx_uart_context_3 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 3"), - .get_reg = lpc32xx_uart_get_register, - .set_reg = lpc32xx_uart_set_register, - .port = LPC32XX_BASE_UART_3, - .irq = LPC32XX_IRQ_UART_3, - .clock = 16 * LPC32XX_UART_3_BAUD, - .initial_baud = LPC32XX_UART_3_BAUD -}; -#endif - -#ifdef LPC32XX_UART_4_BAUD -static ns16550_context lpc32xx_uart_context_4 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 4"), - .get_reg = lpc32xx_uart_get_register, - .set_reg = lpc32xx_uart_set_register, - .port = LPC32XX_BASE_UART_4, - .irq = LPC32XX_IRQ_UART_4, - .clock = 16 * LPC32XX_UART_4_BAUD, - .initial_baud = LPC32XX_UART_4_BAUD -}; -#endif - -#ifdef LPC32XX_UART_6_BAUD -static ns16550_context lpc32xx_uart_context_6 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 6"), - .get_reg = lpc32xx_uart_get_register, - .set_reg = lpc32xx_uart_set_register, - .port = LPC32XX_BASE_UART_6, - .irq = LPC32XX_IRQ_UART_6, - .clock = 16 * LPC32XX_UART_6_BAUD, - .initial_baud = LPC32XX_UART_6_BAUD -}; -#endif - -#ifdef LPC32XX_UART_1_BAUD -static lpc32xx_hsu_context lpc32xx_uart_context_1 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"), - .hsu = (volatile lpc32xx_hsu *) LPC32XX_BASE_UART_1, - .irq = LPC32XX_IRQ_UART_1, - .initial_baud = LPC32XX_UART_1_BAUD -}; -#endif - -#ifdef LPC32XX_UART_2_BAUD -static lpc32xx_hsu_context lpc32xx_uart_context_2 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 2"), - .hsu = (volatile lpc32xx_hsu *) LPC32XX_BASE_UART_2, - .irq = LPC32XX_IRQ_UART_2, - .initial_baud = LPC32XX_UART_2_BAUD -}; -#endif - -#ifdef LPC32XX_UART_7_BAUD -static lpc32xx_hsu_context lpc32xx_uart_context_7 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 7"), - .hsu = (volatile lpc32xx_hsu *) LPC32XX_BASE_UART_7, - .irq = LPC32XX_IRQ_UART_7, - .initial_baud = LPC32XX_UART_7_BAUD -}; -#endif - -const console_device console_device_table[] = { - #ifdef LPC32XX_UART_5_BAUD - { - .device_file = "/dev/ttyS5", - .probe = console_device_probe_default, - .handler = &ns16550_handler_interrupt, - .context = &lpc32xx_uart_context_5.base - }, - #endif - #ifdef LPC32XX_UART_3_BAUD - { - .device_file = "/dev/ttyS3", - .probe = lpc32xx_uart_probe_3, - .handler = &ns16550_handler_interrupt, - .context = &lpc32xx_uart_context_3.base - }, - #endif - #ifdef LPC32XX_UART_4_BAUD - { - .device_file = "/dev/ttyS4", - .probe = lpc32xx_uart_probe_4, - .handler = &ns16550_handler_interrupt, - .context = &lpc32xx_uart_context_4.base - }, - #endif - #ifdef LPC32XX_UART_6_BAUD - { - .device_file = "/dev/ttyS6", - .probe = lpc32xx_uart_probe_6, - .handler = &ns16550_handler_interrupt, - .context = &lpc32xx_uart_context_6.base - }, - #endif - #ifdef LPC32XX_UART_1_BAUD - { - .device_file = "/dev/ttyS1", - .probe = lpc32xx_hsu_probe, - .handler = &lpc32xx_hsu_fns, - .context = &lpc32xx_uart_context_1.base - }, - #endif - #ifdef LPC32XX_UART_2_BAUD - { - .device_file = "/dev/ttyS2", - .probe = lpc32xx_hsu_probe, - .handler = &lpc32xx_hsu_fns, - .context = &lpc32xx_uart_context_2.base - }, - #endif - #ifdef LPC32XX_UART_7_BAUD - { - .device_file = "/dev/ttyS7", - .probe = lpc32xx_hsu_probe, - .handler = &lpc32xx_hsu_fns, - .context = &lpc32xx_uart_context_7.base - }, - #endif -}; - -const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table); diff --git a/c/src/lib/libbsp/arm/lpc32xx/console/hsu.c b/c/src/lib/libbsp/arm/lpc32xx/console/hsu.c deleted file mode 100644 index b2044e0753..0000000000 --- a/c/src/lib/libbsp/arm/lpc32xx/console/hsu.c +++ /dev/null @@ -1,208 +0,0 @@ -/** - * @file - * - * @ingroup arm_lpc32xx - * - * @brief High speed UART driver (14-clock). - */ - -/* - * Copyright (c) 2010-2014 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include - -#define HSU_FIFO_SIZE 64 - -#define HSU_LEVEL_RX_MASK 0xffU -#define HSU_LEVEL_TX_MASK 0xff00U -#define HSU_LEVEL_TX_SHIFT 8 - -#define HSU_RX_DATA_MASK 0xffU -#define HSU_RX_EMPTY (1U << 8) -#define HSU_RX_ERROR (1U << 9) -#define HSU_RX_BREAK (1U << 10) - -#define HSU_IIR_TX (1U << 0) -#define HSU_IIR_RX_TRIG (1U << 1) -#define HSU_IIR_RX_TIMEOUT (1U << 2) - -#define HSU_CTRL_INTR_DISABLED 0x1280fU -#define HSU_CTRL_RX_INTR_ENABLED 0x1284fU -#define HSU_CTRL_RX_AND_TX_INTR_ENABLED 0x1286fU - -/* We are interested in RX timeout, RX trigger and TX trigger interrupts */ -#define HSU_IIR_MASK 0x7U - -bool lpc32xx_hsu_probe(rtems_termios_device_context *base) -{ - lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base; - volatile lpc32xx_hsu *hsu = ctx->hsu; - - hsu->ctrl = HSU_CTRL_INTR_DISABLED; - - /* Drain FIFOs */ - while (hsu->level != 0) { - hsu->fifo; - } - - return true; -} - -static void lpc32xx_hsu_interrupt_handler(void *arg) -{ - rtems_termios_tty *tty = arg; - lpc32xx_hsu_context *ctx = rtems_termios_get_device_context(tty); - volatile lpc32xx_hsu *hsu = ctx->hsu; - - /* Iterate until no more interrupts are pending */ - do { - int rv = 0; - int i = 0; - char buf [HSU_FIFO_SIZE]; - - /* Enqueue received characters */ - while (i < HSU_FIFO_SIZE) { - uint32_t in = hsu->fifo; - - if ((in & HSU_RX_EMPTY) == 0) { - if ((in & HSU_RX_BREAK) == 0) { - buf [i] = in & HSU_RX_DATA_MASK; - ++i; - } - } else { - break; - } - } - rtems_termios_enqueue_raw_characters(tty, buf, i); - - /* Dequeue transmitted characters */ - rv = rtems_termios_dequeue_characters(tty, (int) ctx->chars_in_transmission); - if (rv == 0) { - /* Nothing to transmit */ - } - } while ((hsu->iir & HSU_IIR_MASK) != 0); -} - -static bool lpc32xx_hsu_first_open( - struct rtems_termios_tty *tty, - rtems_termios_device_context *base, - struct termios *term, - rtems_libio_open_close_args_t *args -) -{ - lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base; - volatile lpc32xx_hsu *hsu = ctx->hsu; - rtems_status_code sc; - bool ok; - - sc = rtems_interrupt_handler_install( - ctx->irq, - "HSU", - RTEMS_INTERRUPT_UNIQUE, - lpc32xx_hsu_interrupt_handler, - tty - ); - ok = sc == RTEMS_SUCCESSFUL; - - if (ok) { - rtems_termios_set_initial_baud(tty, ctx->initial_baud); - hsu->ctrl = HSU_CTRL_RX_INTR_ENABLED; - } - - return ok; -} - -static void lpc32xx_hsu_last_close( - struct rtems_termios_tty *tty, - rtems_termios_device_context *base, - rtems_libio_open_close_args_t *args -) -{ - lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base; - volatile lpc32xx_hsu *hsu = ctx->hsu; - - hsu->ctrl = HSU_CTRL_INTR_DISABLED; - - rtems_interrupt_handler_remove( - ctx->irq, - lpc32xx_hsu_interrupt_handler, - tty - ); -} - -static void lpc32xx_hsu_write( - rtems_termios_device_context *base, - const char *buf, - size_t len -) -{ - lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base; - volatile lpc32xx_hsu *hsu = ctx->hsu; - size_t tx_level = (hsu->level & HSU_LEVEL_TX_MASK) >> HSU_LEVEL_TX_SHIFT; - size_t tx_free = HSU_FIFO_SIZE - tx_level; - size_t i = 0; - size_t out = len > tx_free ? tx_free : len; - - for (i = 0; i < out; ++i) { - hsu->fifo = buf [i]; - } - - ctx->chars_in_transmission = out; - - if (len > 0) { - hsu->ctrl = HSU_CTRL_RX_AND_TX_INTR_ENABLED; - } else { - hsu->ctrl = HSU_CTRL_RX_INTR_ENABLED; - hsu->iir = HSU_IIR_TX; - } -} - -static bool lpc32xx_hsu_set_attributes( - rtems_termios_device_context *base, - const struct termios *term -) -{ - lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base; - volatile lpc32xx_hsu *hsu = ctx->hsu; - int baud_flags = term->c_ospeed; - - if (baud_flags != 0) { - int32_t baud = rtems_termios_baud_to_number(baud_flags); - - if (baud > 0) { - uint32_t baud_divisor = 14 * (uint32_t) baud; - uint32_t rate = LPC32XX_PERIPH_CLK / baud_divisor; - uint32_t remainder = LPC32XX_PERIPH_CLK - rate * baud_divisor; - - if (2 * remainder >= baud_divisor) { - ++rate; - } - - hsu->rate = rate - 1; - } - } - - return true; -} - -const rtems_termios_device_handler lpc32xx_hsu_fns = { - .first_open = lpc32xx_hsu_first_open, - .last_close = lpc32xx_hsu_last_close, - .write = lpc32xx_hsu_write, - .set_attributes = lpc32xx_hsu_set_attributes, - .mode = TERMIOS_IRQ_DRIVEN -}; diff --git a/c/src/lib/libbsp/arm/raspberrypi/Makefile.am b/c/src/lib/libbsp/arm/raspberrypi/Makefile.am index 58cfe1f237..106c0b43f9 100644 --- a/c/src/lib/libbsp/arm/raspberrypi/Makefile.am +++ b/c/src/lib/libbsp/arm/raspberrypi/Makefile.am @@ -16,7 +16,7 @@ dist_project_lib_DATA = startup/bsp_specs # Header # ############################################################################### -noinst_HEADERS = console/font_data.h +noinst_HEADERS = ../../../../../../bsps/arm/raspberrypi/console/font_data.h ############################################################################### # Data # @@ -68,12 +68,12 @@ librtemsbsp_a_SOURCES += irq/irq.c # Console librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c -librtemsbsp_a_SOURCES += console/console-config.c -librtemsbsp_a_SOURCES += console/console_select.c -librtemsbsp_a_SOURCES += console/usart.c -librtemsbsp_a_SOURCES += console/fb.c -librtemsbsp_a_SOURCES += console/fbcons.c -librtemsbsp_a_SOURCES += console/outch.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/raspberrypi/console/console-config.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/raspberrypi/console/console_select.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/raspberrypi/console/usart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/raspberrypi/console/fb.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/raspberrypi/console/fbcons.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/raspberrypi/console/outch.c # Mailbox librtemsbsp_a_SOURCES += misc/mailbox.c diff --git a/c/src/lib/libbsp/arm/raspberrypi/console/console-config.c b/c/src/lib/libbsp/arm/raspberrypi/console/console-config.c deleted file mode 100644 index d2186c918b..0000000000 --- a/c/src/lib/libbsp/arm/raspberrypi/console/console-config.c +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file - * - * @ingroup raspberrypi_usart - * - * @brief Console Configuration. - */ - -/* - * Copyright (c) 2015 Yang Qiao - * based on work by: - * Copyright (c) 2013 Alan Cudmore - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * - * http://www.rtems.org/license/LICENSE - * - */ - -#include - -#include - -#include -#include -#include -#include -#include - -console_tbl Console_Configuration_Ports [] = { - { - .sDeviceName = "/dev/ttyS0", - .deviceType = SERIAL_CUSTOM, - .pDeviceFns = &bcm2835_usart_fns, - .deviceProbe = NULL, - .pDeviceFlow = NULL, - .ulCtrlPort1 = BCM2835_UART0_BASE, - .ulCtrlPort2 = 0, - .ulClock = USART0_DEFAULT_BAUD, - .ulIntVector = BCM2835_IRQ_ID_UART - }, - { - .sDeviceName ="/dev/fbcons", - .deviceType = SERIAL_CUSTOM, - .pDeviceFns = &fbcons_fns, - .deviceProbe = fbcons_probe, - .pDeviceFlow = NULL, - }, -}; - -#define PORT_COUNT \ - (sizeof(Console_Configuration_Ports) \ - / sizeof(Console_Configuration_Ports [0])) - -unsigned long Console_Configuration_Count = PORT_COUNT; - -static void output_char(char c) -{ - const console_fns *con = - Console_Configuration_Ports [Console_Port_Minor].pDeviceFns; - - con->deviceWritePolled((int) Console_Port_Minor, c); -} - -BSP_output_char_function_type BSP_output_char = output_char; - -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/arm/raspberrypi/console/console_select.c b/c/src/lib/libbsp/arm/raspberrypi/console/console_select.c deleted file mode 100644 index 42c4944ebe..0000000000 --- a/c/src/lib/libbsp/arm/raspberrypi/console/console_select.c +++ /dev/null @@ -1,114 +0,0 @@ -/** - * @file - * - * @ingroup raspberrypi_console - * - * @brief console select - */ - -/* - * Copyright (c) 2015 Yang Qiao - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * - * http://www.rtems.org/license/LICENSE - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h" -#include - -rtems_device_minor_number BSPPrintkPort = 0; - -/* - * Method to return true if the device associated with the - * minor number probs available. - */ -static bool bsp_Is_Available( rtems_device_minor_number minor ) -{ - console_tbl *cptr = Console_Port_Tbl[ minor ]; - - /* - * First perform the configuration dependent probe, then the - * device dependent probe - */ - if ( ( !cptr->deviceProbe || cptr->deviceProbe( minor ) ) && - cptr->pDeviceFns->deviceProbe( minor ) ) { - return true; - } - - return false; -} - -/* - * Method to return the first available device. - */ -static rtems_device_minor_number bsp_First_Available_Device( void ) -{ - rtems_device_minor_number minor; - - for ( minor = 0; minor < Console_Port_Count; minor++ ) { - console_tbl *cptr = Console_Port_Tbl[ minor ]; - - /* - * First perform the configuration dependent probe, then the - * device dependent probe - */ - - if ( ( !cptr->deviceProbe || cptr->deviceProbe( minor ) ) && - cptr->pDeviceFns->deviceProbe( minor ) ) { - return minor; - } - } - - /* - * Error No devices were found. We will want to bail here. - */ - bsp_fatal( BSP_FATAL_CONSOLE_NO_DEV ); -} - -void bsp_console_select( void ) -{ - /* - * Reset Console_Port_Minor and - * BSPPrintkPort here if desired. - * - * This default version allows the bsp to set these - * values at creation and will not touch them again - * unless the selected port number is not available. - */ - const char *opt; - - Console_Port_Minor = BSP_CONSOLE_UART0; - BSPPrintkPort = BSP_CONSOLE_UART0; - - opt = rpi_cmdline_get_arg( "--console=" ); - - if ( opt ) { - if ( strncmp( opt, "fbcons", sizeof( "fbcons" ) - 1 ) == 0 ) { - if ( rpi_video_is_initialized() > 0 ) { - Console_Port_Minor = BSP_CONSOLE_FB; - BSPPrintkPort = BSP_CONSOLE_FB; - } - } - } - - /* - * If the device that was selected isn't available then - * let the user know and select the first available device. - */ - if ( !bsp_Is_Available( Console_Port_Minor ) ) { - Console_Port_Minor = bsp_First_Available_Device(); - } -} diff --git a/c/src/lib/libbsp/arm/raspberrypi/console/fb.c b/c/src/lib/libbsp/arm/raspberrypi/console/fb.c deleted file mode 100644 index 815d17e8ca..0000000000 --- a/c/src/lib/libbsp/arm/raspberrypi/console/fb.c +++ /dev/null @@ -1,437 +0,0 @@ -/** - * @file - * - * @ingroup raspberrypi - * - * @brief framebuffer support. - */ - -/* - * Copyright (c) 2015 Yang Qiao - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * - * http://www.rtems.org/license/LICENSE - * - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#define SCREEN_WIDTH 1024 -#define SCREEN_HEIGHT 768 -#define BPP 32 - -/* flag to limit driver to protect against multiple opens */ -static Atomic_Flag driver_mutex; - -/* - * screen information for the driver (fb0). - */ - -static struct fb_var_screeninfo fb_var_info = { - .xres = SCREEN_WIDTH, - .yres = SCREEN_HEIGHT, - .bits_per_pixel = BPP -}; - -static struct fb_fix_screeninfo fb_fix_info = { - .smem_start = (void *) NULL, - .smem_len = 0, - .type = FB_TYPE_PACKED_PIXELS, - .visual = FB_VISUAL_TRUECOLOR, - .line_length = 0 -}; - -typedef enum { - NO_SUITABLE_MODE = -1, - BAD_FORMAT = -2, - AUTO_SELECT = -3, - DONT_INIT = -4, - NO_MODE_REQ = -5, -} mode_err_ret_val; - -int rpi_get_fix_screen_info( struct fb_fix_screeninfo *info ) -{ - *info = fb_fix_info; - return 0; -} - -int rpi_get_var_screen_info( struct fb_var_screeninfo *info ) -{ - *info = fb_var_info; - return 0; -} - -/** - * @brief Find mode given in string format. - * - * expected format - * x[-] - * numbers , and are decadic - * - * @param[out] fb_var_ptr pointer to variable mode part filled by function - * @param[in] video_string string to be parsed - * @retval video mode number to be set - * @retval -1 no suitable mode found - * @retval -2 bad format of the video_string - * @retval -3 automatic mode selection requested - * @retval -4 request to not initialize graphics - * @retval -5 no mode requested/empty video string - */ - -static int parse_mode_from_string( - struct fb_var_screeninfo *fb_var_ptr, - const char *video_string -) -{ - const char *opt; - char *endptr; - uint32_t width; - uint32_t height; - uint32_t bpp = 0; - - opt = video_string; - - if ( opt == NULL ) - return NO_MODE_REQ; - - if ( strncmp( opt, "auto", 4 ) == 0 ) - return AUTO_SELECT; - - if ( strncmp( opt, "none", 4 ) == 0 || - strncmp( opt, "off", 3 ) == 0 ) - return DONT_INIT; - - width = strtol( opt, &endptr, 10 ); - - if ( *endptr != 'x' ) { - return BAD_FORMAT; - } - - opt = endptr + 1; - height = strtol( opt, &endptr, 10 ); - - switch ( *endptr ) { - case '-': - opt = endptr + 1; - endptr = NULL; - bpp = strtol( opt, &endptr, 10 ); - - if ( ( endptr == opt ) || ( endptr == NULL ) ) - return BAD_FORMAT; - - if ( *endptr && ( *endptr != ' ' ) ) - return BAD_FORMAT; - - break; - case ' ': - case 0: - break; - default: - return BAD_FORMAT; - } - - fb_var_ptr->xres = width; - fb_var_ptr->yres = height; - - if ( bpp != 0 ) - fb_var_ptr->bits_per_pixel = bpp; - - return 0; -} - -static int find_mode_from_vc( void ) -{ - int res; - unsigned int width; - unsigned int height; - bcm2835_get_display_size_entries entries; - - res = bcm2835_mailbox_get_display_size( &entries ); - - width = entries.width; - height = entries.height; - - if ( width == 0 || height == 0 ) { - fb_var_info.xres = SCREEN_WIDTH; - fb_var_info.yres = SCREEN_HEIGHT; - } else { - fb_var_info.xres = width; - fb_var_info.yres = height; - } - printk("find_mode_from_vc %u x %u, res %d\n", width, height, res); - - return res; -} - -bool rpi_fb_hdmi_is_present( void ) -{ - bcm2835_get_display_size_entries entries; - - memset( &entries, 0, sizeof( entries ) ); - bcm2835_mailbox_get_display_size( &entries ); - - /* Impossible display dimension */ - if ( ( entries.width < 10 ) || ( entries.height < 10 ) ) - return false; - - /* Know default values reported when monitor is not present */ - if ( ( entries.width == 0x290 ) && ( entries.height == 0x1A0 ) ) - return false; - - return true; -} - -int rpi_fb_init( void ) -{ - int res; - int mode_from_cmdline; - bcm2835_init_frame_buffer_entries init_frame_buffer_entries; - - if ( fb_fix_info.smem_start != NULL ) { - return RPI_FB_INIT_ALREADY_INITIALIZED; - } - - if ( rpi_fb_hdmi_is_present() == false ) { - return RPI_FB_INIT_NO_DISPLAY; - } - - mode_from_cmdline = parse_mode_from_string( &fb_var_info, - rpi_cmdline_get_arg( "--video=" ) ); - - switch ( mode_from_cmdline ) { - case BAD_FORMAT: - return RPI_FB_INIT_CMDLINE_BAD_FORMAT; - case AUTO_SELECT: - break; - case DONT_INIT: - return RPI_FB_INIT_CMDLINE_DONT_INIT; - case NO_MODE_REQ: - return RPI_FB_INIT_CMDLINE_NO_MODE_REQ; - } - - if ( mode_from_cmdline ) { - if ( find_mode_from_vc() ) - return RPI_FB_INIT_MODE_PROBE_ERROR; - } - - memset( &init_frame_buffer_entries, 0, sizeof( init_frame_buffer_entries ) ); - init_frame_buffer_entries.xres = fb_var_info.xres; - init_frame_buffer_entries.yres = fb_var_info.yres; - init_frame_buffer_entries.xvirt = fb_var_info.xres; - init_frame_buffer_entries.yvirt = fb_var_info.yres; - init_frame_buffer_entries.depth = fb_var_info.bits_per_pixel; - init_frame_buffer_entries.pixel_order = bcm2835_mailbox_pixel_order_rgb; - init_frame_buffer_entries.alpha_mode = bcm2835_mailbox_alpha_mode_0_opaque; - init_frame_buffer_entries.voffset_x = 0; - init_frame_buffer_entries.voffset_y = 0; - init_frame_buffer_entries.overscan_left = 0; - init_frame_buffer_entries.overscan_right = 0; - init_frame_buffer_entries.overscan_top = 0; - init_frame_buffer_entries.overscan_bottom = 0; - printk("bcm2835_mailbox_init_frame_buffer ...\n"); - res = bcm2835_mailbox_init_frame_buffer( &init_frame_buffer_entries ); - printk("bcm2835_mailbox_init_frame_buffer returned %d\n", res); - if (res != 0) { - printk("bcm2835_mailbox_init_frame_buffer retry ...\n"); - res = bcm2835_mailbox_init_frame_buffer( &init_frame_buffer_entries ); - printk("bcm2835_mailbox_init_frame_buffer returned %d\n", res); - if (res != 0) - return RPI_FB_INIT_SETUP_FAILED; - } - - bcm2835_get_pitch_entries get_pitch_entries; - bcm2835_mailbox_get_pitch( &get_pitch_entries ); - - fb_var_info.xres = init_frame_buffer_entries.xres; - fb_var_info.yres = init_frame_buffer_entries.yres; - fb_var_info.bits_per_pixel = init_frame_buffer_entries.depth; - fb_fix_info.smem_start = (void *) init_frame_buffer_entries.base; - fb_fix_info.smem_len = init_frame_buffer_entries.size; - fb_fix_info.line_length = get_pitch_entries.pitch; - - if ( fb_fix_info.smem_start == NULL ) - return RPI_FB_INIT_START_ADDR_UNKNOWN; - - printk("fb_fix_info.smem_start %p\n", fb_fix_info.smem_start); - - arm_cp15_set_translation_table_entries( (void *) fb_fix_info.smem_start, - (void *) fb_fix_info.smem_start + - fb_fix_info.smem_len, - ARMV7_MMU_DATA_READ_WRITE_CACHED ); - - return RPI_FB_INIT_OK; -} - -/* - * fbds device driver initialize entry point. - */ - -rtems_device_driver frame_buffer_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - - /* register the devices */ - status = rtems_io_register_name( FRAMEBUFFER_DEVICE_0_NAME, major, 0 ); - - if ( status != RTEMS_SUCCESSFUL ) { - printk( "[!] error registering framebuffer\n" ); - rtems_fatal_error_occurred( status ); - } - - _Atomic_Flag_clear( &driver_mutex, ATOMIC_ORDER_RELEASE ); - return RTEMS_SUCCESSFUL; -} - -/* - * fbds device driver open operation. - */ - -rtems_device_driver frame_buffer_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - if ( _Atomic_Flag_test_and_set( &driver_mutex, - ATOMIC_ORDER_ACQUIRE ) != 0 ) { - printk( "RaspberryPi framebuffer could not lock driver_mutex\n" ); - return RTEMS_UNSATISFIED; - } - - if ( fb_fix_info.smem_start == NULL ) { - int res; - res = rpi_fb_init(); - if ( (res < RPI_FB_INIT_OK) || (fb_fix_info.smem_start == NULL) ) { - _Atomic_Flag_clear( &driver_mutex, ATOMIC_ORDER_RELEASE ); - printk( "RaspberryPi framebuffer initialization failed\n" ); - return RTEMS_UNSATISFIED; - } - } - - memset( (void *) fb_fix_info.smem_start, 0, fb_fix_info.smem_len ); - return RTEMS_SUCCESSFUL; -} - -/* - * fbds device driver close operation. - */ - -rtems_device_driver frame_buffer_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - /* restore previous state. for VGA this means return to text mode. - * leave out if graphics hardware has been initialized in - * frame_buffer_initialize() */ - memset( (void *) fb_fix_info.smem_start, 0, fb_fix_info.smem_len ); - _Atomic_Flag_clear( &driver_mutex, ATOMIC_ORDER_RELEASE ); - return RTEMS_SUCCESSFUL; -} - -/* - * fbds device driver read operation. - */ - -rtems_device_driver frame_buffer_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg; - - rw_args->bytes_moved = - ( ( rw_args->offset + rw_args->count ) > fb_fix_info.smem_len ) ? - ( fb_fix_info.smem_len - rw_args->offset ) : rw_args->count; - memcpy( rw_args->buffer, - (const void *) ( fb_fix_info.smem_start + rw_args->offset ), - rw_args->bytes_moved ); - return RTEMS_SUCCESSFUL; -} - -/* - * fbds device driver write operation. - */ - -rtems_device_driver frame_buffer_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg; - - rw_args->bytes_moved = - ( ( rw_args->offset + rw_args->count ) > fb_fix_info.smem_len ) ? - ( fb_fix_info.smem_len - rw_args->offset ) : rw_args->count; - memcpy( (void *) ( fb_fix_info.smem_start + rw_args->offset ), - rw_args->buffer, - rw_args->bytes_moved ); - return RTEMS_SUCCESSFUL; -} - -/* - * ioctl entry point. - */ - -rtems_device_driver frame_buffer_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_libio_ioctl_args_t *args = arg; - - /* XXX check minor */ - - switch ( args->command ) { - case FBIOGET_VSCREENINFO: - memcpy( args->buffer, &fb_var_info, sizeof( fb_var_info ) ); - args->ioctl_return = 0; - break; - case FBIOGET_FSCREENINFO: - memcpy( args->buffer, &fb_fix_info, sizeof( fb_fix_info ) ); - args->ioctl_return = 0; - break; - case FBIOGETCMAP: - /* no palette - truecolor mode */ - args->ioctl_return = -1; - return RTEMS_UNSATISFIED; - case FBIOPUTCMAP: - /* no palette - truecolor mode */ - args->ioctl_return = -1; - return RTEMS_UNSATISFIED; - default: - args->ioctl_return = -1; - return RTEMS_UNSATISFIED; - } - - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/lib/libbsp/arm/raspberrypi/console/fbcons.c b/c/src/lib/libbsp/arm/raspberrypi/console/fbcons.c deleted file mode 100644 index 3669ba458d..0000000000 --- a/c/src/lib/libbsp/arm/raspberrypi/console/fbcons.c +++ /dev/null @@ -1,177 +0,0 @@ -/** - * @file - * - * @ingroup raspberrypi_console - * - * @brief framebuffer graphic console support. - */ - -/* - * Copyright (c) 2015 Yang Qiao - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * - * http://www.rtems.org/license/LICENSE - * - */ - -#include -#include - -#include - -#include -#include - -#include -#include -#include -#include - -/* - * fbcons_init - * - * This function initializes the fb console to a quiecsent state. - */ -static void fbcons_init( int minor ) -{ -} - -/* - * fbcons_open - * - * This function opens a port for communication. - * - * Default state is 9600 baud, 8 bits, No parity, and 1 stop bit. - */ -static int fbcons_open( - int major, - int minor, - void *arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * fbcons_close - * - * This function shuts down the requested port. - */ -static int fbcons_close( - int major, - int minor, - void *arg -) -{ - return ( RTEMS_SUCCESSFUL ); -} - -/* - * fbcons_write_polled - * - * This routine polls out the requested character. - */ -static void fbcons_write_polled( - int minor, - char c -) -{ - rpi_fb_outch( c ); - - if ( c == '\n' ) - rpi_fb_outch( '\r' ); /* LF = LF + CR */ -} - -/* - * fbcons_write_support_polled - * - * Console Termios output entry point when using polled output. - * - */ -static ssize_t fbcons_write_support_polled( - int minor, - const char *buf, - size_t len -) -{ - int nwrite = 0; - - /* - * poll each byte in the string out of the port. - */ - while ( nwrite < len ) { - fbcons_write_polled( minor, *buf++ ); - nwrite++; - } - - /* - * return the number of bytes written. - */ - return nwrite; -} - -/* - * fbcons_inbyte_nonblocking_polled - * - * Console Termios polling input entry point. - */ -static int fbcons_inbyte_nonblocking_polled( int minor ) -{ - // if( rtems_kbpoll() ) { - // int c = getch(); - // return c; - // } - - return -1; -} - -/* - * fbcons_set_attributes - * - * This function sets the UART channel to reflect the requested termios - * port settings. - */ -static int fbcons_set_attributes( - int minor, - const struct termios *t -) -{ - return 0; -} - -bool fbcons_probe( int minor ) -{ - // rtems_status_code status; - static bool firstTime = true; - static bool ret = false; - - /* - * keyboard interrupt should be registered when the keyboard is available - */ - if ( firstTime ) { - if ( !rpi_fb_hdmi_is_present() ) { - ret = false; - } else { - ret = true; - } - } - - firstTime = false; - - return ret; -} - -const console_fns fbcons_fns = -{ - .deviceProbe = libchip_serial_default_probe, /* deviceProbe */ - .deviceFirstOpen = fbcons_open, /* deviceFirstOpen */ - .deviceLastClose = fbcons_close, /* deviceLastClose */ - .deviceRead = fbcons_inbyte_nonblocking_polled, /* deviceRead */ - .deviceWrite = fbcons_write_support_polled, /* deviceWrite */ - .deviceInitialize = fbcons_init, /* deviceInitialize */ - .deviceWritePolled = fbcons_write_polled, /* deviceWritePolled */ - .deviceSetAttributes = fbcons_set_attributes, /* deviceSetAttributes */ - .deviceOutputUsesInterrupts = FALSE, /* deviceOutputUsesInterrupts*/ -}; diff --git a/c/src/lib/libbsp/arm/raspberrypi/console/font_data.h b/c/src/lib/libbsp/arm/raspberrypi/console/font_data.h deleted file mode 100644 index 852310cbf9..0000000000 --- a/c/src/lib/libbsp/arm/raspberrypi/console/font_data.h +++ /dev/null @@ -1,4639 +0,0 @@ -/** - * @file - * - * @ingroup raspberrypi - * - * @brief graphic text console font file - * - */ -/* - * Copyright (c) 2015 Yang Qiao - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * - * http://www.rtems.org/license/LICENSE - * - */ - -#ifndef LIBBSP_ARM_RASPBERRYPI_FONT_DATA_H -#define LIBBSP_ARM_RASPBERRYPI_FONT_DATA_H - -#define RPI_FONT_CHARS 256 -#define RPI_FONT_WIDTH 8 -#define RPI_FONT_HEIGHT 16 -#define RPI_FONT_SIZE (RPI_FONT_CHARS * RPI_FONT_HEIGHT) - -static unsigned char rpi_font[RPI_FONT_SIZE] = { - - /* 0 0x00 '^@' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 1 0x01 '^A' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x81, /* 10000001 */ - 0xa5, /* 10100101 */ - 0x81, /* 10000001 */ - 0x81, /* 10000001 */ - 0xbd, /* 10111101 */ - 0x99, /* 10011001 */ - 0x81, /* 10000001 */ - 0x81, /* 10000001 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 2 0x02 '^B' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0xff, /* 11111111 */ - 0xdb, /* 11011011 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xc3, /* 11000011 */ - 0xe7, /* 11100111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 3 0x03 '^C' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x6c, /* 01101100 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0x7c, /* 01111100 */ - 0x38, /* 00111000 */ - 0x10, /* 00010000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 4 0x04 '^D' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x7c, /* 01111100 */ - 0xfe, /* 11111110 */ - 0x7c, /* 01111100 */ - 0x38, /* 00111000 */ - 0x10, /* 00010000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 5 0x05 '^E' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0xe7, /* 11100111 */ - 0xe7, /* 11100111 */ - 0xe7, /* 11100111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 6 0x06 '^F' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x7e, /* 01111110 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 7 0x07 '^G' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 8 0x08 '^H' */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xe7, /* 11100111 */ - 0xc3, /* 11000011 */ - 0xc3, /* 11000011 */ - 0xe7, /* 11100111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - - /* 9 0x09 '^I' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x42, /* 01000010 */ - 0x42, /* 01000010 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 10 0x0a '^J' */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xc3, /* 11000011 */ - 0x99, /* 10011001 */ - 0xbd, /* 10111101 */ - 0xbd, /* 10111101 */ - 0x99, /* 10011001 */ - 0xc3, /* 11000011 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - - /* 11 0x0b '^K' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1e, /* 00011110 */ - 0x0e, /* 00001110 */ - 0x1a, /* 00011010 */ - 0x32, /* 00110010 */ - 0x78, /* 01111000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 12 0x0c '^L' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 13 0x0d '^M' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3f, /* 00111111 */ - 0x33, /* 00110011 */ - 0x3f, /* 00111111 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x70, /* 01110000 */ - 0xf0, /* 11110000 */ - 0xe0, /* 11100000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 14 0x0e '^N' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7f, /* 01111111 */ - 0x63, /* 01100011 */ - 0x7f, /* 01111111 */ - 0x63, /* 01100011 */ - 0x63, /* 01100011 */ - 0x63, /* 01100011 */ - 0x63, /* 01100011 */ - 0x67, /* 01100111 */ - 0xe7, /* 11100111 */ - 0xe6, /* 11100110 */ - 0xc0, /* 11000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 15 0x0f '^O' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xdb, /* 11011011 */ - 0x3c, /* 00111100 */ - 0xe7, /* 11100111 */ - 0x3c, /* 00111100 */ - 0xdb, /* 11011011 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 16 0x10 '^P' */ - 0x00, /* 00000000 */ - 0x80, /* 10000000 */ - 0xc0, /* 11000000 */ - 0xe0, /* 11100000 */ - 0xf0, /* 11110000 */ - 0xf8, /* 11111000 */ - 0xfe, /* 11111110 */ - 0xf8, /* 11111000 */ - 0xf0, /* 11110000 */ - 0xe0, /* 11100000 */ - 0xc0, /* 11000000 */ - 0x80, /* 10000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 17 0x11 '^Q' */ - 0x00, /* 00000000 */ - 0x02, /* 00000010 */ - 0x06, /* 00000110 */ - 0x0e, /* 00001110 */ - 0x1e, /* 00011110 */ - 0x3e, /* 00111110 */ - 0xfe, /* 11111110 */ - 0x3e, /* 00111110 */ - 0x1e, /* 00011110 */ - 0x0e, /* 00001110 */ - 0x06, /* 00000110 */ - 0x02, /* 00000010 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 18 0x12 '^R' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 19 0x13 '^S' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 20 0x14 '^T' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7f, /* 01111111 */ - 0xdb, /* 11011011 */ - 0xdb, /* 11011011 */ - 0xdb, /* 11011011 */ - 0x7b, /* 01111011 */ - 0x1b, /* 00011011 */ - 0x1b, /* 00011011 */ - 0x1b, /* 00011011 */ - 0x1b, /* 00011011 */ - 0x1b, /* 00011011 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 21 0x15 '^U' */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0x60, /* 01100000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x0c, /* 00001100 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 22 0x16 '^V' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 23 0x17 '^W' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 24 0x18 '^X' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 25 0x19 '^Y' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 26 0x1a '^Z' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0xfe, /* 11111110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 27 0x1b '^[' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xfe, /* 11111110 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 28 0x1c '^\' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 29 0x1d '^]' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x28, /* 00101000 */ - 0x6c, /* 01101100 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x28, /* 00101000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 30 0x1e '^^' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x38, /* 00111000 */ - 0x7c, /* 01111100 */ - 0x7c, /* 01111100 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 31 0x1f '^_' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0x7c, /* 01111100 */ - 0x7c, /* 01111100 */ - 0x38, /* 00111000 */ - 0x38, /* 00111000 */ - 0x10, /* 00010000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 32 0x20 ' ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 33 0x21 '!' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 34 0x22 '"' */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x24, /* 00100100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 35 0x23 '#' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 36 0x24 '$' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc2, /* 11000010 */ - 0xc0, /* 11000000 */ - 0x7c, /* 01111100 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x86, /* 10000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 37 0x25 '%' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc2, /* 11000010 */ - 0xc6, /* 11000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc6, /* 11000110 */ - 0x86, /* 10000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 38 0x26 '&' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 39 0x27 ''' */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 40 0x28 '(' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 41 0x29 ')' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 42 0x2a '*' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0xff, /* 11111111 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 43 0x2b '+' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 44 0x2c ',' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 45 0x2d '-' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 46 0x2e '.' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 47 0x2f '/' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x02, /* 00000010 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0x80, /* 10000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 48 0x30 '0' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 49 0x31 '1' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x38, /* 00111000 */ - 0x78, /* 01111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 50 0x32 '2' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 51 0x33 '3' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x3c, /* 00111100 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 52 0x34 '4' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x0c, /* 00001100 */ - 0x1c, /* 00011100 */ - 0x3c, /* 00111100 */ - 0x6c, /* 01101100 */ - 0xcc, /* 11001100 */ - 0xfe, /* 11111110 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x1e, /* 00011110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 53 0x35 '5' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xfc, /* 11111100 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 54 0x36 '6' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xfc, /* 11111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 55 0x37 '7' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 56 0x38 '8' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 57 0x39 '9' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7e, /* 01111110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 58 0x3a ':' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 59 0x3b ';' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 60 0x3c '<' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x06, /* 00000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 61 0x3d '=' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 62 0x3e '>' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 63 0x3f '?' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 64 0x40 '@' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xde, /* 11011110 */ - 0xde, /* 11011110 */ - 0xde, /* 11011110 */ - 0xdc, /* 11011100 */ - 0xc0, /* 11000000 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 65 0x41 'A' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 66 0x42 'B' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfc, /* 11111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0xfc, /* 11111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 67 0x43 'C' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0xc2, /* 11000010 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc2, /* 11000010 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 68 0x44 'D' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xf8, /* 11111000 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0xf8, /* 11111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 69 0x45 'E' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x66, /* 01100110 */ - 0x62, /* 01100010 */ - 0x68, /* 01101000 */ - 0x78, /* 01111000 */ - 0x68, /* 01101000 */ - 0x60, /* 01100000 */ - 0x62, /* 01100010 */ - 0x66, /* 01100110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 70 0x46 'F' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x66, /* 01100110 */ - 0x62, /* 01100010 */ - 0x68, /* 01101000 */ - 0x78, /* 01111000 */ - 0x68, /* 01101000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 71 0x47 'G' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0xc2, /* 11000010 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xde, /* 11011110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x66, /* 01100110 */ - 0x3a, /* 00111010 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 72 0x48 'H' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 73 0x49 'I' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 74 0x4a 'J' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1e, /* 00011110 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 75 0x4b 'K' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xe6, /* 11100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0x78, /* 01111000 */ - 0x78, /* 01111000 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 76 0x4c 'L' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xf0, /* 11110000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x62, /* 01100010 */ - 0x66, /* 01100110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 77 0x4d 'M' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xee, /* 11101110 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0xd6, /* 11010110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 78 0x4e 'N' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xe6, /* 11100110 */ - 0xf6, /* 11110110 */ - 0xfe, /* 11111110 */ - 0xde, /* 11011110 */ - 0xce, /* 11001110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 79 0x4f 'O' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 80 0x50 'P' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfc, /* 11111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 81 0x51 'Q' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xd6, /* 11010110 */ - 0xde, /* 11011110 */ - 0x7c, /* 01111100 */ - 0x0c, /* 00001100 */ - 0x0e, /* 00001110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 82 0x52 'R' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfc, /* 11111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 83 0x53 'S' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x60, /* 01100000 */ - 0x38, /* 00111000 */ - 0x0c, /* 00001100 */ - 0x06, /* 00000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 84 0x54 'T' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x5a, /* 01011010 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 85 0x55 'U' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 86 0x56 'V' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x10, /* 00010000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 87 0x57 'W' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xfe, /* 11111110 */ - 0xee, /* 11101110 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 88 0x58 'X' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x7c, /* 01111100 */ - 0x38, /* 00111000 */ - 0x38, /* 00111000 */ - 0x7c, /* 01111100 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 89 0x59 'Y' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 90 0x5a 'Z' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0x86, /* 10000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc2, /* 11000010 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 91 0x5b '[' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 92 0x5c '\' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x80, /* 10000000 */ - 0xc0, /* 11000000 */ - 0xe0, /* 11100000 */ - 0x70, /* 01110000 */ - 0x38, /* 00111000 */ - 0x1c, /* 00011100 */ - 0x0e, /* 00001110 */ - 0x06, /* 00000110 */ - 0x02, /* 00000010 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 93 0x5d ']' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 94 0x5e '^' */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 95 0x5f '_' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 96 0x60 '`' */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 97 0x61 'a' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 98 0x62 'b' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xe0, /* 11100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x78, /* 01111000 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 99 0x63 'c' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 100 0x64 'd' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1c, /* 00011100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x3c, /* 00111100 */ - 0x6c, /* 01101100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 101 0x65 'e' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 102 0x66 'f' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1c, /* 00011100 */ - 0x36, /* 00110110 */ - 0x32, /* 00110010 */ - 0x30, /* 00110000 */ - 0x78, /* 01111000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 103 0x67 'g' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x7c, /* 01111100 */ - 0x0c, /* 00001100 */ - 0xcc, /* 11001100 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - - /* 104 0x68 'h' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xe0, /* 11100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x6c, /* 01101100 */ - 0x76, /* 01110110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 105 0x69 'i' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 106 0x6a 'j' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x00, /* 00000000 */ - 0x0e, /* 00001110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* 107 0x6b 'k' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xe0, /* 11100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0x78, /* 01111000 */ - 0x78, /* 01111000 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 108 0x6c 'l' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 109 0x6d 'm' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xec, /* 11101100 */ - 0xfe, /* 11111110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 110 0x6e 'n' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xdc, /* 11011100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 111 0x6f 'o' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 112 0x70 'p' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xdc, /* 11011100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - - /* 113 0x71 'q' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x7c, /* 01111100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x1e, /* 00011110 */ - 0x00, /* 00000000 */ - - /* 114 0x72 'r' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xdc, /* 11011100 */ - 0x76, /* 01110110 */ - 0x66, /* 01100110 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 115 0x73 's' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0x60, /* 01100000 */ - 0x38, /* 00111000 */ - 0x0c, /* 00001100 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 116 0x74 't' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0xfc, /* 11111100 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x36, /* 00110110 */ - 0x1c, /* 00011100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 117 0x75 'u' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 118 0x76 'v' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 119 0x77 'w' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 120 0x78 'x' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x38, /* 00111000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 121 0x79 'y' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7e, /* 01111110 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0xf8, /* 11111000 */ - 0x00, /* 00000000 */ - - /* 122 0x7a 'z' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xcc, /* 11001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 123 0x7b '{' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x0e, /* 00001110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x70, /* 01110000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x0e, /* 00001110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 124 0x7c '|' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 125 0x7d '}' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x70, /* 01110000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x0e, /* 00001110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 126 0x7e '~' */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 127 0x7f */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 128 0x80 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0xc2, /* 11000010 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc2, /* 11000010 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 129 0x81 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 130 0x82 */ - 0x00, /* 00000000 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 131 0x83 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 132 0x84 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 133 0x85 */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 134 0x86 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 135 0x87 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x18, /* 00011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 136 0x88 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 137 0x89 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 138 0x8a */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 139 0x8b */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 140 0x8c */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 141 0x8d */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 142 0x8e */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 143 0x8f */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 144 0x90 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x66, /* 01100110 */ - 0x62, /* 01100010 */ - 0x68, /* 01101000 */ - 0x78, /* 01111000 */ - 0x68, /* 01101000 */ - 0x62, /* 01100010 */ - 0x66, /* 01100110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 145 0x91 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xec, /* 11101100 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x7e, /* 01111110 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0x6e, /* 01101110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 146 0x92 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3e, /* 00111110 */ - 0x6c, /* 01101100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xfe, /* 11111110 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xce, /* 11001110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 147 0x93 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 148 0x94 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 149 0x95 */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 150 0x96 */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x78, /* 01111000 */ - 0xcc, /* 11001100 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 151 0x97 */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 152 0x98 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7e, /* 01111110 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - - /* 153 0x99 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 154 0x9a */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 155 0x9b */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 156 0x9c */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x64, /* 01100100 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xe6, /* 11100110 */ - 0xfc, /* 11111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 157 0x9d */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 158 0x9e */ - 0x00, /* 00000000 */ - 0xf8, /* 11111000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xf8, /* 11111000 */ - 0xc4, /* 11000100 */ - 0xcc, /* 11001100 */ - 0xde, /* 11011110 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 159 0x9f */ - 0x00, /* 00000000 */ - 0x0e, /* 00001110 */ - 0x1b, /* 00011011 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xd8, /* 11011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 160 0xa0 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 161 0xa1 */ - 0x00, /* 00000000 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 162 0xa2 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 163 0xa3 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 164 0xa4 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0xdc, /* 11011100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 165 0xa5 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xe6, /* 11100110 */ - 0xf6, /* 11110110 */ - 0xfe, /* 11111110 */ - 0xde, /* 11011110 */ - 0xce, /* 11001110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 166 0xa6 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x3e, /* 00111110 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 167 0xa7 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 168 0xa8 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 169 0xa9 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 170 0xaa */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 171 0xab */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0xe0, /* 11100000 */ - 0x62, /* 01100010 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xdc, /* 11011100 */ - 0x86, /* 10000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x3e, /* 00111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 172 0xac */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0xe0, /* 11100000 */ - 0x62, /* 01100010 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x66, /* 01100110 */ - 0xce, /* 11001110 */ - 0x9a, /* 10011010 */ - 0x3f, /* 00111111 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 173 0xad */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 174 0xae */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x36, /* 00110110 */ - 0x6c, /* 01101100 */ - 0xd8, /* 11011000 */ - 0x6c, /* 01101100 */ - 0x36, /* 00110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 175 0xaf */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xd8, /* 11011000 */ - 0x6c, /* 01101100 */ - 0x36, /* 00110110 */ - 0x6c, /* 01101100 */ - 0xd8, /* 11011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 176 0xb0 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - - /* 177 0xb1 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - - /* 178 0xb2 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - - /* 179 0xb3 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 180 0xb4 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 181 0xb5 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 182 0xb6 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf6, /* 11110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 183 0xb7 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 184 0xb8 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 185 0xb9 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf6, /* 11110110 */ - 0x06, /* 00000110 */ - 0xf6, /* 11110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 186 0xba */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 187 0xbb */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x06, /* 00000110 */ - 0xf6, /* 11110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 188 0xbc */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf6, /* 11110110 */ - 0x06, /* 00000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 189 0xbd */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 190 0xbe */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 191 0xbf */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 192 0xc0 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 193 0xc1 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 194 0xc2 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 195 0xc3 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 196 0xc4 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 197 0xc5 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 198 0xc6 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 199 0xc7 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x37, /* 00110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 200 0xc8 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x37, /* 00110111 */ - 0x30, /* 00110000 */ - 0x3f, /* 00111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 201 0xc9 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3f, /* 00111111 */ - 0x30, /* 00110000 */ - 0x37, /* 00110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 202 0xca */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf7, /* 11110111 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 203 0xcb */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0xf7, /* 11110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 204 0xcc */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x37, /* 00110111 */ - 0x30, /* 00110000 */ - 0x37, /* 00110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 205 0xcd */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 206 0xce */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf7, /* 11110111 */ - 0x00, /* 00000000 */ - 0xf7, /* 11110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 207 0xcf */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 208 0xd0 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 209 0xd1 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 210 0xd2 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 211 0xd3 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x3f, /* 00111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 212 0xd4 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 213 0xd5 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 214 0xd6 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3f, /* 00111111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 215 0xd7 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xff, /* 11111111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 216 0xd8 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 217 0xd9 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 218 0xda */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 219 0xdb */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - - /* 220 0xdc */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - - /* 221 0xdd */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - - /* 222 0xde */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - - /* 223 0xdf */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 224 0xe0 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0xdc, /* 11011100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 225 0xe1 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xd8, /* 11011000 */ - 0xcc, /* 11001100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xcc, /* 11001100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 226 0xe2 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 227 0xe3 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 228 0xe4 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 229 0xe5 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 230 0xe6 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0x00, /* 00000000 */ - - /* 231 0xe7 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 232 0xe8 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 233 0xe9 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 234 0xea */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0xee, /* 11101110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 235 0xeb */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1e, /* 00011110 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x3e, /* 00111110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 236 0xec */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0xdb, /* 11011011 */ - 0xdb, /* 11011011 */ - 0xdb, /* 11011011 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 237 0xed */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x03, /* 00000011 */ - 0x06, /* 00000110 */ - 0x7e, /* 01111110 */ - 0xdb, /* 11011011 */ - 0xdb, /* 11011011 */ - 0xf3, /* 11110011 */ - 0x7e, /* 01111110 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 238 0xee */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1c, /* 00011100 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x7c, /* 01111100 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x1c, /* 00011100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 239 0xef */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 240 0xf0 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 241 0xf1 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 242 0xf2 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 243 0xf3 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 244 0xf4 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x0e, /* 00001110 */ - 0x1b, /* 00011011 */ - 0x1b, /* 00011011 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 245 0xf5 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 246 0xf6 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 247 0xf7 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 248 0xf8 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 249 0xf9 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 250 0xfa */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 251 0xfb */ - 0x00, /* 00000000 */ - 0x0f, /* 00001111 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0xec, /* 11101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x3c, /* 00111100 */ - 0x1c, /* 00011100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 252 0xfc */ - 0x00, /* 00000000 */ - 0x6c, /* 01101100 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 253 0xfd */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x32, /* 00110010 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 254 0xfe */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 255 0xff */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - -}; - -#endif diff --git a/c/src/lib/libbsp/arm/raspberrypi/console/outch.c b/c/src/lib/libbsp/arm/raspberrypi/console/outch.c deleted file mode 100644 index 20601384c7..0000000000 --- a/c/src/lib/libbsp/arm/raspberrypi/console/outch.c +++ /dev/null @@ -1,463 +0,0 @@ -/** - * @file - * - * @ingroup raspberrypi - * - * @brief displaying characters on the console - */ - -/** - * - * Copyright (c) 2015 Yang Qiao - * based on work by: - * Copyright (C) 1998 Eric Valette (valette@crf.canon.fr) - * Canon Centre Recherche France. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - * Till Straumann , 2003/9: - * - added handling of basic escape sequences (cursor movement - * and erasing; just enough for the line editor 'libtecla' to - * work...) - * - */ - -#include -#include -#include -#include - -#include -#include -#include "font_data.h" - -static void wr_cursor( - int r, - int c -) -{ - /* dummy function for now */ -} - -#define TAB_SPACE 4 -#define CONSOLE_BG_COL 0x00 -#define CONSOLE_FG_COL 0xa0 - -static void *fb_mem = NULL; -static unsigned short maxCol; -static unsigned short maxRow; -static unsigned short bytes_per_pixel; -static unsigned int bytes_per_line; -static unsigned int bytes_per_char_line; -static unsigned char row; -static unsigned char column; -static unsigned int nLines; -static uint32_t fgx, bgx, eorx; -static int rpi_video_initialized; - -static const int video_font_draw_table32[ 16 ][ 4 ] = { - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00000000, 0x00000000, 0x00000000, 0x00ffffff }, - { 0x00000000, 0x00000000, 0x00ffffff, 0x00000000 }, - { 0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff }, - { 0x00000000, 0x00ffffff, 0x00000000, 0x00000000 }, - { 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff }, - { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000 }, - { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff }, - { 0x00ffffff, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff }, - { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000 }, - { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff }, - { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000 }, - { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff }, - { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000 }, - { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff } -}; - -static void scroll( void ) -{ - int i, j; /* Counters */ - uint8_t *pt_scroll, *pt_bitmap; /* Pointers on the bit-map */ - - pt_bitmap = fb_mem; - j = 0; - pt_bitmap = pt_bitmap + j; - pt_scroll = pt_bitmap + bytes_per_char_line; - - for ( i = j; i < maxRow - 1; i++ ) { - memcpy( pt_bitmap, pt_scroll, bytes_per_char_line ); - pt_bitmap = pt_bitmap + bytes_per_char_line; - pt_scroll = pt_bitmap + bytes_per_char_line; - } - - /* - * Blank characters are displayed on the last line. - */ - memset( pt_bitmap, 0, bytes_per_char_line ); -} - -static void doCRNL( - int cr, - int nl -) -{ - if ( nl ) { - if ( ++row == maxRow ) { - scroll(); /* Scroll the screen now */ - row = maxRow - 1; - } - - nLines++; - } - - if ( cr ) - column = 0; - - /* Move cursor on the next location */ - if ( cr || nl ) { - wr_cursor( row, column ); - } -} - -static void advanceCursor( void ) -{ - if ( ++column == maxCol ) - doCRNL( 1, 1 ); - else - wr_cursor( row, column ); -} - -static void gotorc( - int r, - int c -) -{ - column = c; - row = r; - wr_cursor( row, column ); -} - -static void video_drawchars( - int r, - int c, - unsigned char ch -) -{ - if ( fb_mem == NULL ) { - return; - } - - uint8_t *cdat, *dest, *dest0; - int rows, offset; - - offset = r * bytes_per_char_line + c * bytes_per_pixel * RPI_FONT_WIDTH; - dest0 = fb_mem + offset; - - /* - * only 32-bit per pixel format is supported for now - */ - cdat = rpi_font + ch * RPI_FONT_HEIGHT; - - for ( rows = RPI_FONT_HEIGHT, dest = dest0; - rows--; dest += bytes_per_line ) { - uint8_t bits = *cdat++; - - ( (uint32_t *) dest )[ 0 ] = - ( video_font_draw_table32 - [ bits >> 4 ][ 0 ] & eorx ) ^ bgx; - ( (uint32_t *) dest )[ 1 ] = - ( video_font_draw_table32 - [ bits >> 4 ][ 1 ] & eorx ) ^ bgx; - ( (uint32_t *) dest )[ 2 ] = - ( video_font_draw_table32 - [ bits >> 4 ][ 2 ] & eorx ) ^ bgx; - ( (uint32_t *) dest )[ 3 ] = - ( video_font_draw_table32 - [ bits >> 4 ][ 3 ] & eorx ) ^ bgx; - - ( (uint32_t *) dest )[ 4 ] = - ( video_font_draw_table32 - [ bits & 15 ][ 0 ] & eorx ) ^ bgx; - ( (uint32_t *) dest )[ 5 ] = - ( video_font_draw_table32 - [ bits & 15 ][ 1 ] & eorx ) ^ bgx; - ( (uint32_t *) dest )[ 6 ] = - ( video_font_draw_table32 - [ bits & 15 ][ 2 ] & eorx ) ^ bgx; - ( (uint32_t *) dest )[ 7 ] = - ( video_font_draw_table32 - [ bits & 15 ][ 3 ] & eorx ) ^ bgx; - } -} - -#define ESC ( (char) 27 ) -/* erase current location without moving the cursor */ -#define BLANK ( (char) 0x7f ) - -static void videoPutChar( char ch ) -{ - switch ( ch ) { - case '\b': { - if ( column ) - column--; - - /* Move cursor on the previous location */ - wr_cursor( row, column ); - return; - } - case '\t': { - int i; - - i = TAB_SPACE - ( column & ( TAB_SPACE - 1 ) ); - - while ( i-- ) { - - video_drawchars( row, column, ' ' ); - column += 1; - - if ( column >= maxCol ) { - doCRNL( 1, 1 ); - return; - } - } - - wr_cursor( row, column ); - - return; - } - case '\n': { - doCRNL( 0, 1 ); - return; - } - case 7: { /* Bell code must be inserted here */ - return; - } - case '\r': { - doCRNL( 1, 0 ); - return; - } - case BLANK: { - video_drawchars( row, column, ' ' ); - - wr_cursor( row, column ); - - return; - } - default: { - // *pt_bitmap = (unsigned char)ch | attribute; - video_drawchars( row, column, ch ); - advanceCursor(); - return; - } - } -} - -/* trivial state machine to handle escape sequences: - * - * --------------------------------- - * | | - * | | - * KEY: esc V [ DCABHKJ esc | - * STATE: 0 -----> 27 -----> '[' ----------> -1 ----- - * ^\ \ \ \ - * KEY: | \other \ other \ other \ other - * <------------------------------------- - * - * in state '-1', the DCABHKJ cases are handled - * - * (cursor motion and screen clearing) - */ - -#define DONE ( -1 ) - -static int handleEscape( - int oldState, - char ch -) -{ - int rval = 0; - int ro, co; - - switch ( oldState ) { - case DONE: /* means the previous char terminated an ESC sequence... */ - case 0: - - if ( 27 == ch ) { - rval = 27; /* START of an ESC sequence */ - } - - break; - - case 27: - - if ( '[' == ch ) { - rval = ch; /* received ESC '[', so far */ - } else { - /* dump suppressed 'ESC'; outch will append the char */ - videoPutChar( ESC ); - } - - break; - - case '[': - /* handle 'ESC' '[' sequences here */ - ro = row; - co = column; - rval = DONE; /* done */ - - switch ( ch ) { - case 'D': /* left */ - - if ( co > 0 ) - co--; - - break; - case 'C': /* right */ - - if ( co < maxCol ) - co++; - - break; - case 'A': /* up */ - - if ( ro > 0 ) - ro--; - - break; - case 'B': /* down */ - - if ( ro < maxRow ) - ro++; - - break; - case 'H': /* home */ - ro = co = 0; - break; - case 'K': /* clear to end of line */ - - while ( column < maxCol - 1 ) - videoPutChar( ' ' ); - - videoPutChar( BLANK ); - break; - case 'J': /* clear to end of screen */ - - while ( ( ( row < maxRow - 1 ) || ( column < maxCol - 1 ) ) ) - videoPutChar( ' ' ); - - videoPutChar( BLANK ); - break; - default: - videoPutChar( ESC ); - videoPutChar( '[' ); - /* DONT move the cursor */ - ro = -1; - rval = 0; - break; - } - - // /* reset cursor */ - if ( ro >= 0 ) - gotorc( ro, co ); - - default: - break; - } - - return rval; -} - -static void clear_screen( void ) -{ - int i, j; - - for ( j = 0; j < maxRow; j++ ) { - for ( i = 0; i < maxCol; i++ ) { - videoPutChar( ' ' ); - } - } - - column = 0; - row = 0; -} - -void rpi_fb_outch( char c ) -{ - static int escaped = 0; - - if ( !( escaped = handleEscape( escaped, c ) ) ) { - if ( '\n' == c ) - videoPutChar( '\r' ); - - videoPutChar( c ); - } -} - -void rpi_video_init( void ) -{ - int ret = rpi_fb_init(); - - if ( ( ret != RPI_FB_INIT_OK ) && - ( ret != RPI_FB_INIT_ALREADY_INITIALIZED ) ) { - rpi_video_initialized = 0; - return; - } - - struct fb_var_screeninfo fb_var_info; - struct fb_fix_screeninfo fb_fix_info; - rpi_get_var_screen_info( &fb_var_info ); - rpi_get_fix_screen_info( &fb_fix_info ); - maxCol = fb_var_info.xres / RPI_FONT_WIDTH; - maxRow = fb_var_info.yres / RPI_FONT_HEIGHT; - bytes_per_pixel = fb_var_info.bits_per_pixel / 8; - bytes_per_line = bytes_per_pixel * fb_var_info.xres; - bytes_per_char_line = RPI_FONT_HEIGHT * bytes_per_line; - fb_mem = RTEMS_DEVOLATILE( void *, fb_fix_info.smem_start ); - column = 0; - row = 0; - nLines = 0; - fgx = ( CONSOLE_FG_COL << 24 ) | - ( CONSOLE_FG_COL << 16 ) | - ( CONSOLE_FG_COL << 8 ) | - CONSOLE_FG_COL; - bgx = ( CONSOLE_BG_COL << 24 ) | - ( CONSOLE_BG_COL << 16 ) | - ( CONSOLE_BG_COL << 8 ) | - CONSOLE_BG_COL; - eorx = fgx ^ bgx; - clear_screen(); - rpi_video_initialized = 1; -} - -int rpi_video_is_initialized( void ) -{ - return rpi_video_initialized; -} - -/* for old DOS compatibility n-curses type of applications */ -void gotoxy( - int x, - int y -); -int whereX( void ); -int whereY( void ); - -void gotoxy( - int x, - int y -) -{ - gotorc( y, x ); -} - -int whereX( void ) -{ - return row; -} - -int whereY( void ) -{ - return column; -} diff --git a/c/src/lib/libbsp/arm/raspberrypi/console/usart.c b/c/src/lib/libbsp/arm/raspberrypi/console/usart.c deleted file mode 100644 index 25fb523621..0000000000 --- a/c/src/lib/libbsp/arm/raspberrypi/console/usart.c +++ /dev/null @@ -1,167 +0,0 @@ -/** - * @file - * - * @ingroup raspberrypi_usart - * - * @brief USART support. - */ - -/* - * Copyright (c) 2013 Alan Cudmore - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * - * http://www.rtems.org/license/LICENSE - * - */ - -#include - -#include -#include -#include -#include -#include - -static void usart_delay(uint32_t n) -{ - volatile uint32_t i = 0; - - for(i = 0; i < n; i++) - ; -} - -#if 0 -/* - * These will be useful when the driver supports interrupt driven IO. - */ -static rtems_vector_number usart_get_irq_number(const console_tbl *ct) -{ - return ct->ulIntVector; -} - -static uint32_t usart_get_baud(const console_tbl *ct) -{ - return ct->ulClock; -} -#endif - -static void usart_set_baud(int minor, int baud) -{ - /* - * Nothing for now - */ - return; -} - -static void usart_initialize(int minor) -{ - unsigned int gpio_reg; - - /* - ** Program GPIO pins for UART 0 - */ - gpio_reg = BCM2835_REG(BCM2835_GPIO_GPFSEL1); - gpio_reg &= ~(7<<12); /* gpio14 */ - gpio_reg |= (4<<12); /* alt0 */ - gpio_reg &= ~(7<<15); /* gpio15 */ - gpio_reg |= (4<<15); /* alt0 */ - BCM2835_REG(BCM2835_GPIO_GPFSEL1) = gpio_reg; - - BCM2835_REG(BCM2835_GPIO_GPPUD) = 0; - usart_delay(150); - BCM2835_REG(BCM2835_GPIO_GPPUDCLK0) = (1<<14)|(1<<15); - usart_delay(150); - BCM2835_REG(BCM2835_GPIO_GPPUDCLK0) = 0; - - /* - ** Init the PL011 UART - */ - BCM2835_REG(BCM2835_UART0_CR) = 0; - BCM2835_REG(BCM2835_UART0_ICR) = 0x7FF; - BCM2835_REG(BCM2835_UART0_IMSC) = 0; - BCM2835_REG(BCM2835_UART0_IBRD) = 1; - BCM2835_REG(BCM2835_UART0_FBRD) = 40; - BCM2835_REG(BCM2835_UART0_LCRH) = 0x70; - BCM2835_REG(BCM2835_UART0_RSRECR) = 0; - - BCM2835_REG(BCM2835_UART0_CR) = 0x301; - - BCM2835_REG(BCM2835_UART0_IMSC) = BCM2835_UART0_IMSC_RX; - - usart_set_baud(minor, 115000); -} - -static int usart_first_open(int major, int minor, void *arg) -{ - rtems_libio_open_close_args_t *oc = (rtems_libio_open_close_args_t *) arg; - struct rtems_termios_tty *tty = (struct rtems_termios_tty *) oc->iop->data1; - const console_tbl *ct = Console_Port_Tbl [minor]; - console_data *cd = &Console_Port_Data [minor]; - - cd->termios_data = tty; - rtems_termios_set_initial_baud(tty, ct->ulClock); - - return 0; -} - -static int usart_last_close(int major, int minor, void *arg) -{ - return 0; -} - -static int usart_read_polled(int minor) -{ - if (minor == 0) { - if (((BCM2835_REG(BCM2835_UART0_FR)) & BCM2835_UART0_FR_RXFE) == 0) { - return((BCM2835_REG(BCM2835_UART0_DR)) & 0xFF ); - } else { - return -1; - } - } else { - printk("Unknown console minor number: %d\n", minor); - return -1; - } -} - -static void usart_write_polled(int minor, char c) -{ - while (1) { - if ((BCM2835_REG(BCM2835_UART0_FR) & BCM2835_UART0_FR_TXFF) == 0) - break; - } - BCM2835_REG(BCM2835_UART0_DR) = c; -} - -static ssize_t usart_write_support_polled( - int minor, - const char *s, - size_t n -) -{ - ssize_t i = 0; - - for (i = 0; i < n; ++i) { - usart_write_polled(minor, s [i]); - } - - return n; -} - -static int usart_set_attributes(int minor, const struct termios *term) -{ - return -1; -} - -const console_fns bcm2835_usart_fns = { - .deviceProbe = libchip_serial_default_probe, - .deviceFirstOpen = usart_first_open, - .deviceLastClose = usart_last_close, - .deviceRead = usart_read_polled, - .deviceWrite = usart_write_support_polled, - .deviceInitialize = usart_initialize, - .deviceWritePolled = usart_write_polled, - .deviceSetAttributes = usart_set_attributes, - .deviceOutputUsesInterrupts = false -}; diff --git a/c/src/lib/libbsp/arm/realview-pbx-a9/Makefile.am b/c/src/lib/libbsp/arm/realview-pbx-a9/Makefile.am index 7f235343e5..bc1e0437cb 100644 --- a/c/src/lib/libbsp/arm/realview-pbx-a9/Makefile.am +++ b/c/src/lib/libbsp/arm/realview-pbx-a9/Makefile.am @@ -61,12 +61,12 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c librtemsbsp_a_SOURCES += ../shared/arm-gic-irq.c # Console -librtemsbsp_a_SOURCES += ../../shared/console-termios-init.c -librtemsbsp_a_SOURCES += ../../shared/console-termios.c -librtemsbsp_a_SOURCES += ../../shared/get-serial-mouse-ps2.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios-init.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/getserialmouseps2.c librtemsbsp_a_SOURCES += ../shared/arm-pl011.c librtemsbsp_a_SOURCES += ../shared/arm-pl050.c -librtemsbsp_a_SOURCES += console/console-config.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/realview-pbx-a9/console/console-config.c # Clock librtemsbsp_a_SOURCES += ../shared/arm-a9mpcore-clock-config.c diff --git a/c/src/lib/libbsp/arm/realview-pbx-a9/console/console-config.c b/c/src/lib/libbsp/arm/realview-pbx-a9/console/console-config.c deleted file mode 100644 index 66dcfa6803..0000000000 --- a/c/src/lib/libbsp/arm/realview-pbx-a9/console/console-config.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include - -#include -#include -#include -#include -#include - -static arm_pl011_context pl011_context = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("PL011"), - .regs = (volatile pl011 *) 0x10009000, - .irq = RVPBXA9_IRQ_UART_0, - .initial_baud = 115200 -}; - -static arm_pl050_context pl050_context = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("PL050"), - .regs = (volatile pl050 *) 0x10007000, - .irq = RVPBXA9_IRQ_KMI1, - .initial_baud = 115200 -}; - -static void output_char(char c) -{ - arm_pl011_write_polled(&pl011_context.base, c); -} - -static bool pl011_probe(rtems_termios_device_context *base) -{ - BSP_output_char = output_char; - - return arm_pl011_probe(base); -} - -static void output_char_init(char c) -{ - pl011_probe(&pl011_context.base); - output_char(c); -} - -BSP_output_char_function_type BSP_output_char = output_char_init; - -BSP_polling_getchar_function_type BSP_poll_char = NULL; - -const console_device console_device_table[] = { - { - .device_file = "/dev/ttyS0", - .probe = pl011_probe, - .handler = &arm_pl011_fns, - .context = &pl011_context.base - }, { - .device_file = SERIAL_MOUSE_DEVICE_PS2, - .probe = console_device_probe_default, - .handler = &arm_pl050_fns, - .context = &pl050_context.base - } -}; - -const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table); diff --git a/c/src/lib/libbsp/arm/rtl22xx/Makefile.am b/c/src/lib/libbsp/arm/rtl22xx/Makefile.am index da8ef3aef1..e64bbeee9f 100644 --- a/c/src/lib/libbsp/arm/rtl22xx/Makefile.am +++ b/c/src/lib/libbsp/arm/rtl22xx/Makefile.am @@ -33,7 +33,7 @@ librtemsbsp_a_SOURCES +=../../../../../../bsps/arm/rtl22xx/clock/clockdrv.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c -librtemsbsp_a_SOURCES += console/uart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/rtl22xx/console/uart.c # IRQ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c librtemsbsp_a_SOURCES += irq/irq.c diff --git a/c/src/lib/libbsp/arm/rtl22xx/console/lpc22xx_uart.h b/c/src/lib/libbsp/arm/rtl22xx/console/lpc22xx_uart.h deleted file mode 100644 index f6ae249672..0000000000 --- a/c/src/lib/libbsp/arm/rtl22xx/console/lpc22xx_uart.h +++ /dev/null @@ -1,187 +0,0 @@ -/** - * @file - * @ingroup rtl22xx_uart - * @brief UART support. - */ - -#ifndef LPC22XX_UART_H -#define LPC22XX_UART_H - -/** - * @defgroup rtl22xx_uart UART Support - * @ingroup arm_rtl22xx - * @brief UART (Universal Asynchronous Reciever/Transmitter) Support - * @{ - */ - -#define FIFODEEP 16 - -#define BD115200 115200 -#define BD38400 38400 -#define BD9600 9600 - -/** @brief PINSEL0 Value for UART0 */ -#define U0_PINSEL (0x00000005) -/** @brief PINSEL0 Mask for UART0 */ -#define U0_PINMASK (0x0000000F) -/** @brief PINSEL0 Value for UART1 */ -#define U1_PINSEL (0x00050000) -/** @brief PINSEL0 Mask for UART1 */ -#define U1_PINMASK (0x000F0000) - -/** - * @name Uart line control register bit descriptions - * @{ - */ - -#define LCR_WORDLENTH_BIT 0 -#define LCR_STOPBITSEL_BIT 2 -#define LCR_PARITYENBALE_BIT 3 -#define LCR_PARITYSEL_BIT 4 -#define LCR_BREAKCONTROL_BIT 6 -#define LCR_DLAB_BIT 7 - -/** @} */ - -/** - * @name Line Control Register bit definitions - * @{ - */ - -/** @brief 5-bit character length */ -#define ULCR_CHAR_5 (0 << 0) -/** @brief 6-bit character length */ -#define ULCR_CHAR_6 (1 << 0) -/** @brief 7-bit character length */ -#define ULCR_CHAR_7 (2 << 0) -/** @brief 8-bit character length */ -#define ULCR_CHAR_8 (3 << 0) -/** @brief no stop bits */ -#define ULCR_STOP_0 (0 << 2) -/** @brief 1 stop bit */ -#define ULCR_STOP_1 (1 << 2) -/** @brief No Parity */ -#define ULCR_PAR_NO (0 << 3) -/** @brief Odd Parity */ -#define ULCR_PAR_ODD (1 << 3) -/** @brief Even Parity */ -#define ULCR_PAR_EVEN (3 << 3) -/** @brief MARK "1" Parity */ -#define ULCR_PAR_MARK (5 << 3) -/** @brief SPACE "0" Paruty */ -#define ULCR_PAR_SPACE (7 << 3) -/** @brief Output BREAK line condition */ -#define ULCR_BREAK_ENABLE (1 << 6) -/** @brief Enable Divisor Latch Access */ -#define ULCR_DLAB_ENABLE (1 << 7) - -/** @} */ - -/** - * @name Modem Control Register bit definitions - * @{ - */ - -/** @brief Data Terminal Ready */ -#define UMCR_DTR (1 << 0) -/** @brief Request To Send */ -#define UMCR_RTS (1 << 1) -/** @brief Loopback */ -#define UMCR_LB (1 << 4) - -/** @} */ - -/** - * @name Line Status Register bit definitions - * @{ - */ - -/** @brief Receive Data Ready */ -#define ULSR_RDR (1 << 0) -/** @brief Overrun Error */ -#define ULSR_OE (1 << 1) -/** @brief Parity Error */ -#define ULSR_PE (1 << 2) -/** @brief Framing Error */ -#define ULSR_FE (1 << 3) -/** @brief Break Interrupt */ -#define ULSR_BI (1 << 4) -/** @brief Transmit Holding Register Empty */ -#define ULSR_THRE (1 << 5) -/** @brief Transmitter Empty */ -#define ULSR_TEMT (1 << 6) -/** @brief Error in Receive FIFO */ -#define ULSR_RXFE (1 << 7) -#define ULSR_ERR_MASK 0x1E - -/** @} */ - -/** - * @name Modem Status Register bit definitions - * @{ - */ - -/** @brief Delta Clear To Send */ -#define UMSR_DCTS (1 << 0) -/** @brief Delta Data Set Ready */ -#define UMSR_DDSR (1 << 1) -/** @brief Trailing Edge Ring Indicator */ -#define UMSR_TERI (1 << 2) -/** @brief Delta Data Carrier Detect */ -#define UMSR_DDCD (1 << 3) -/** @brief Clear To Send */ -#define UMSR_CTS (1 << 4) -/** @brief Data Set Ready */ -#define UMSR_DSR (1 << 5) -/** @brief Ring Indicator */ -#define UMSR_RI (1 << 6) -/** @brief Data Carrier Detect */ -#define UMSR_DCD (1 << 7) - -/** @} */ - -/** - * @name Uart Interrupt Identification - * @{ - */ - -#define IIR_RSL 0x3 -#define IIR_RDA 0x2 -#define IIR_CTI 0x6 -#define IIR_THRE 0x1 - -/** @} */ - -/** - * @name Uart Interrupt Enable Type - * @{ - */ - -#define IER_RBR 0x1 -#define IER_THRE 0x2 -#define IER_RLS 0x4 - -/** @} */ - -/** - * @name Uart Receiver Errors - * @{ - */ - -#define RC_FIFO_OVERRUN_ERR 0x1 -#define RC_OVERRUN_ERR 0x2 -#define RC_PARITY_ERR 0x4 -#define RC_FRAMING_ERR 0x8 -#define RC_BREAK_IND 0x10 - -/** @} */ - -typedef enum { - UART0 = 0, - UART1 -} LPC_UartChanel_t; - -/** @} */ - -#endif - diff --git a/c/src/lib/libbsp/arm/rtl22xx/console/uart.c b/c/src/lib/libbsp/arm/rtl22xx/console/uart.c deleted file mode 100644 index 2952e74508..0000000000 --- a/c/src/lib/libbsp/arm/rtl22xx/console/uart.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * console driver for RTL22xx UARTs - * - * If you want the driver to be interrupt driven, you - * need to write the ISR, and in the ISR insert the - * chars into termios's queue. - */ - -/* - * Copyright (c) By ray - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include /* Must be before libio.h */ -#include -#include -#include - -/* Put the CPU (or UART) specific header file #include here */ -#include -#include "lpc22xx_uart.h" - -#include -#include - -/* How many serial ports? */ -#define NUM_DEVS 1 - -int dbg_dly; - -/* static function prototypes */ -static int uart_first_open(int major, int minor, void *arg); -static int uart_last_close(int major, int minor, void *arg); -static int uart_read(int minor); -static ssize_t uart_write(int minor, const char *buf, size_t len); -static void uart_init(int minor); -static void uart_write_polled(int minor, char c); -static int uart_set_attributes(int minor, const struct termios *t); - -/* These are used by code in console.c */ -unsigned long Console_Configuration_Count = NUM_DEVS; - -/* Pointers to functions for handling the UART. */ -const console_fns uart_fns = { - libchip_serial_default_probe, - uart_first_open, - uart_last_close, - uart_read, - uart_write, - uart_init, - uart_write_polled, /* not used in this driver */ - uart_set_attributes, - FALSE /* TRUE if interrupt driven, FALSE if not. */ -}; - -/* - * There's one item in array for each UART. - * - * Some of these fields are marked "NOT USED". They are not used - * by console.c, but may be used by drivers in libchip - */ -console_tbl Console_Configuration_Ports[] = { -{ - "/dev/com0", /* sDeviceName */ - SERIAL_CUSTOM, /* deviceType */ - &uart_fns, /* pDeviceFns */ - NULL, /* deviceProbe */ - NULL, /* pDeviceFlow */ - 0, /* ulMargin - NOT USED */ - 0, /* ulHysteresis - NOT USED */ - NULL, /* pDeviceParams */ - 0, /* ulCtrlPort1 - NOT USED */ - 0, /* ulCtrlPort2 - NOT USED */ - 0, /* ulDataPort - NOT USED */ - NULL, /* getRegister - NOT USED */ - NULL, /* setRegister - NOT USED */ - NULL, /* getData - NOT USED */ - NULL, /* setData - NOT USED */ - 0, /* ulClock - NOT USED */ - 0 /* ulIntVector - NOT USED */ -} -#if 0 -{ - "/dev/com1", /* sDeviceName */ - SERIAL_CUSTOM, /* deviceType */ - &uart_fns, /* pDeviceFns */ - NULL, /* deviceProbe */ - NULL, /* pDeviceFlow */ - 0, /* ulMargin - NOT USED */ - 0, /* ulHysteresis - NOT USED */ - NULL, /* pDeviceParams */ - 0, /* ulCtrlPort1 - NOT USED */ - 0, /* ulCtrlPort2 - NOT USED */ - 0, /* ulDataPort - NOT USED */ - NULL, /* getRegister - NOT USED */ - NULL, /* setRegister - NOT USED */ - NULL, /* getData - NOT USED */ - NULL, /* setData - NOT USED */ - 0, /* ulClock - NOT USED */ - 0 /* ulIntVector - NOT USED */ -} -#endif -}; - -/* - * This is called the first time each device is opened. If the driver - * is interrupt driven, you should enable interrupts here. Otherwise, - * it's probably safe to do nothing. - * - * Since micromonitor already set up the UART, we do nothing. - */ -static int uart_first_open(int major, int minor, void *arg) -{ - return 0; -} - -/* - * This is called the last time each device is closed. If the driver - * is interrupt driven, you should disable interrupts here. Otherwise, - * it's probably safe to do nothing. - */ -static int uart_last_close(int major, int minor, void *arg) -{ - return 0; -} - -/* - * Read one character from UART. - * - * Return -1 if there's no data, otherwise return - * the character in lowest 8 bits of returned int. - */ -static int uart_read(int minor) -{ - char c; - - switch (minor) { - case 0: - if (U0LSR & ULSR_RDR) { - c = U0RBR; - return c; - } - return -1; - case 1: - if (U1LSR & ULSR_RDR) { - c = U1RBR; - return c; - } - return -1; - default: - break; - } - printk("Unknown console minor number %d\n", minor); - return -1; -} - -/* - * Write buffer to UART - * - * return 1 on success, -1 on error - */ -static ssize_t uart_write(int minor, const char *buf, size_t len) -{ - size_t i; - - switch (minor) { - case 0: - for (i = 0; i < len; i++) { - while (!(U0LSR & ULSR_THRE)) /* wait for TX buffer to empty*/ - continue; /* also either WDOG() or swap()*/ - U0THR = (char) buf[i]; - } - break; - case 1: - for (i = 0; i < len; i++) { - while (!(U0LSR & ULSR_THRE)) /* wait for TX buffer to empty*/ - continue; /* also either WDOG() or swap()*/ - U0THR = (char) buf[i]; - } - break; - default: - printk("Unknown console minor number %d\n", minor); - return -1; - } - - return len; -} - -/* Set up the UART. */ -static void uart_init(int minor) -{ -#if 0 //init will be done in bspstart.c - int baud=6; - int mode =0x03; - if(minor==0){ - // set port pins for UART0 - PINSEL0 = (PINSEL0 & ~U0_PINMASK) | U0_PINSEL; - - U0IER = 0x00; // disable all interrupts - - // set the baudrate - U0LCR = 1<<7; // select divisor latches - U0DLL = (uint8_t)baud; // set for baud low byte - U0DLM = (uint8_t)(baud >> 8); // set for baud high byte - - // set the number of characters and other - // user specified operating parameters - U0LCR = (mode & ~ULCR_DLAB_ENABLE); - U0FCR = mode>>8; /*fifo mode*/ - - // set port pins for UART1 - PINSEL0 = (PINSEL0 & ~U1_PINMASK) | U1_PINSEL; - - U1IER = 0x00; // disable all interrupts - }else if(minor==1){ - // set the baudrate - U1LCR = ULCR_DLAB_ENABLE; // select divisor latches - U1DLL = (uint8_t)baud; // set for baud low byte - U1DLM = (uint8_t)(baud >> 8); // set for baud high byte - - // set the number of characters and other - // user specified operating parameters - U1LCR = (mode & ~ULCR_DLAB_ENABLE); - U1FCR = mode>>8;/*fifo mode*/ - } - -#endif -} - -/* I'm not sure this is needed for the shared console driver. */ -static void uart_write_polled(int minor, char c) -{ - uart_write(minor, &c, 1); -} - -/* This is for setting baud rate, bits, etc. */ -static int uart_set_attributes(int minor, const struct termios *t) -{ - return 0; -} - -/* - * Write a character to the console. This is used by printk() and - * maybe other low level functions. It should not use interrupts or any - * RTEMS system calls. It needs to be very simple - */ -static void _BSP_put_char( char c ) -{ - uart_write_polled(0, c); -} - -BSP_output_char_function_type BSP_output_char = _BSP_put_char; - -static int _BSP_get_char(void) -{ - return uart_read(0); -} - -BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char; - -/* - * init USART 0¡£8 bit, 1 Stop,No checkout, BPS115200 - */ -void UART0_Ini(void) -{ - long Fdiv; - int i; - - PINSEL0 = 0x00000005; // I/O to UART0 - U0LCR = 0x83; // DLAB = 1 - Fdiv = (Fpclk >>4) / UART_BPS; // configure BPS - U0DLM = Fdiv/256; - U0DLL = Fdiv%256; - U0LCR = 0x03; - - for(i=0;i<10;i++){ - U0THR = 67; //send a C to see if is OK - while ( (U0LSR&0x40)==0 ); - } -} diff --git a/c/src/lib/libbsp/arm/smdk2410/Makefile.am b/c/src/lib/libbsp/arm/smdk2410/Makefile.am index a9c43789f4..748cde9c94 100644 --- a/c/src/lib/libbsp/arm/smdk2410/Makefile.am +++ b/c/src/lib/libbsp/arm/smdk2410/Makefile.am @@ -34,7 +34,7 @@ librtemsbsp_a_SOURCES +=../../../../../../bsps/arm/smdk2410/clock/support.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c -librtemsbsp_a_SOURCES += console/uart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/smdk2410/console/uart.c # IRQ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c librtemsbsp_a_SOURCES += irq/irq.c diff --git a/c/src/lib/libbsp/arm/smdk2410/console/uart.c b/c/src/lib/libbsp/arm/smdk2410/console/uart.c deleted file mode 100644 index 06adecf239..0000000000 --- a/c/src/lib/libbsp/arm/smdk2410/console/uart.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * console driver for S3C2400 UARTs - * - * This driver uses the shared console driver in - * ...../libbsp/shared/console.c - * - * If you want the driver to be interrupt driven, you - * need to write the ISR, and in the ISR insert the - * chars into termios's queue. - * - * Copyright (c) 2004 Cogent Computer Systems - * Written by Jay Monkman - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. -*/ -#include /* Must be before libio.h */ -#include -#include -#include - -/* Put the CPU (or UART) specific header file #include here */ -#include -#include -#include - -/* How many serial ports? */ -#define NUM_DEVS 1 - -int uart_poll_read(int minor); - -int dbg_dly; - -/* static function prototypes */ -static int uart_first_open(int major, int minor, void *arg); -static int uart_last_close(int major, int minor, void *arg); -static int uart_read(int minor); -static ssize_t uart_write(int minor, const char *buf, size_t len); -static void uart_init(int minor); -static void uart_write_polled(int minor, char c); -static int uart_set_attributes(int minor, const struct termios *t); - -/* These are used by code in console.c */ -unsigned long Console_Configuration_Count = NUM_DEVS; - -/* Pointers to functions for handling the UART. */ -const console_fns uart_fns = -{ - libchip_serial_default_probe, - uart_first_open, - uart_last_close, - uart_read, - uart_write, - uart_init, - uart_write_polled, /* not used in this driver */ - uart_set_attributes, - FALSE /* TRUE if interrupt driven, FALSE if not. */ -}; - -/* - * There's one item in array for each UART. - * - * Some of these fields are marked "NOT USED". They are not used - * by console.c, but may be used by drivers in libchip - * - */ -console_tbl Console_Configuration_Ports[] = { - { - "/dev/com0", /* sDeviceName */ - SERIAL_CUSTOM, /* deviceType */ - &uart_fns, /* pDeviceFns */ - NULL, /* deviceProbe */ - NULL, /* pDeviceFlow */ - 0, /* ulMargin - NOT USED */ - 0, /* ulHysteresis - NOT USED */ - NULL, /* pDeviceParams */ - 0, /* ulCtrlPort1 - NOT USED */ - 0, /* ulCtrlPort2 - NOT USED */ - 0, /* ulDataPort - NOT USED */ - NULL, /* getRegister - NOT USED */ - NULL, /* setRegister - NOT USED */ - NULL, /* getData - NOT USED */ - NULL, /* setData - NOT USED */ - 0, /* ulClock - NOT USED */ - 0 /* ulIntVector - NOT USED */ - } -}; - -/*********************************************************************/ -/* Functions called via termios callbacks (i.e. the ones in uart_fns */ -/*********************************************************************/ - -/* - * This is called the first time each device is opened. If the driver - * is interrupt driven, you should enable interrupts here. Otherwise, - * it's probably safe to do nothing. - * - * Since micromonitor already set up the UART, we do nothing. - */ -static int uart_first_open(int major, int minor, void *arg) -{ - return 0; -} - - -/* - * This is called the last time each device is closed. If the driver - * is interrupt driven, you should disable interrupts here. Otherwise, - * it's probably safe to do nothing. - */ -static int uart_last_close(int major, int minor, void *arg) -{ - return 0; -} - - -/* - * Read one character from UART. - * - * Return -1 if there's no data, otherwise return - * the character in lowest 8 bits of returned int. - */ -static int uart_read(int minor) -{ - char c; - - if (minor == 0) { - if (rUTRSTAT0 & 0x1) { - c = rURXH0 & 0xff; - return c; - } else { - return -1; - } - } else { - printk("Unknown console minor number: %d\n", minor); - return -1; - } - -} - - -/* - * Write buffer to UART - * - * return 1 on success, -1 on error - */ -static ssize_t uart_write(int minor, const char *buf, size_t len) -{ - int i; - - if (minor == 0) { - for (i = 0; i < len; i++) { - /* Wait for fifo to have room */ - while(!(rUTRSTAT0 & 0x2)) { - continue; - } - - rUTXH0 = (char) buf[i]; - } - } else { - printk("Unknown console minor number: %d\n", minor); - return -1; - } - - return 1; -} - - -/* Set up the UART. */ -static void uart_init(int minor) -{ - int i; - unsigned int reg = 0; - - /* enable UART0 */ - rCLKCON|=0x100; - - /* value is calculated so : (int)(PCLK/16./baudrate) -1 */ - reg = get_PCLK() / (16 * 115200) - 1; - - /* FIFO enable, Tx/Rx FIFO clear */ - rUFCON0 = 0x07; - rUMCON0 = 0x0; - /* Normal,No parity,1 stop,8 bit */ - rULCON0 = 0x3; - /* - * tx=level,rx=edge,disable timeout int.,enable rx error int., - * normal,interrupt or polling - */ - rUCON0 = 0x245; - rUBRDIV0 = reg; - - for (i = 0; i < 100; i++); - -} - -/* I'm not sure this is needed for the shared console driver. */ -static void uart_write_polled(int minor, char c) -{ - uart_write(minor, &c, 1); -} - -/* This is for setting baud rate, bits, etc. */ -static int uart_set_attributes(int minor, const struct termios *t) -{ - return 0; -} - -/***********************************************************************/ -/* - * The following functions are not used by TERMIOS, but other RTEMS - * functions use them instead. - */ -/***********************************************************************/ -/* - * Read from UART. This is used in the exit code, and can't - * rely on interrupts. -*/ -int uart_poll_read(int minor) -{ - return uart_read(minor); -} - - -/* - * Write a character to the console. This is used by printk() and - * maybe other low level functions. It should not use interrupts or any - * RTEMS system calls. It needs to be very simple - */ -static void _BSP_put_char( char c ) { - uart_write_polled(0, c); -} - -BSP_output_char_function_type BSP_output_char = _BSP_put_char; - -static int _BSP_get_char(void) -{ - return uart_poll_read(0); -} - -BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char; diff --git a/c/src/lib/libbsp/arm/stm32f4/Makefile.am b/c/src/lib/libbsp/arm/stm32f4/Makefile.am index 640cb59adf..760b387a18 100644 --- a/c/src/lib/libbsp/arm/stm32f4/Makefile.am +++ b/c/src/lib/libbsp/arm/stm32f4/Makefile.am @@ -56,8 +56,8 @@ librtemsbsp_a_SOURCES += ../shared/armv7m/irq/armv7m-irq-dispatch.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c -librtemsbsp_a_SOURCES += console/console-config.c -librtemsbsp_a_SOURCES += console/usart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/stm32f4/console/console-config.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/stm32f4/console/usart.c # I2C librtemsbsp_a_SOURCES += i2c/i2c.c diff --git a/c/src/lib/libbsp/arm/stm32f4/console/console-config.c b/c/src/lib/libbsp/arm/stm32f4/console/console-config.c deleted file mode 100644 index 6bf2d7e3b5..0000000000 --- a/c/src/lib/libbsp/arm/stm32f4/console/console-config.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2012 Sebastian Huber. All rights reserved. - * - * embedded brains GmbH - * Obere Lagerstr. 30 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include - -#include -#include -#include -#include - -console_tbl Console_Configuration_Ports [] = { - #ifdef STM32F4_ENABLE_USART_1 - { - .sDeviceName = "/dev/ttyS0", - .deviceType = SERIAL_CUSTOM, - .pDeviceFns = &stm32f4_usart_fns, - .ulCtrlPort1 = (uint32_t) STM32F4_USART_1, - .ulCtrlPort2 = 0, - .ulClock = STM32F4_USART_BAUD, - .ulIntVector = STM32F4_IRQ_USART1 - }, - #endif - #ifdef STM32F4_ENABLE_USART_2 - { - .sDeviceName = "/dev/ttyS1", - .deviceType = SERIAL_CUSTOM, - .pDeviceFns = &stm32f4_usart_fns, - .ulCtrlPort1 = (uint32_t) STM32F4_USART_2, - .ulCtrlPort2 = 1, - .ulClock = STM32F4_USART_BAUD, - .ulIntVector = STM32F4_IRQ_USART2 - }, - #endif - #ifdef STM32F4_ENABLE_USART_3 - { - .sDeviceName = "/dev/ttyS2", - .deviceType = SERIAL_CUSTOM, - .pDeviceFns = &stm32f4_usart_fns, - .ulCtrlPort1 = (uint32_t) STM32F4_USART_3, - .ulCtrlPort2 = 2, - .ulClock = STM32F4_USART_BAUD, - .ulIntVector = STM32F4_IRQ_USART3 - }, - #endif - #ifdef STM32F4_ENABLE_UART_4 - { - .sDeviceName = "/dev/ttyS3", - .deviceType = SERIAL_CUSTOM, - .pDeviceFns = &stm32f4_usart_fns, - .ulCtrlPort1 = (uint32_t) STM32F4_USART_4, - .ulCtrlPort2 = 3, - .ulClock = STM32F4_USART_BAUD, - .ulIntVector = STM32F4_IRQ_UART4 - }, - #endif - #ifdef STM32F4_ENABLE_UART_5 - { - .sDeviceName = "/dev/ttyS4", - .deviceType = SERIAL_CUSTOM, - .pDeviceFns = &stm32f4_usart_fns, - .ulCtrlPort1 = (uint32_t) STM32F4_USART_5, - .ulCtrlPort2 = 4, - .ulClock = STM32F4_USART_BAUD, - .ulIntVector = STM32F4_IRQ_UART5 - }, - #endif - #ifdef STM32F4_ENABLE_USART_6 - { - .sDeviceName = "/dev/ttyS5", - .deviceType = SERIAL_CUSTOM, - .pDeviceFns = &stm32f4_usart_fns, - .ulCtrlPort1 = (uint32_t) STM32F4_USART_6, - .ulCtrlPort2 = 5, - .ulClock = STM32F4_USART_BAUD, - .ulIntVector = STM32F4_IRQ_USART6 - }, - #endif -}; - -#define PORT_COUNT \ - (sizeof(Console_Configuration_Ports) \ - / sizeof(Console_Configuration_Ports [0])) - -unsigned long Console_Configuration_Count = PORT_COUNT; - -static void output_char(char c) -{ - const console_fns *con = - Console_Configuration_Ports [Console_Port_Minor].pDeviceFns; - - con->deviceWritePolled((int) Console_Port_Minor, c); -} - -BSP_output_char_function_type BSP_output_char = output_char; - -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/arm/stm32f4/console/usart.c b/c/src/lib/libbsp/arm/stm32f4/console/usart.c deleted file mode 100644 index 24e010d6bf..0000000000 --- a/c/src/lib/libbsp/arm/stm32f4/console/usart.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2012 Sebastian Huber. All rights reserved. - * - * embedded brains GmbH - * Obere Lagerstr. 30 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include -#include -#include -#include -#include - -static volatile stm32f4_usart *usart_get_regs(const console_tbl *ct) -{ - return (stm32f4_usart *) ct->ulCtrlPort1; -} - -#if 0 -static rtems_vector_number usart_get_irq_number(const console_tbl *ct) -{ - return ct->ulIntVector; -} -#endif - -static const stm32f4_rcc_index usart_rcc_index [] = { - STM32F4_RCC_USART1, - STM32F4_RCC_USART2, - STM32F4_RCC_USART3, - STM32F4_RCC_UART4, - STM32F4_RCC_UART5, -#ifdef STM32F4_FAMILY_F4XXXX - STM32F4_RCC_USART6 -#endif /* STM32F4_FAMILY_F4XXXX */ -}; - -static stm32f4_rcc_index usart_get_rcc_index(const console_tbl *ct) -{ - return usart_rcc_index [ct->ulCtrlPort2]; -} - -static const uint8_t usart_pclk_index [] = { 1, 0, 0, 0, 0, 1 }; - -static const uint32_t usart_pclk_by_index [] = { - STM32F4_PCLK1, - STM32F4_PCLK2 -}; - -static uint32_t usart_get_pclk(const console_tbl *ct) -{ - return usart_pclk_by_index [usart_pclk_index [ct->ulCtrlPort2]]; -} - -static uint32_t usart_get_baud(const console_tbl *ct) -{ - return ct->ulClock; -} - -/* - * a = 8 * (2 - CR1[OVER8]) - * - * usartdiv = div_mantissa + div_fraction / a - * - * baud = pclk / (a * usartdiv) - * - * usartdiv = pclk / (a * baud) - * - * Calculation in integer arithmetic: - * - * 1. div_mantissa = pclk / (a * baud) - * - * 2. div_fraction = pclk / (baud - a * div_mantissa) - */ -static uint32_t usart_get_bbr( - volatile stm32f4_usart *usart, - uint32_t pclk, - uint32_t baud -) -{ - uint32_t a = 8 * (2 - ((usart->cr1 & STM32F4_USART_CR1_OVER8) != 0)); - uint32_t div_mantissa_low = pclk / (a * baud); - uint32_t div_fraction_low = pclk / (baud - a * div_mantissa_low); - uint32_t div_mantissa_high; - uint32_t div_fraction_high; - uint32_t high_err; - uint32_t low_err; - uint32_t div_mantissa; - uint32_t div_fraction; - - if (div_fraction_low < a - 1) { - div_mantissa_high = div_fraction_low; - div_fraction_high = div_fraction_low + 1; - } else { - div_mantissa_high = div_fraction_low + 1; - div_fraction_high = 0; - } - - high_err = pclk - baud * (a * div_mantissa_high + div_fraction_high); - low_err = baud * (a * div_mantissa_low + div_fraction_low) - pclk; - - if (low_err < high_err) { - div_mantissa = div_mantissa_low; - div_fraction = div_fraction_low; - } else { - div_mantissa = div_mantissa_high; - div_fraction = div_fraction_high; - } - - return STM32F4_USART_BBR_DIV_MANTISSA(div_mantissa) - | STM32F4_USART_BBR_DIV_FRACTION(div_fraction); -} - -static void usart_initialize(int minor) -{ - const console_tbl *ct = Console_Port_Tbl [minor]; - volatile stm32f4_usart *usart = usart_get_regs(ct); - uint32_t pclk = usart_get_pclk(ct); - uint32_t baud = usart_get_baud(ct); - stm32f4_rcc_index rcc_index = usart_get_rcc_index(ct); - - stm32f4_rcc_set_clock(rcc_index, true); - - usart->cr1 = 0; - usart->cr2 = 0; - usart->cr3 = 0; - usart->bbr = usart_get_bbr(usart, pclk, baud); - usart->cr1 = STM32F4_USART_CR1_UE - | STM32F4_USART_CR1_TE - | STM32F4_USART_CR1_RE; -} - -static int usart_first_open(int major, int minor, void *arg) -{ - rtems_libio_open_close_args_t *oc = (rtems_libio_open_close_args_t *) arg; - struct rtems_termios_tty *tty = (struct rtems_termios_tty *) oc->iop->data1; - const console_tbl *ct = Console_Port_Tbl [minor]; - console_data *cd = &Console_Port_Data [minor]; - - cd->termios_data = tty; - rtems_termios_set_initial_baud(tty, ct->ulClock); - - return 0; -} - -static int usart_last_close(int major, int minor, void *arg) -{ - return 0; -} - -static int usart_read_polled(int minor) -{ - const console_tbl *ct = Console_Port_Tbl [minor]; - volatile stm32f4_usart *usart = usart_get_regs(ct); - - if ((usart->sr & STM32F4_USART_SR_RXNE) != 0) { - return STM32F4_USART_DR_GET(usart->dr); - } else { - return -1; - } -} - -static void usart_write_polled(int minor, char c) -{ - const console_tbl *ct = Console_Port_Tbl [minor]; - volatile stm32f4_usart *usart = usart_get_regs(ct); - - while ((usart->sr & STM32F4_USART_SR_TXE) == 0) { - /* Wait */ - } - - usart->dr = STM32F4_USART_DR(c); -} - -static ssize_t usart_write_support_polled( - int minor, - const char *s, - size_t n -) -{ - ssize_t i = 0; - - for (i = 0; i < n; ++i) { - usart_write_polled(minor, s [i]); - } - - return n; -} - -static int usart_set_attributes(int minor, const struct termios *term) -{ - return -1; -} - -const console_fns stm32f4_usart_fns = { - .deviceProbe = libchip_serial_default_probe, - .deviceFirstOpen = usart_first_open, - .deviceLastClose = usart_last_close, - .deviceRead = usart_read_polled, - .deviceWrite = usart_write_support_polled, - .deviceInitialize = usart_initialize, - .deviceWritePolled = usart_write_polled, - .deviceSetAttributes = usart_set_attributes, - .deviceOutputUsesInterrupts = false -}; diff --git a/c/src/lib/libbsp/arm/tms570/Makefile.am b/c/src/lib/libbsp/arm/tms570/Makefile.am index 3857fc4fda..106d6c1d9e 100644 --- a/c/src/lib/libbsp/arm/tms570/Makefile.am +++ b/c/src/lib/libbsp/arm/tms570/Makefile.am @@ -62,9 +62,9 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c librtemsbsp_a_SOURCES += irq/irq.c # Console -librtemsbsp_a_SOURCES += ../../shared/console-termios.c -librtemsbsp_a_SOURCES += console/printk-support.c -librtemsbsp_a_SOURCES += console/tms570-sci.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/tms570/console/printk-support.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/tms570/console/tms570-sci.c # Clock librtemsbsp_a_SOURCES +=../../../../../../bsps/arm/tms570/clock/clock.c diff --git a/c/src/lib/libbsp/arm/tms570/console/printk-support.c b/c/src/lib/libbsp/arm/tms570/console/printk-support.c deleted file mode 100644 index 529c5dba20..0000000000 --- a/c/src/lib/libbsp/arm/tms570/console/printk-support.c +++ /dev/null @@ -1,126 +0,0 @@ -/** - * @file printk-support.c - * - * @ingroup tms570 - * - * @brief definitions of serial line for debugging. - */ - -/* - * Copyright (c) 2014 Premysl Houdek - * - * Google Summer of Code 2014 at - * Czech Technical University in Prague - * Zikova 1903/4 - * 166 36 Praha 6 - * Czech Republic - * - * Based on LPC24xx and LPC1768 BSP - * by embedded brains GmbH and others - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include -#include - -#define TMS570_CONSOLE (&driver_context_table[0]) - -/** - * @brief Puts chars into peripheral - * - * debug functions always use serial dev 0 peripheral - * - * @retval Void - */ -static void tms570_debug_console_putc(char ch) -{ - tms570_sci_context *ctx = TMS570_CONSOLE; - volatile tms570_sci_t *regs = ctx->regs; - rtems_interrupt_level level; - - rtems_interrupt_disable(level); - while ( ( regs->FLR & TMS570_SCI_FLR_TXRDY ) == 0) { - rtems_interrupt_flash(level); - } - regs->TD = ch; - while ( ( regs->FLR & TMS570_SCI_FLR_TX_EMPTY ) == 0) { - rtems_interrupt_flash(level); - } - rtems_interrupt_enable(level); -} - -/** - * @brief debug console output - * - * debug functions always use serial dev 0 peripheral - * - * @retval Void - */ -static void tms570_debug_console_out(char c) -{ - tms570_debug_console_putc(c); -} - -static void tms570_debug_console_init(void) -{ - tms570_sci_context *ctx = TMS570_CONSOLE; - struct termios term; - - tms570_sci_initialize(ctx); - memset(&term, 0, sizeof(term)); - term.c_cflag = B115200; - tms570_sci_set_attributes(&ctx->base, &term); - BSP_output_char = tms570_debug_console_out; -} - -static void tms570_debug_console_early_init(char c) -{ - tms570_debug_console_init(); - tms570_debug_console_out(c); -} - -/** - * @brief debug console input - * - * debug functions always use serial dev 0 peripheral - * - * @retval x Read char - * @retval -1 No input character available - */ -static int tms570_debug_console_in( void ) -{ - tms570_sci_context *ctx = TMS570_CONSOLE; - volatile tms570_sci_t *regs = ctx->regs; - rtems_interrupt_level level; - int c; - - rtems_interrupt_disable(level); - - if ( regs->FLR & TMS570_SCI_FLR_RXRDY ) { - c = (unsigned char) regs->RD; - } else { - c = -1; - } - - rtems_interrupt_enable(level); - - return c; -} - -BSP_output_char_function_type BSP_output_char = - tms570_debug_console_early_init; - -BSP_polling_getchar_function_type BSP_poll_char = tms570_debug_console_in; - -RTEMS_SYSINIT_ITEM( - tms570_debug_console_init, - RTEMS_SYSINIT_BSP_START, - RTEMS_SYSINIT_ORDER_LAST -); diff --git a/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c b/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c deleted file mode 100644 index 48986e9a2e..0000000000 --- a/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c +++ /dev/null @@ -1,642 +0,0 @@ -/** - * @file tms570-sci.c - * - * @ingroup tms570 - * - * @brief Serial communication interface (SCI) functions definitions. - */ - -/* - * Copyright (c) 2014 Premysl Houdek - * - * Google Summer of Code 2014 at - * Czech Technical University in Prague - * Zikova 1903/4 - * 166 36 Praha 6 - * Czech Republic - * - * Based on LPC24xx and LPC1768 BSP - * by embedded brains GmbH and others - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TMS570_SCI_BUFFER_SIZE 1 - -/** - * @brief Table including all serial drivers - * - * Definitions of all serial drivers - */ -tms570_sci_context driver_context_table[] = { - { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("TMS570 SCI1"), - .device_name = "/dev/console", - /* TMS570 UART peripheral use subset of LIN registers which are equivalent - * to SCI ones - */ - .regs = (volatile tms570_sci_t *) &TMS570_LIN, - .irq = TMS570_IRQ_SCI_LEVEL_0, - }, - { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("TMS570 SCI2"), - .device_name = "/dev/ttyS1", - .regs = &TMS570_SCI, - .irq = TMS570_IRQ_SCI2_LEVEL_0, - } -}; - -void tms570_sci_initialize(tms570_sci_context *ctx) -{ - uint32_t rx_pin = 1 << 1; - uint32_t tx_pin = 1 << 2; - - /* Resec SCI peripheral */ - ctx->regs->GCR0 = TMS570_SCI_GCR0_RESET * 0; - ctx->regs->GCR0 = TMS570_SCI_GCR0_RESET * 1; - - /* Clear all interrupt sources */ - ctx->regs->CLEARINT = 0xffffffff; - - /* Map all interrupts to SCI INT0 line */ - ctx->regs->CLEARINTLVL = 0xffffffff; - - ctx->regs->GCR1 = TMS570_SCI_GCR1_TXENA * 0 | - TMS570_SCI_GCR1_RXENA * 0 | - TMS570_SCI_GCR1_CONT * 0 | /* continue operation when debugged */ - TMS570_SCI_GCR1_LOOP_BACK * 0 | - TMS570_SCI_GCR1_POWERDOWN * 0 | - TMS570_SCI_GCR1_SLEEP * 0 | - TMS570_SCI_GCR1_SWnRST * 0 | /* reset state */ - TMS570_SCI_GCR1_CLOCK * 1 | /* internal clock */ - TMS570_SCI_GCR1_TIMING_MODE * 1 | - TMS570_SCI_GCR1_COMM_MODE * 0; - - /* Setup connection of SCI peripheral Rx and Tx pins */ - ctx->regs->PIO0 = rx_pin * 1 | tx_pin * 1; /* Rx and Tx pins are not GPIO */ - ctx->regs->PIO3 = rx_pin * 0 | tx_pin * 0; /* Default output low */ - ctx->regs->PIO1 = rx_pin * 0 | tx_pin * 0; /* Input when not used by SCI */ - ctx->regs->PIO6 = rx_pin * 0 | tx_pin * 0; /* No open drain */ - ctx->regs->PIO7 = rx_pin * 0 | tx_pin * 0; /* Pull-up/down enabled */ - ctx->regs->PIO8 = rx_pin * 1 | tx_pin * 1; /* Select pull-up */ - - /* Bring device out of software reset */ - ctx->regs->GCR1 |= TMS570_SCI_GCR1_SWnRST; -} - -/** - * @brief Serial drivers init function - * - * Initialize all serial drivers specified in driver_context_table - * - * @param[in] major - * @param[in] minor - * @param[in] arg - * @retval RTEMS_SUCCESSFUL Initialization completed - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code sc; -#if CONSOLE_USE_INTERRUPTS - const rtems_termios_device_handler *handler = &tms570_sci_handler_interrupt; -#else - const rtems_termios_device_handler *handler = &tms570_sci_handler_polled; -#endif - - /* - * Initialize the Termios infrastructure. If Termios has already - * been initialized by another device driver, then this call will - * have no effect. - */ - rtems_termios_initialize(); - - /* Initialize each device */ - for ( - minor = 0; - minor < RTEMS_ARRAY_SIZE(driver_context_table); - ++minor - ) { - tms570_sci_context *ctx = &driver_context_table[minor]; - - tms570_sci_initialize(ctx); - - /* - * Install this device in the file system and Termios. In order - * to use the console (i.e. being able to do printf, scanf etc. - * on stdin, stdout and stderr), one device must be registered as - * "/dev/console" (CONSOLE_DEVICE_NAME). - */ - sc = rtems_termios_device_install( - ctx->device_name, - handler, - NULL, - &ctx->base - ); - if ( sc != RTEMS_SUCCESSFUL ) { - bsp_fatal(BSP_FATAL_CONSOLE_NO_DEV); - } - } - return RTEMS_SUCCESSFUL; -} - -/** - * @brief Reads chars from HW - * - * Reads chars from HW peripheral specified in driver context. - * TMS570 does not have HW buffer for serial line so this function can - * return only 0 or 1 char - * - * @param[in] ctx context of the driver - * @param[out] buf read data buffer - * @param[in] N size of buffer - * @retval x Number of read chars from peripherals - */ -static int tms570_sci_read_received_chars( - tms570_sci_context * ctx, - char * buf, - int N) -{ - if ( N < 1 ) { - return 0; - } - if ( ctx->regs->RD != 0 ) { - buf[0] = ctx->regs->RD; - return 1; - } - return 0; -} - -/** - * @brief Enables RX interrupt - * - * Enables RX interrupt source of SCI peripheral - * specified in the driver context. - * - * @param[in] ctx context of the driver - * @retval Void - */ -static void tms570_sci_enable_interrupts(tms570_sci_context * ctx) -{ - ctx->regs->SETINT = TMS570_SCI_SETINT_SET_RX_INT; -} - -/** - * @brief Disables RX interrupt - * - * Disables RX interrupt source of SCI peripheral specified in the driver - * context. - * - * @param[in] ctx context of the driver - * @retval Void - */ -static void tms570_sci_disable_interrupts(tms570_sci_context * ctx) -{ - ctx->regs->CLEARINT = TMS570_SCI_CLEARINT_CLR_RX_INT; -} - -/** - * @brief Check whether driver has put char in HW - * - * Check whether driver has put char in HW. - * This information is read from the driver context not from a peripheral. - * TMS570 does not have write data buffer asociated with SCI - * so the return can be only 0 or 1. - * - * @param[in] ctx context of the driver - * @retval x - */ -static int tms570_sci_transmitted_chars(tms570_sci_context * ctx) -{ - int ret; - - ret = ctx->tx_chars_in_hw; - if ( ret == 1 ) { - ctx->tx_chars_in_hw = 0; - return 1; - } - return ret; -} - -/** - * @brief Set attributes of the HW peripheral - * - * Sets attributes of the HW peripheral (parity, baud rate, etc.) - * - * @param[in] base context of the driver - * @param[in] t termios driver - * @retval true peripheral setting is changed - */ -bool tms570_sci_set_attributes( - rtems_termios_device_context *base, - const struct termios *t -) -{ - tms570_sci_context *ctx = (tms570_sci_context *) base; - rtems_interrupt_lock_context lock_context; - int32_t bauddiv; - int32_t baudrate; - uint32_t flr_tx_ready = TMS570_SCI_FLR_TX_EMPTY; - /* - * Test for TMS570_SCI_FLR_TXRDY is not necessary - * because both SCITD and SCITXSHF has to be empty - * to TX_EMPTY be asserted. But there is no interrupt - * option for TX_EMPTY. Polling is used isntead. - */ - - /* Baud rate */ - baudrate = rtems_termios_baud_to_number(cfgetospeed(t)); - - rtems_termios_device_lock_acquire(base, &lock_context); - - while ( (ctx->regs->GCR1 & TMS570_SCI_GCR1_TXENA) && - (ctx->regs->FLR & flr_tx_ready) != flr_tx_ready) { - /* - * There are pending characters in the hardware, - * change in the middle of the character Tx leads - * to disturb of the character and SCI engine - */ - rtems_interval tw; - - rtems_termios_device_lock_release(base, &lock_context); - - tw = rtems_clock_get_ticks_per_second(); - tw = tw * 5 / baudrate + 1; - rtems_task_wake_after( tw ); - - rtems_termios_device_lock_acquire(base, &lock_context); - } - - ctx->regs->GCR1 &= ~( TMS570_SCI_GCR1_SWnRST | TMS570_SCI_GCR1_TXENA | - TMS570_SCI_GCR1_RXENA ); - - ctx->regs->GCR1 &= ~TMS570_SCI_GCR1_STOP; /*one stop bit*/ - ctx->regs->FORMAT = TMS570_SCI_FORMAT_CHAR(0x7); - - switch ( t->c_cflag & ( PARENB|PARODD ) ) { - case ( PARENB|PARODD ): - /* Odd parity */ - ctx->regs->GCR1 &= ~TMS570_SCI_GCR1_PARITY; - ctx->regs->GCR1 |= TMS570_SCI_GCR1_PARITY_ENA; - break; - - case PARENB: - /* Even parity */ - ctx->regs->GCR1 |= TMS570_SCI_GCR1_PARITY; - ctx->regs->GCR1 |= TMS570_SCI_GCR1_PARITY_ENA; - break; - - default: - case 0: - case PARODD: - /* No Parity */ - ctx->regs->GCR1 &= ~TMS570_SCI_GCR1_PARITY_ENA; - } - - /* Apply baudrate to the hardware */ - baudrate *= 2 * 16; - bauddiv = (BSP_PLL_OUT_CLOCK + baudrate / 2) / baudrate; - ctx->regs->BRS = bauddiv; - - ctx->regs->GCR1 |= TMS570_SCI_GCR1_SWnRST | TMS570_SCI_GCR1_TXENA | - TMS570_SCI_GCR1_RXENA; - - rtems_termios_device_lock_release(base, &lock_context); - - return true; -} - -/** - * @brief sci interrupt handler - * - * Handler checks which interrupt occured and provides nessesary maintenance - * dequeue characters in termios driver whether character is send succesfully - * enqueue characters in termios driver whether character is recieved - * - * @param[in] arg rtems_termios_tty - * @retval Void - */ -static void tms570_sci_interrupt_handler(void * arg) -{ - rtems_termios_tty *tty = arg; - tms570_sci_context *ctx = rtems_termios_get_device_context(tty); - char buf[TMS570_SCI_BUFFER_SIZE]; - size_t n; - - /* - * Check if we have received something. - */ - if ( (ctx->regs->FLR & TMS570_SCI_FLR_RXRDY ) == TMS570_SCI_FLR_RXRDY ) { - n = tms570_sci_read_received_chars(ctx, buf, TMS570_SCI_BUFFER_SIZE); - if ( n > 0 ) { - /* Hand the data over to the Termios infrastructure */ - rtems_termios_enqueue_raw_characters(tty, buf, n); - } - } - /* - * Check if we have something transmitted. - */ - if ( (ctx->regs->FLR & TMS570_SCI_FLR_TXRDY ) == TMS570_SCI_FLR_TXRDY ) { - n = tms570_sci_transmitted_chars(ctx); - if ( n > 0 ) { - /* - * Notify Termios that we have transmitted some characters. It - * will call now the interrupt write function if more characters - * are ready for transmission. - */ - rtems_termios_dequeue_characters(tty, n); - } - } -} - -/** - * @brief sci write function called from interrupt - * - * Nonblocking write function. Writes characters to HW peripheral - * TMS570 does not have write data buffer asociated with SCI - * so only one character can be written. - * - * @param[in] base context of the driver - * @param[in] buf buffer of characters pending to send - * @param[in] len size of the buffer - * @retval Void - */ -static void tms570_sci_interrupt_write( - rtems_termios_device_context *base, - const char *buf, - size_t len -) -{ - tms570_sci_context *ctx = (tms570_sci_context *) base; - - if ( len > 0 ) { - /* start UART TX, this will result in an interrupt when done */ - ctx->regs->TD = *buf; - /* character written - raise count*/ - ctx->tx_chars_in_hw = 1; - /* Enable TX interrupt (interrupt is edge-triggered) */ - ctx->regs->SETINT = (1<<8); - - } else { - /* No more to send, disable TX interrupts */ - ctx->regs->CLEARINT = (1<<8); - /* Tell close that we sent everything */ - } -} - -/** - * @brief sci write function - * - * Blocking write function. Waits until HW peripheral is ready and then writes - * character to HW peripheral. Writes all characters in the buffer. - * - * @param[in] base context of the driver - * @param[in] buf buffer of characters pending to send - * @param[in] len size of the buffer - * @retval Void - */ -static void tms570_sci_poll_write( - rtems_termios_device_context *base, - const char *buf, - size_t n -) -{ - tms570_sci_context *ctx = (tms570_sci_context *) base; - size_t i; - - /* Write */ - - for ( i = 0; i < n; ++i ) { - while ( (ctx->regs->FLR & TMS570_SCI_FLR_TX_EMPTY ) == 0) { - ; - } - ctx->regs->TD = buf[i]; - } -} - -/** - * @brief See if there is recieved charakter to read - * - * read the RX flag from peripheral specified in context - * - * @param[in] ctx context of the driver - * @retval 0 No character to read - * @retval x Character ready to read - */ -static int TMS570_sci_can_read_char( - tms570_sci_context * ctx -) -{ - return ctx->regs->FLR & TMS570_SCI_FLR_RXRDY; -} - -/** - * @brief reads character from peripheral - * - * reads the recieved character from peripheral specified in context - * - * @param[in] ctx context of the driver - * @retval x Character - */ -static char TMS570_sci_read_char( - tms570_sci_context * ctx -) -{ - return ctx->regs->RD; -} - -/** - * @brief sci read function - * - * check if there is recieved character to be read and reads it. - * - * @param[in] base context of the driver - * @retval -1 No character to be read - * @retval x Read character - */ -static int tms570_sci_poll_read(rtems_termios_device_context *base) -{ - tms570_sci_context *ctx = (tms570_sci_context *) base; - - /* Check if a character is available */ - if ( TMS570_sci_can_read_char(ctx) ) { - return TMS570_sci_read_char(ctx); - } else { - return -1; - } -} - -/** - * @brief initialization of the driver - * - * initialization of the HW peripheral specified in contex of the driver. - * This function is called only once when opening the driver. - * - * @param[in] tty Termios control - * @param[in] ctx context of the driver - * @param[in] term Termios attributes - * @param[in] args - * @retval false Error occured during initialization - * @retval true Driver is open and ready - */ -static bool tms570_sci_poll_first_open( - rtems_termios_tty *tty, - rtems_termios_device_context *ctx, - struct termios *term, - rtems_libio_open_close_args_t *args -) -{ - bool ok; - - rtems_termios_set_best_baud(term, TMS570_SCI_BAUD_RATE); - ok = tms570_sci_set_attributes(ctx, term); - if ( !ok ) { - return false; - } - return true; -} - -/** - * @brief initialization of the interrupt driven driver - * - * calls tms570_sci_poll_first_open function. - * install and enables interrupts. - * - * @param[in] tty Termios control - * @param[in] base context of the driver - * @param[in] args - * @retval false Error occured during initialization - * @retval true Driver is open and ready - */ -static bool tms570_sci_interrupt_first_open( - rtems_termios_tty *tty, - rtems_termios_device_context *base, - struct termios *term, - rtems_libio_open_close_args_t *args -) -{ - tms570_sci_context *ctx = (tms570_sci_context *) base; - rtems_status_code sc; - bool ret; - - ret = tms570_sci_poll_first_open(tty, base, term, args); - if ( ret == false ) { - return false; - } - - /* Register Interrupt handler */ - sc = rtems_interrupt_handler_install(ctx->irq, - ctx->device_name, - RTEMS_INTERRUPT_SHARED, - tms570_sci_interrupt_handler, - tty - ); - if ( sc != RTEMS_SUCCESSFUL ) { - return false; - } - tms570_sci_enable_interrupts(ctx); - return true; -} - -/** - * @brief closes sci peripheral - * - * @param[in] tty Termios control - * @param[in] base context of the driver - * @param[in] args - * @retval false Error occured during initialization - * @retval true Driver is open and ready - */ -static void tms570_sci_poll_last_close( - rtems_termios_tty *tty, - rtems_termios_device_context *base, - rtems_libio_open_close_args_t *args -) -{ - ; -} - -/** - * @brief closes sci peripheral of interrupt driven driver - * - * calls tms570_sci_poll_last_close and disables interrupts - * - * @param[in] tty Termios control - * @param[in] base context of the driver - * @param[in] args - * @retval false Error occured during initialization - * @retval true Driver is open and ready - */ -static void tms570_sci_interrupt_last_close( - rtems_termios_tty *tty, - rtems_termios_device_context *base, - rtems_libio_open_close_args_t *args -) -{ - tms570_sci_context *ctx = (tms570_sci_context *) base; - rtems_interrupt_lock_context lock_context; - rtems_interval tw; - int32_t baudrate; - - /* Turn off RX interrupts */ - rtems_termios_device_lock_acquire(base, &lock_context); - tms570_sci_disable_interrupts(ctx); - rtems_termios_device_lock_release(base, &lock_context); - - tw = rtems_clock_get_ticks_per_second(); - baudrate = rtems_termios_baud_to_number(cfgetospeed(&tty->termios)); - tw = tw * 10 / baudrate + 1; - while ( ( ctx->regs->FLR & TMS570_SCI_FLR_TX_EMPTY ) == 0 ) { - rtems_task_wake_after(tw); - } - - /* uninstall ISR */ - rtems_interrupt_handler_remove(ctx->irq, tms570_sci_interrupt_handler, tty); - - tms570_sci_poll_last_close(tty, base, args); -} - -/** - * @brief Struct containing definitions of polled driver functions. - * - * Encapsulates polled driver functions. - * Use of this table is determited by not defining TMS570_USE_INTERRUPTS - */ -const rtems_termios_device_handler tms570_sci_handler_polled = { - .first_open = tms570_sci_poll_first_open, - .last_close = tms570_sci_poll_last_close, - .poll_read = tms570_sci_poll_read, - .write = tms570_sci_poll_write, - .set_attributes = tms570_sci_set_attributes, - .mode = TERMIOS_POLLED -}; - -/** - * @brief Struct containing definitions of interrupt driven driver functions. - * - * Encapsulates interrupt driven driver functions. - * Use of this table is determited by defining TMS570_USE_INTERRUPTS - */ -const rtems_termios_device_handler tms570_sci_handler_interrupt = { - .first_open = tms570_sci_interrupt_first_open, - .last_close = tms570_sci_interrupt_last_close, - .poll_read = NULL, - .write = tms570_sci_interrupt_write, - .set_attributes = tms570_sci_set_attributes, - .mode = TERMIOS_IRQ_DRIVEN -}; diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am b/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am index 823c92be4b..0b468fd12e 100644 --- a/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am +++ b/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am @@ -59,10 +59,10 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c librtemsbsp_a_SOURCES += ../shared/arm-gic-irq.c # Console -librtemsbsp_a_SOURCES += ../../shared/console-termios.c -librtemsbsp_a_SOURCES += console/console-config.c -librtemsbsp_a_SOURCES += console/debug-console.c -librtemsbsp_a_SOURCES += console/zynq-uart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/xilinx-zynq/console/console-config.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/xilinx-zynq/console/debug-console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/xilinx-zynq/console/zynq-uart.c # Clock librtemsbsp_a_SOURCES += ../shared/arm-a9mpcore-clock-config.c diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/console/console-config.c b/c/src/lib/libbsp/arm/xilinx-zynq/console/console-config.c deleted file mode 100644 index ce7da2f114..0000000000 --- a/c/src/lib/libbsp/arm/xilinx-zynq/console/console-config.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include - -#include -#include - -#include - -zynq_uart_context zynq_uart_instances[2] = { - { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 0" ), - .regs = (volatile struct zynq_uart *) 0xe0000000, - .irq = ZYNQ_IRQ_UART_0 - }, { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 1" ), - .regs = (volatile struct zynq_uart *) 0xe0001000, - .irq = ZYNQ_IRQ_UART_1 - } -}; - -rtems_status_code console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - size_t i; - - rtems_termios_initialize(); - - for (i = 0; i < RTEMS_ARRAY_SIZE(zynq_uart_instances); ++i) { - char uart[] = "/dev/ttySX"; - - uart[sizeof(uart) - 2] = (char) ('0' + i); - rtems_termios_device_install( - &uart[0], - &zynq_uart_handler, - NULL, - &zynq_uart_instances[i].base - ); - - if (i == BSP_CONSOLE_MINOR) { - link(&uart[0], CONSOLE_DEVICE_NAME); - } - } - - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/console/debug-console.c b/c/src/lib/libbsp/arm/xilinx-zynq/console/debug-console.c deleted file mode 100644 index 38c0050e90..0000000000 --- a/c/src/lib/libbsp/arm/xilinx-zynq/console/debug-console.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include - -#include - -#include - -static void zynq_debug_console_out(char c) -{ - rtems_termios_device_context *base = - &zynq_uart_instances[BSP_CONSOLE_MINOR].base; - - zynq_uart_write_polled(base, c); -} - -static void zynq_debug_console_init(void) -{ - rtems_termios_device_context *base = - &zynq_uart_instances[BSP_CONSOLE_MINOR].base; - - zynq_uart_initialize(base); - BSP_output_char = zynq_debug_console_out; -} - -static void zynq_debug_console_early_init(char c) -{ - rtems_termios_device_context *base = - &zynq_uart_instances[BSP_CONSOLE_MINOR].base; - - zynq_uart_initialize(base); - zynq_debug_console_out(c); -} - -static int zynq_debug_console_in(void) -{ - rtems_termios_device_context *base = - &zynq_uart_instances[BSP_CONSOLE_MINOR].base; - - return zynq_uart_read_polled(base); -} - -BSP_output_char_function_type BSP_output_char = zynq_debug_console_early_init; - -BSP_polling_getchar_function_type BSP_poll_char = zynq_debug_console_in; - -RTEMS_SYSINIT_ITEM( - zynq_debug_console_init, - RTEMS_SYSINIT_BSP_START, - RTEMS_SYSINIT_ORDER_LAST -); diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/console/zynq-uart.c b/c/src/lib/libbsp/arm/xilinx-zynq/console/zynq-uart.c deleted file mode 100644 index fa91f3f46e..0000000000 --- a/c/src/lib/libbsp/arm/xilinx-zynq/console/zynq-uart.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include - -#include - -/* - * Make weak and let the user override. - */ -uint32_t zynq_uart_input_clock(void) __attribute__ ((weak)); - -uint32_t zynq_uart_input_clock(void) -{ - return ZYNQ_CLOCK_UART; -} - -static int zynq_cal_baud_rate(uint32_t baudrate, - uint32_t* brgr, - uint32_t* bauddiv, - uint32_t modereg) -{ - uint32_t brgr_value; /* Calculated value for baud rate generator */ - uint32_t calcbaudrate; /* Calculated baud rate */ - uint32_t bauderror; /* Diff between calculated and requested baud rate */ - uint32_t best_error = 0xFFFFFFFF; - uint32_t percenterror; - uint32_t bdiv; - uint32_t inputclk = zynq_uart_input_clock(); - - /* - * Make sure the baud rate is not impossilby large. - * Fastest possible baud rate is Input Clock / 2. - */ - if ((baudrate * 2) > inputclk) { - return -1; - } - /* - * Check whether the input clock is divided by 8 - */ - if(modereg & ZYNQ_UART_MODE_CLKS) { - inputclk = inputclk / 8; - } - - /* - * Determine the Baud divider. It can be 4to 254. - * Loop through all possible combinations - */ - for (bdiv = 4; bdiv < 255; bdiv++) { - - /* - * Calculate the value for BRGR register - */ - brgr_value = inputclk / (baudrate * (bdiv + 1)); - - /* - * Calculate the baud rate from the BRGR value - */ - calcbaudrate = inputclk/ (brgr_value * (bdiv + 1)); - - /* - * Avoid unsigned integer underflow - */ - if (baudrate > calcbaudrate) { - bauderror = baudrate - calcbaudrate; - } - else { - bauderror = calcbaudrate - baudrate; - } - - /* - * Find the calculated baud rate closest to requested baud rate. - */ - if (best_error > bauderror) { - *brgr = brgr_value; - *bauddiv = bdiv; - best_error = bauderror; - } - } - - /* - * Make sure the best error is not too large. - */ - percenterror = (best_error * 100) / baudrate; -#define XUARTPS_MAX_BAUD_ERROR_RATE 3 /* max % error allowed */ - if (XUARTPS_MAX_BAUD_ERROR_RATE < percenterror) { - return -1; - } - - return 0; -} - -void zynq_uart_initialize(rtems_termios_device_context *base) -{ - zynq_uart_context *ctx = (zynq_uart_context *) base; - volatile zynq_uart *regs = ctx->regs; - uint32_t brgr = 0x3e; - uint32_t bauddiv = 0x6; - - zynq_cal_baud_rate(ZYNQ_UART_DEFAULT_BAUD, &brgr, &bauddiv, regs->mode); - - regs->control &= ~(ZYNQ_UART_CONTROL_RXEN | ZYNQ_UART_CONTROL_TXEN); - regs->control = ZYNQ_UART_CONTROL_RXDIS - | ZYNQ_UART_CONTROL_TXDIS - | ZYNQ_UART_CONTROL_RXRES - | ZYNQ_UART_CONTROL_TXRES; - regs->mode = ZYNQ_UART_MODE_CHMODE(ZYNQ_UART_MODE_CHMODE_NORMAL) - | ZYNQ_UART_MODE_PAR(ZYNQ_UART_MODE_PAR_NONE) - | ZYNQ_UART_MODE_CHRL(ZYNQ_UART_MODE_CHRL_8); - regs->baud_rate_gen = ZYNQ_UART_BAUD_RATE_GEN_CD(brgr); - regs->baud_rate_div = ZYNQ_UART_BAUD_RATE_DIV_BDIV(bauddiv); - regs->rx_fifo_trg_lvl = ZYNQ_UART_RX_FIFO_TRG_LVL_RTRIG(0); - regs->rx_timeout = ZYNQ_UART_RX_TIMEOUT_RTO(0); - regs->control = ZYNQ_UART_CONTROL_RXEN - | ZYNQ_UART_CONTROL_TXEN - | ZYNQ_UART_CONTROL_RSTTO; -} - -#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS -static void zynq_uart_interrupt(void *arg) -{ - rtems_termios_tty *tty = arg; - zynq_uart_context *ctx = rtems_termios_get_device_context(tty); - volatile zynq_uart *regs = ctx->regs; - uint32_t channel_sts; - - if ((regs->irq_sts & (ZYNQ_UART_TIMEOUT | ZYNQ_UART_RTRIG)) != 0) { - regs->irq_sts = ZYNQ_UART_TIMEOUT | ZYNQ_UART_RTRIG; - - do { - char c = (char) ZYNQ_UART_TX_RX_FIFO_FIFO_GET(regs->tx_rx_fifo); - - rtems_termios_enqueue_raw_characters(tty, &c, 1); - - channel_sts = regs->channel_sts; - } while ((channel_sts & ZYNQ_UART_CHANNEL_STS_REMPTY) == 0); - } else { - channel_sts = regs->channel_sts; - } - - if (ctx->transmitting && (channel_sts & ZYNQ_UART_CHANNEL_STS_TEMPTY) != 0) { - rtems_termios_dequeue_characters(tty, 1); - } -} -#endif - -static bool zynq_uart_first_open( - rtems_termios_tty *tty, - rtems_termios_device_context *base, - struct termios *term, - rtems_libio_open_close_args_t *args -) -{ -#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS - zynq_uart_context *ctx = (zynq_uart_context *) base; - volatile zynq_uart *regs = ctx->regs; - rtems_status_code sc; -#endif - - rtems_termios_set_initial_baud(tty, ZYNQ_UART_DEFAULT_BAUD); - zynq_uart_initialize(base); - -#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS - regs->rx_timeout = 32; - regs->rx_fifo_trg_lvl = ZYNQ_UART_FIFO_DEPTH / 2; - regs->irq_dis = 0xffffffff; - regs->irq_sts = 0xffffffff; - regs->irq_en = ZYNQ_UART_RTRIG | ZYNQ_UART_TIMEOUT; - sc = rtems_interrupt_handler_install( - ctx->irq, - "UART", - RTEMS_INTERRUPT_SHARED, - zynq_uart_interrupt, - tty - ); - if (sc != RTEMS_SUCCESSFUL) { - return false; - } -#endif - - return true; -} - -#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS -static void zynq_uart_last_close( - rtems_termios_tty *tty, - rtems_termios_device_context *base, - rtems_libio_open_close_args_t *args -) -{ - zynq_uart_context *ctx = (zynq_uart_context *) base; - - rtems_interrupt_handler_remove(ctx->irq, zynq_uart_interrupt, tty); -} -#endif - -int zynq_uart_read_polled(rtems_termios_device_context *base) -{ - zynq_uart_context *ctx = (zynq_uart_context *) base; - volatile zynq_uart *regs = ctx->regs; - - if ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_REMPTY) != 0) { - return -1; - } else { - return ZYNQ_UART_TX_RX_FIFO_FIFO_GET(regs->tx_rx_fifo); - } -} - -void zynq_uart_write_polled( - rtems_termios_device_context *base, - char c -) -{ - zynq_uart_context *ctx = (zynq_uart_context *) base; - volatile zynq_uart *regs = ctx->regs; - - while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TFUL) != 0) { - /* Wait */ - } - - regs->tx_rx_fifo = ZYNQ_UART_TX_RX_FIFO_FIFO(c); -} - -static void zynq_uart_write_support( - rtems_termios_device_context *base, - const char *buf, - size_t len -) -{ -#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS - zynq_uart_context *ctx = (zynq_uart_context *) base; - volatile zynq_uart *regs = ctx->regs; - - if (len > 0) { - ctx->transmitting = true; - regs->irq_sts = ZYNQ_UART_TEMPTY; - regs->irq_en = ZYNQ_UART_TEMPTY; - regs->tx_rx_fifo = ZYNQ_UART_TX_RX_FIFO_FIFO(buf[0]); - } else { - ctx->transmitting = false; - regs->irq_dis = ZYNQ_UART_TEMPTY; - } -#else - ssize_t i; - - for (i = 0; i < len; ++i) { - zynq_uart_write_polled(base, buf[i]); - } -#endif -} - -static bool zynq_uart_set_attributes( - rtems_termios_device_context *context, - const struct termios *term -) -{ -#if 0 - volatile zynq_uart *regs = zynq_uart_get_regs(minor); - uint32_t brgr = 0; - uint32_t bauddiv = 0; - int rc; - - rc = zynq_cal_baud_rate(115200, &brgr, &bauddiv, regs->mode); - if (rc != 0) - return rc; - - regs->control &= ~(ZYNQ_UART_CONTROL_RXEN | ZYNQ_UART_CONTROL_TXEN); - regs->baud_rate_gen = ZYNQ_UART_BAUD_RATE_GEN_CD(brgr); - regs->baud_rate_div = ZYNQ_UART_BAUD_RATE_DIV_BDIV(bauddiv); - regs->control |= ZYNQ_UART_CONTROL_RXEN | ZYNQ_UART_CONTROL_TXEN; - - return true; -#else - return false; -#endif -} - -const rtems_termios_device_handler zynq_uart_handler = { - .first_open = zynq_uart_first_open, - .set_attributes = zynq_uart_set_attributes, - .write = zynq_uart_write_support, -#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS - .last_close = zynq_uart_last_close, - .mode = TERMIOS_IRQ_DRIVEN -#else - .poll_read = zynq_uart_read_polled, - .mode = TERMIOS_POLLED -#endif -}; - -void zynq_uart_reset_tx_flush(zynq_uart_context *ctx) -{ - volatile zynq_uart *regs = ctx->regs; - int c = 4; - - while (c-- > 0) - zynq_uart_write_polled(&ctx->base, '\r'); - - while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TEMPTY) == 0) { - /* Wait */ - } -} diff --git a/c/src/lib/libbsp/bfin/TLL6527M/Makefile.am b/c/src/lib/libbsp/bfin/TLL6527M/Makefile.am index a1fedd768e..b47be73d17 100644 --- a/c/src/lib/libbsp/bfin/TLL6527M/Makefile.am +++ b/c/src/lib/libbsp/bfin/TLL6527M/Makefile.am @@ -25,7 +25,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/getentropy/getentropy librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspgetworkarea-default.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/TLL6527M/console/console.c librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/shared/cache/cache.c librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/TLL6527M/start/interrupt.c diff --git a/c/src/lib/libbsp/bfin/TLL6527M/console/console.c b/c/src/lib/libbsp/bfin/TLL6527M/console/console.c deleted file mode 100644 index 1871bdbb9d..0000000000 --- a/c/src/lib/libbsp/bfin/TLL6527M/console/console.c +++ /dev/null @@ -1,181 +0,0 @@ -/** - *@file console.c - * - *@brief - * - This file implements uart console for TLL6527M. TLL6527M has BF527 with - * second uart (uart-1) connected to the console. - * - * Target: TLL6527v1-0 - * Compiler: - * - * COPYRIGHT (c) 2010 by ECE Northeastern University. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license - * - * @author Rohan Kangralkar, ECE, Northeastern University - * (kangralkar.r@husky.neu.edu) - * - * LastChange: - */ - -#include -#include -#include -#include -#include - -#include -#include - -/*************************************************** -LOCAL DEFINES - ***************************************************/ - - -/*************************************************** -STATIC GLOBALS - ***************************************************/ -/** - * Declaration of UART - */ -static bfin_uart_channel_t channels[] = { - {"/dev/console", - UART1_BASE_ADDRESS, - DMA10_BASE_ADDRESS, - DMA11_BASE_ADDRESS, - CONSOLE_USE_INTERRUPTS, - UART_USE_DMA, - CONSOLE_BAUDRATE, - NULL, - 0, - 0} -}; - -/** - * Over all configuration - */ -static bfin_uart_config_t config = { - SCLK, - sizeof(channels) / sizeof(channels[0]), - channels -}; - - -#if CONSOLE_USE_INTERRUPTS -/** - * The Rx and Tx isr will get the same argument - * The isr will have to find if it was the rx that caused the interrupt or - * the tx - */ -static bfin_isr_t bfinUARTISRs[] = { -#if UART_USE_DMA - /* For First uart */ - {IRQ_DMA10_UART1_RX, bfinUart_rxDmaIsr, (void *)&channels[0], 0}, - {IRQ_DMA11_UART1_TX, bfinUart_txDmaIsr, (void *)&channels[0], 0}, - /* For second uart */ -#else - /* For First uart */ - {IRQ_DMA10_UART1_RX, bfinUart_rxIsr, &channels[0], 0}, - {IRQ_DMA11_UART1_TX, bfinUart_txIsr, &channels[0], 0}, - /* For second uart */ -#endif -}; -#endif - - -static void TLL6527_BSP_output_char(char c) { - - bfin_uart_poll_write(0, c); -} - -static int TLL6527_BSP_poll_char(void) { - - return bfin_uart_poll_read(0); -} - -BSP_output_char_function_type BSP_output_char = TLL6527_BSP_output_char; -BSP_polling_getchar_function_type BSP_poll_char = TLL6527_BSP_poll_char; - - - -rtems_device_driver console_close(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) { - - return rtems_termios_close(arg); -} - -rtems_device_driver console_read(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) { - - return rtems_termios_read(arg); -} - -rtems_device_driver console_write(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) { - - return rtems_termios_write(arg); -} - -rtems_device_driver console_control(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) { - - return rtems_termios_ioctl(arg); -} - - - -/* - * Open entry point - */ -rtems_device_driver console_open(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) { - - return bfin_uart_open(major, minor, arg); -} - - - -/** - * - * This routine initializes the console IO driver. - * - * Parameters - * @param major major number - * @param minor minor number - * - * Output parameters: NONE - * - * @return void - */ -rtems_device_driver console_initialize(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) { - rtems_status_code status = RTEMS_NOT_DEFINED; -#if CONSOLE_USE_INTERRUPTS - int i = 0; -#endif - - status = bfin_uart_initialize(major, &config); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - -#if CONSOLE_USE_INTERRUPTS - for (i = 0; i < sizeof(bfinUARTISRs) / sizeof(bfinUARTISRs[0]); i++) { - bfin_interrupt_register(&bfinUARTISRs[i]); -#if INTERRUPT_USE_TABLE -#else - bfin_interrupt_enable(&bfinUARTISRs[i], 1); -#endif - } -#endif - - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/lib/libbsp/bfin/bf537Stamp/Makefile.am b/c/src/lib/libbsp/bfin/bf537Stamp/Makefile.am index d86fd55243..e8c3e183f2 100644 --- a/c/src/lib/libbsp/bfin/bf537Stamp/Makefile.am +++ b/c/src/lib/libbsp/bfin/bf537Stamp/Makefile.am @@ -26,7 +26,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/getentropy/getentropy librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspgetworkarea-default.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/bf537Stamp/console/console.c librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/shared/cache/cache.c librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/shared/interrupt.c diff --git a/c/src/lib/libbsp/bfin/bf537Stamp/console/console.c b/c/src/lib/libbsp/bfin/bf537Stamp/console/console.c deleted file mode 100644 index e9fe24cda1..0000000000 --- a/c/src/lib/libbsp/bfin/bf537Stamp/console/console.c +++ /dev/null @@ -1,141 +0,0 @@ -/* Console driver for bf537Stamp - */ - -/* - * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA - * written by Allan Hessenflow - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - - -#include -#include -#include -#include -#include - -#include -#include -#include - -/* -#undef CONSOLE_USE_INTERRUPTS -#define CONSOLE_USE_INTERRUPTS 1 -*/ - -static bfin_uart_channel_t channels[] = { - {"/dev/console", - UART0_BASE_ADDRESS, - 0, - 0, - CONSOLE_USE_INTERRUPTS, - 0, - #ifdef CONSOLE_FORCE_BAUD - CONSOLE_FORCE_BAUD, - #else - 0, - #endif - NULL, - 0, - 0} - -#if (!BFIN_ON_SKYEYE) -, - {"/dev/tty1", - UART1_BASE_ADDRESS, - CONSOLE_USE_INTERRUPTS, - 0, - NULL, - 0} -#endif -}; - -static bfin_uart_config_t config = { - SCLK, - sizeof(channels) / sizeof(channels[0]), - channels -}; - -#if CONSOLE_USE_INTERRUPTS -static bfin_isr_t bfinUARTISRs[] = { - {SIC_DMA8_UART0_RX_VECTOR, bfinUart_rxIsr, 0, 0, NULL}, - {SIC_DMA10_UART1_RX_VECTOR, bfinUart_rxIsr, 0, 0, NULL}, - {SIC_DMA9_UART0_TX_VECTOR, bfinUart_txIsr, 0, 0, NULL}, - {SIC_DMA11_UART1_TX_VECTOR, bfinUart_txIsr, 0, 0, NULL} -}; -#endif - - -static void bf537Stamp_BSP_output_char(char c) { - - bfin_uart_poll_write(0, c); -} - -static int bf537Stamp_BSP_poll_char(void) { - - return bfin_uart_poll_read(0); -} - -BSP_output_char_function_type BSP_output_char = bf537Stamp_BSP_output_char; -BSP_polling_getchar_function_type BSP_poll_char = bf537Stamp_BSP_poll_char; - -rtems_device_driver console_initialize(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) { - rtems_status_code status; -#if CONSOLE_USE_INTERRUPTS - int i; -#endif - - status = bfin_uart_initialize(major, &config); -#if CONSOLE_USE_INTERRUPTS - for (i = 0; i < sizeof(bfinUARTISRs) / sizeof(bfinUARTISRs[0]); i++) { - bfin_interrupt_register(&bfinUARTISRs[i]); - bfin_interrupt_enable(&bfinUARTISRs[i], TRUE); - } -#endif - - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - return RTEMS_SUCCESSFUL; -} - -rtems_device_driver console_open(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) { - - return bfin_uart_open(major, minor, arg); -} - -rtems_device_driver console_close(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) { - - return rtems_termios_close(arg); -} - -rtems_device_driver console_read(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) { - - return rtems_termios_read(arg); -} - -rtems_device_driver console_write(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) { - - return rtems_termios_write(arg); -} - -rtems_device_driver console_control(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) { - - return rtems_termios_ioctl(arg); -} - diff --git a/c/src/lib/libbsp/bfin/eZKit533/Makefile.am b/c/src/lib/libbsp/bfin/eZKit533/Makefile.am index f74b1d6710..d5a0685958 100644 --- a/c/src/lib/libbsp/bfin/eZKit533/Makefile.am +++ b/c/src/lib/libbsp/bfin/eZKit533/Makefile.am @@ -26,7 +26,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/getentropy/getentropy librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspgetworkarea-default.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c -librtemsbsp_a_SOURCES += console/console-io.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/eZKit533/console/console-io.c librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/shared/cache/cache.c librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/shared/interrupt.c diff --git a/c/src/lib/libbsp/bfin/eZKit533/console/console-io.c b/c/src/lib/libbsp/bfin/eZKit533/console/console-io.c deleted file mode 100644 index 5bafb3a094..0000000000 --- a/c/src/lib/libbsp/bfin/eZKit533/console/console-io.c +++ /dev/null @@ -1,126 +0,0 @@ -/* console-io.c - * - * This file contains the hardware specific portions of the TTY driver - * for the serial ports for ezkit533. - * - * Copyright (c) 2006 by Atos Automacao Industrial Ltda. - * written by Alain Schaefer - * and Antonio Giovanini - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - - -#include -#include -#include -#include -#include - -#include -#include -#include - -static bfin_uart_channel_t channels[] = { - {"/dev/console", - UART0_BASE_ADDRESS, - 0, - 0, - CONSOLE_USE_INTERRUPTS, - 0, -#ifdef CONSOLE_FORCE_BAUD - CONSOLE_FORCE_BAUD, -#else - 0, -#endif - NULL, - 0, - 0} -}; - -static bfin_uart_config_t config = { - SCLK, - sizeof(channels) / sizeof(channels[0]), - channels -}; - -#if CONSOLE_USE_INTERRUPTS -static bfin_isr_t bfinUARTISRs[] = { - {SIC_DMA6_UART0_RX_VECTOR, bfinUart_rxIsr, 0, 0, NULL}, - {SIC_DMA7_UART0_TX_VECTOR, bfinUart_txIsr, 0, 0, NULL}, -}; -#endif - - -static void eZKit533_BSP_output_char(char c) { - - bfin_uart_poll_write(0, c); -} - -static int eZKit533_BSP_poll_char(void) { - - return bfin_uart_poll_read(0); -} - -BSP_output_char_function_type BSP_output_char = eZKit533_BSP_output_char; -BSP_polling_getchar_function_type BSP_poll_char = eZKit533_BSP_poll_char; - -rtems_device_driver console_initialize(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) { - rtems_status_code status; -#if CONSOLE_USE_INTERRUPTS - int i; -#endif - - status = bfin_uart_initialize(major, &config); -#if CONSOLE_USE_INTERRUPTS - for (i = 0; i < sizeof(bfinUARTISRs) / sizeof(bfinUARTISRs[0]); i++) { - bfin_interrupt_register(&bfinUARTISRs[i]); - bfin_interrupt_enable(&bfinUARTISRs[i], TRUE); - } -#endif - - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - return RTEMS_SUCCESSFUL; -} - -rtems_device_driver console_open(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) { - - return bfin_uart_open(major, minor, arg); -} - -rtems_device_driver console_close(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) { - - return rtems_termios_close(arg); -} - -rtems_device_driver console_read(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) { - - return rtems_termios_read(arg); -} - -rtems_device_driver console_write(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) { - - return rtems_termios_write(arg); -} - -rtems_device_driver console_control(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) { - - return rtems_termios_ioctl(arg); -} - diff --git a/c/src/lib/libbsp/epiphany/epiphany_sim/Makefile.am b/c/src/lib/libbsp/epiphany/epiphany_sim/Makefile.am index b90849e4e2..4b001ac26c 100644 --- a/c/src/lib/libbsp/epiphany/epiphany_sim/Makefile.am +++ b/c/src/lib/libbsp/epiphany/epiphany_sim/Makefile.am @@ -48,7 +48,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/clock/clock-simidle.c librtemsbsp_a_SOURCES += timer/timer.c # console -librtemsbsp_a_SOURCES += ../../shared/console-polled.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-polled.c # IRQ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c @@ -58,7 +58,7 @@ librtemsbsp_a_SOURCES += irq/irq.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/cache/nocache.c # debugio -librtemsbsp_a_SOURCES += console/console-io.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/epiphany/epiphany_sim/console/console-io.c include $(top_srcdir)/../../../../automake/local.am diff --git a/c/src/lib/libbsp/epiphany/epiphany_sim/console/console-io.c b/c/src/lib/libbsp/epiphany/epiphany_sim/console/console-io.c deleted file mode 100644 index e3da54389f..0000000000 --- a/c/src/lib/libbsp/epiphany/epiphany_sim/console/console-io.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2015 University of York. - * Hesham ALMatary - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include - -static void outbyte_console( char ); -static char inbyte_console( void ); - -void console_initialize_hardware(void) -{ - /* Do nothing */ -} - -/* Epiphany simulator would handle this system call */ -static void outbyte_console(char c) -{ - register int chan asm("r0") = STDOUT_FILENO; - register void* addr asm("r1") = &c; - register int len asm("r2") = 1; - - /* Invoke write system call to be handled by Epiphany simulator */ - __asm__ __volatile__ ("trap 0" : : "r" (chan), "r" (addr), "r" (len)); -} - -static char inbyte_console(void) -{ - char c; - register int chan asm("r0") = STDIN_FILENO; - register void* addr asm("r1") = &c; - register int len asm("r2") = 1; - - /* Invoke read system call to be handled by Epiphany simulator */ - asm ("trap 1" :: "r" (chan), "r" (addr), "r" (len)); - return c; -} - -/* - * console_outbyte_polled - * - * This routine transmits a character using polling. - */ -void console_outbyte_polled( - int port, - char ch -) -{ - outbyte_console( ch ); -} - -/* - * console_inbyte_nonblocking - * - * This routine polls for a character. - */ - -int console_inbyte_nonblocking(int port) -{ - char c; - - c = inbyte_console(); - if (!c) - return -1; - return (int) c; -} - -/* - * To support printk - */ - -#include - -static void Epiphany_output_char(char c) { console_outbyte_polled( 0, c ); } - -BSP_output_char_function_type BSP_output_char = Epiphany_output_char; -BSP_polling_getchar_function_type BSP_poll_char = - (void *)console_inbyte_nonblocking; diff --git a/c/src/lib/libbsp/i386/pc386/Makefile.am b/c/src/lib/libbsp/i386/pc386/Makefile.am index 37a7203ea6..aa10b8f2ad 100644 --- a/c/src/lib/libbsp/i386/pc386/Makefile.am +++ b/c/src/lib/libbsp/i386/pc386/Makefile.am @@ -53,42 +53,42 @@ librtemsbsp_a_SOURCES +=../../../../../../bsps/i386/pc386/clock/todcfg.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/rtc/rtc-support.c if RTEMS_VGA -librtemsbsp_a_SOURCES += console/inch.c -librtemsbsp_a_SOURCES += console/outch.c -librtemsbsp_a_SOURCES += console/defkeymap.c -librtemsbsp_a_SOURCES += console/keyboard.c -librtemsbsp_a_SOURCES += console/pc_keyb.c -librtemsbsp_a_SOURCES += console/ps2_mouse.c -librtemsbsp_a_SOURCES += console/vgainit.c -librtemsbsp_a_SOURCES += console/vt.c -librtemsbsp_a_SOURCES += console/videoAsm.S -librtemsbsp_a_SOURCES += console/kbd_parser.c -librtemsbsp_a_SOURCES += console/vgacons.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/inch.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/outch.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/defkeymap.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/keyboard.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/pc_keyb.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/ps2_mouse.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/vgainit.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/vt.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/videoAsm.S +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/kbd_parser.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/vgacons.c if USE_VGA -librtemsbsp_a_SOURCES += console/fb_vga.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/fb_vga.c endif if USE_CIRRUS_GD5446 -librtemsbsp_a_SOURCES += console/fb_cirrus.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/fb_cirrus.c endif if USE_VBE_RM -librtemsbsp_a_SOURCES += console/fb_vesa_rm.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/fb_vesa_rm.c endif endif # console (non-graphics support) -librtemsbsp_a_SOURCES += console/serial_mouse_config.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/serial_mouse_config.c librtemsbsp_a_SOURCES += ../shared/comm/uart.c librtemsbsp_a_SOURCES += ../shared/comm/tty_drv.c librtemsbsp_a_SOURCES += ../shared/realmode_int/realmode_int.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c -librtemsbsp_a_SOURCES += console/console_select.c -librtemsbsp_a_SOURCES += console/console_control.c -librtemsbsp_a_SOURCES += console/conscfg.c -librtemsbsp_a_SOURCES += console/printk_support.c -librtemsbsp_a_SOURCES += console/exar17d15x.c -librtemsbsp_a_SOURCES += console/rtd316.c -librtemsbsp_a_SOURCES += console/uart_bus_pci.c -librtemsbsp_a_SOURCES += console/gdb_select.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/console_select.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/console_control.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/conscfg.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/printk_support.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/exar17d15x.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/rtd316.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/uart_bus_pci.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/gdb_select.c # gdb librtemsbsp_a_SOURCES += ../shared/comm/i386-stub.c diff --git a/c/src/lib/libbsp/i386/pc386/console/conscfg.c b/c/src/lib/libbsp/i386/pc386/console/conscfg.c deleted file mode 100644 index 07602a3436..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/conscfg.c +++ /dev/null @@ -1,198 +0,0 @@ -/** - * @file - * - * This file contains the libchip configuration information - * to instantiate the libchip driver for the VGA console - * and serial ports on a PC. - */ - -/* - * COPYRIGHT (c) 1989-2014, 2016. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#if BSP_ENABLE_VGA -#include -#endif -#include -#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h" - -#if BSP_ENABLE_VGA -#define VGA_CONSOLE_FUNCTIONS &vgacons_fns -#endif - -#if BSP_ENABLE_COM1_COM4 - #if 0 - #define COM_CONSOLE_FUNCTIONS &ns16550_fns_polled - #else - #define COM_CONSOLE_FUNCTIONS &ns16550_fns - #endif - - /* - * Base IO for UART - */ - #define COM1_BASE_IO 0x3F8 - #define COM2_BASE_IO 0x3E8 - #define COM3_BASE_IO 0x2F8 - #define COM4_BASE_IO 0x2E8 - - #define CLOCK_RATE (115200 * 16) - - static uint8_t com_get_register(uint32_t addr, uint8_t i) - { - register uint8_t val; - - inport_byte( (addr + i), val ); - return val; - } - - static void com_set_register(uint32_t addr, uint8_t i, uint8_t val) - { - outport_byte( (addr + i), val ); - } -#endif - -/* - * Default to the PC VGA console if present and configured. - */ -console_tbl Console_Configuration_Ports[] = { -#if BSP_ENABLE_VGA - /* - * If present the VGA console must always be minor 0. - * See console_control. - */ - { - "/dev/vgacons", /* sDeviceName */ - VGA_CONSOLE, /* deviceType */ - VGA_CONSOLE_FUNCTIONS, /* pDeviceFns */ - vgacons_probe, /* deviceProbe */ - NULL, /* pDeviceFlow */ - 16, /* ulMargin */ - 8, /* ulHysteresis */ - (void *) NULL, /* NULL */ /* pDeviceParams */ - 0x00000000, /* ulCtrlPort1 */ - 0x00000000, /* ulCtrlPort2 */ - 0x00000000, /* ulDataPort */ - NULL, /* getRegister */ - NULL, /* setRegister */ - NULL,/* unused */ /* getData */ - NULL,/* unused */ /* setData */ - 0x0, /* ulClock */ - 0x0 /* ulIntVector -- base for port */ - }, -#endif -}; - -unsigned long Console_Configuration_Count = - (sizeof(Console_Configuration_Ports)/sizeof(console_tbl)); - -static console_tbl Legacy_Ports[] = { -#if BSP_ENABLE_COM1_COM4 - { - "/dev/com1", /* sDeviceName */ - SERIAL_NS16550, /* deviceType */ - COM_CONSOLE_FUNCTIONS, /* pDeviceFns */ - NULL, /* deviceProbe */ - NULL, /* pDeviceFlow */ - 16, /* ulMargin */ - 8, /* ulHysteresis */ - (void *) 9600, /* Baud Rate */ /* pDeviceParams */ - COM1_BASE_IO, /* ulCtrlPort1 */ - 0x00000000, /* ulCtrlPort2 */ - COM1_BASE_IO, /* ulDataPort */ - com_get_register, /* getRegister */ - com_set_register, /* setRegister */ - NULL,/* unused */ /* getData */ - NULL,/* unused */ /* setData */ - CLOCK_RATE, /* ulClock */ - BSP_UART_COM1_IRQ /* ulIntVector -- base for port */ - }, - { - "/dev/com2", /* sDeviceName */ - SERIAL_NS16550, /* deviceType */ - COM_CONSOLE_FUNCTIONS, /* pDeviceFns */ - NULL, /* deviceProbe */ - NULL, /* pDeviceFlow */ - 16, /* ulMargin */ - 8, /* ulHysteresis */ - (void *) 9600, /* Baud Rate */ /* pDeviceParams */ - COM2_BASE_IO, /* ulCtrlPort1 */ - 0x00000000, /* ulCtrlPort2 */ - COM2_BASE_IO, /* ulDataPort */ - com_get_register, /* getRegister */ - com_set_register, /* setRegister */ - NULL,/* unused */ /* getData */ - NULL,/* unused */ /* setData */ - CLOCK_RATE, /* ulClock */ - BSP_UART_COM2_IRQ /* ulIntVector -- base for port */ - }, - { - "/dev/com3", /* sDeviceName */ - SERIAL_NS16550, /* deviceType */ - COM_CONSOLE_FUNCTIONS, /* pDeviceFns */ - NULL, /* deviceProbe */ - NULL, /* pDeviceFlow */ - 16, /* ulMargin */ - 8, /* ulHysteresis */ - (void *) 9600, /* Baud Rate */ /* pDeviceParams */ - COM3_BASE_IO, /* ulCtrlPort1 */ - 0x00000000, /* ulCtrlPort2 */ - COM3_BASE_IO, /* ulDataPort */ - com_get_register, /* getRegister */ - com_set_register, /* setRegister */ - NULL,/* unused */ /* getData */ - NULL,/* unused */ /* setData */ - CLOCK_RATE, /* ulClock */ - BSP_UART_COM3_IRQ /* ulIntVector -- base for port */ - }, - { - "/dev/com4", /* sDeviceName */ - SERIAL_NS16550, /* deviceType */ - COM_CONSOLE_FUNCTIONS, /* pDeviceFns */ - NULL, /* deviceProbe */ - NULL, /* pDeviceFlow */ - 16, /* ulMargin */ - 8, /* ulHysteresis */ - (void *) 9600, /* Baud Rate */ /* pDeviceParams */ - COM4_BASE_IO, /* ulCtrlPort1 */ - 0x00000000, /* ulCtrlPort2 */ - COM4_BASE_IO, /* ulDataPort */ - com_get_register, /* getRegister */ - com_set_register, /* setRegister */ - NULL,/* unused */ /* getData */ - NULL,/* unused */ /* setData */ - CLOCK_RATE, /* ulClock */ - BSP_UART_COM4_IRQ /* ulIntVector -- base for port */ - }, -#endif -}; - -#define Legacy_Port_Count \ - (sizeof(Legacy_Ports)/sizeof(console_tbl)) - -void legacy_uart_probe(void) -{ -#if BSP_ENABLE_COM1_COM4 - const char *opt; - /* - * Check the command line to see if com1-com4 are disabled. - */ - opt = bsp_cmdline_arg("--disable-com1-com4"); - if ( opt ) { - printk( "COM1-COM4: disabled\n" ); - } else { - if (Legacy_Port_Count) { - printk("Legacy UART Ports: COM1-COM4\n"); - console_register_devices( Legacy_Ports, Legacy_Port_Count ); - } - } -#endif -} diff --git a/c/src/lib/libbsp/i386/pc386/console/console_control.c b/c/src/lib/libbsp/i386/pc386/console/console_control.c deleted file mode 100644 index 2d1912d3b1..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/console_control.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is an extension of the generic console driver - * shell used by all console drivers using libchip, it contains - * the console_control routine, This bsp needs its own version - * of this method to handle the keyboard and mouse as a single - * device. - */ - -/* - * COPYRIGHT (c) 1989-2011. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#if BSP_ENABLE_VGA -#include -#endif -#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h" - -/* - * console_control - * - * this routine uses the termios driver to process io - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ -#if BSP_ENABLE_VGA - if (minor == 0) { - rtems_libio_ioctl_args_t *args = arg; - - switch (args->command) { - default: - if( vt_ioctl( args->command, (unsigned long)args->buffer ) != 0 ) - return rtems_termios_ioctl (arg); - break; - - case MW_UID_REGISTER_DEVICE: - printk( "SerialMouse: reg=%s\n", (const char*) args->buffer ); - register_kbd_msg_queue( args->buffer, 0 ); - break; - - case MW_UID_UNREGISTER_DEVICE: - unregister_kbd_msg_queue( 0 ); - break; - } - - args->ioctl_return = 0; - return RTEMS_SUCCESSFUL; - } -#endif - return rtems_termios_ioctl (arg); -} diff --git a/c/src/lib/libbsp/i386/pc386/console/console_select.c b/c/src/lib/libbsp/i386/pc386/console/console_select.c deleted file mode 100644 index bde99a4c51..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/console_select.c +++ /dev/null @@ -1,250 +0,0 @@ -/** - * @file - * - * @ingroup Console - * - * @brief pc386 console select - * - * This file contains a routine to select the console based upon a number - * of criteria. - */ - -/* - * COPYRIGHT (c) 2011-2012, 2016. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h" -#ifdef RTEMS_RUNTIME_CONSOLE_SELECT - #include -#endif - -/* - * Method to return true if the device associated with the - * minor number probs available. - */ -static bool bsp_Is_Available( rtems_device_minor_number minor ) -{ - console_tbl *cptr = Console_Port_Tbl[minor]; - - /* - * First perform the configuration dependent probe, then the - * device dependent probe - */ - if ((!cptr->deviceProbe || cptr->deviceProbe(minor)) && - cptr->pDeviceFns->deviceProbe(minor)) { - return true; - } - return false; -} - -/* - * Method to return the first available device. - */ -static rtems_device_minor_number bsp_First_Available_Device( void ) -{ - rtems_device_minor_number minor; - - for (minor=0; minor < Console_Port_Count ; minor++) { - console_tbl *cptr = Console_Port_Tbl[minor]; - - /* - * First perform the configuration dependent probe, then the - * device dependent probe - */ - - if ((!cptr->deviceProbe || cptr->deviceProbe(minor)) && - cptr->pDeviceFns->deviceProbe(minor)) { - return minor; - } - } - - /* - * Error No devices were found. We will want to bail here. - */ - rtems_fatal_error_occurred(RTEMS_IO_ERROR); -} - -static bool parse_printk_or_console( - const char *param, - rtems_device_minor_number *minor_out -) -{ - static const char *opt; - const char *option; - const char *comma; - size_t length; - size_t index; - rtems_device_minor_number minor; - console_tbl *conscfg; - - /* - * Check the command line for the type of mode the console is. - */ - opt = bsp_cmdline_arg(param); - if ( !opt ) { - return false; - } - - /* - * Fine the length, there can be more command line visible. - */ - length = 0; - while ((opt[length] != ' ') && (opt[length] != '\0')) { - ++length; - if (length > NAME_MAX) { - printk("invalid option (%s): too long\n", param); - return false; - } - } - - /* - * Only match up to a comma or NULL - */ - index = 0; - while ((opt[index] != '=') && (index < length)) { - ++index; - } - - if (opt[index] != '=') { - printk("invalid option (%s): no equals\n", param); - return false; - } - - ++index; - option = &opt[index]; - - while ((opt[index] != ',') && (index < length)) { - ++index; - } - - if (opt[index] == ',') - comma = &opt[index]; - else - comma = NULL; - - length = &opt[index] - option; - - conscfg = console_find_console_entry( option, length, &minor ); - if ( conscfg == NULL ) { - return false; - } - - *minor_out = minor; - if (comma) { - option = comma + 1; - if (strncmp (option, "115200", sizeof ("115200") - 1) == 0) - conscfg->pDeviceParams = (void *)115200; - else if (strncmp (option, "57600", sizeof ("57600") - 1) == 0) - conscfg->pDeviceParams = (void *)57600; - else if (strncmp (option, "38400", sizeof ("38400") - 1) == 0) - conscfg->pDeviceParams = (void *)38400; - else if (strncmp (option, "19200", sizeof ("19200") - 1) == 0) - conscfg->pDeviceParams = (void *)19200; - else if (strncmp (option, "9600", sizeof ("9600") - 1) == 0) - conscfg->pDeviceParams = (void *)9600; - else if (strncmp (option, "4800", sizeof ("4800") - 1) == 0) - conscfg->pDeviceParams = (void *)4800; - } - - return true; -} - -/* - * Helper to retrieve device name - */ -static inline const char *get_name( - rtems_device_minor_number minor -) -{ - return Console_Port_Tbl[minor]->sDeviceName; -} - -/* - * Parse the arguments early so the printk and console ports are - * set appropriately. - */ -void pc386_parse_console_arguments(void) -{ - rtems_device_minor_number minor; - rtems_device_minor_number minor_console = 0; - rtems_device_minor_number minor_printk = 0; - - /* - * Assume that if only --console is specified, that printk() should - * follow that selection by default. - */ - if ( parse_printk_or_console( "--console=", &minor ) ) { - minor_console = minor; - minor_printk = minor; - } - - /* - * But if explicitly specified, attempt to honor it. - */ - if ( parse_printk_or_console( "--printk=", &minor ) ) { - minor_printk = minor; - } - - printk( "Console: %s printk: %s\n", - get_name(minor_console),get_name(minor_printk) ); - - /* - * Any output after this can cause problems until termios is initialised. - */ - Console_Port_Minor = minor_console; - BSPPrintkPort = minor_printk; -} - -/* - * This handles the selection of the console after the devices are - * initialized. - */ -void bsp_console_select(void) -{ - #ifdef RTEMS_RUNTIME_CONSOLE_SELECT - /* - * WARNING: This code is really needed any more and should be removed. - * references to COM1 and COM2 like they are wrong. - */ - if ( BSP_runtime_console_select ) - BSP_runtime_console_select(&BSPPrintkPort, &Console_Port_Minor); - - /* - * If no video card, fall back to serial port console - */ - if((Console_Port_Minor == BSP_CONSOLE_VGA) - && (*(unsigned char*) NB_MAX_ROW_ADDR == 0) - && (*(unsigned short*)NB_MAX_COL_ADDR == 0)) { - Console_Port_Minor = BSP_CONSOLE_COM2; - BSPPrintkPort = BSP_CONSOLE_COM1; - } - #endif - - /* - * If the device that was selected isn't available then - * let the user know and select the first available device. - */ - if ( !bsp_Is_Available( Console_Port_Minor ) ) { - printk( - "Error finding %s setting console to first available\n", - get_name(Console_Port_Minor) - ); - Console_Port_Minor = bsp_First_Available_Device(); - } -} diff --git a/c/src/lib/libbsp/i386/pc386/console/defkeymap.c b/c/src/lib/libbsp/i386/pc386/console/defkeymap.c deleted file mode 100644 index a6bf5103a1..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/defkeymap.c +++ /dev/null @@ -1,262 +0,0 @@ -/* Do not edit this file! It was automatically generated by */ -/* loadkeys --mktable defkeymap.map > defkeymap.c */ - -#include -#include -#include - -u_short plain_map[NR_KEYS] = { - 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, - 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, - 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, - 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73, - 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b, - 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, - 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c, - 0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, - 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, - 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, - 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a, - 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, - 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, - 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -u_short shift_map[NR_KEYS] = { - 0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, - 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, - 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, - 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53, - 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a, - 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, - 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, - 0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e, - 0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307, - 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, - 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a, - 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, - 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116, - 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -u_short altgr_map[NR_KEYS] = { - 0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200, - 0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200, - 0xfb71, 0xfb77, 0xf918, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, - 0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201, 0xf702, 0xf914, 0xfb73, - 0xf917, 0xf919, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf200, - 0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xf916, 0xfb76, - 0xf915, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c, - 0xf703, 0xf200, 0xf207, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, - 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911, - 0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b, - 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516, - 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, - 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, - 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -u_short ctrl_map[NR_KEYS] = { - 0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e, - 0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf200, - 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, - 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf702, 0xf001, 0xf013, - 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, - 0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, - 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, - 0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, - 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf204, 0xf307, - 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, - 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf10a, - 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, - 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, - 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -u_short shift_ctrl_map[NR_KEYS] = { - 0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200, - 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, - 0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013, - 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, - 0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016, - 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c, - 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307, - 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, - 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, - 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, - 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -u_short alt_map[NR_KEYS] = { - 0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, - 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, - 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, - 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, - 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, - 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, - 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c, - 0xf703, 0xf820, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, - 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf907, - 0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901, - 0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a, - 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, - 0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, - 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -u_short ctrl_alt_map[NR_KEYS] = { - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, - 0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813, - 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, - 0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816, - 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c, - 0xf703, 0xf200, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, - 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf200, 0xf307, - 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, - 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a, - 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, - 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, - 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -ushort *key_maps[MAX_NR_KEYMAPS] = { - plain_map, shift_map, altgr_map, 0, - ctrl_map, shift_ctrl_map, 0, 0, - alt_map, 0, 0, 0, - ctrl_alt_map, 0 -}; - -unsigned int keymap_count = 7; - -/* - * Philosophy: most people do not define more strings, but they who do - * often want quite a lot of string space. So, we statically allocate - * the default and allocate dynamically in chunks of 512 bytes. - */ - -char func_buf[] = { - '\033', '[', '[', 'A', 0, - '\033', '[', '[', 'B', 0, - '\033', '[', '[', 'C', 0, - '\033', '[', '[', 'D', 0, - '\033', '[', '[', 'E', 0, - '\033', '[', '1', '7', '~', 0, - '\033', '[', '1', '8', '~', 0, - '\033', '[', '1', '9', '~', 0, - '\033', '[', '2', '0', '~', 0, - '\033', '[', '2', '1', '~', 0, - '\033', '[', '2', '3', '~', 0, - '\033', '[', '2', '4', '~', 0, - '\033', '[', '2', '5', '~', 0, - '\033', '[', '2', '6', '~', 0, - '\033', '[', '2', '8', '~', 0, - '\033', '[', '2', '9', '~', 0, - '\033', '[', '3', '1', '~', 0, - '\033', '[', '3', '2', '~', 0, - '\033', '[', '3', '3', '~', 0, - '\033', '[', '3', '4', '~', 0, - '\033', '[', '1', '~', 0, - '\033', '[', '2', '~', 0, - '\033', '[', '3', '~', 0, - '\033', '[', '4', '~', 0, - '\033', '[', '5', '~', 0, - '\033', '[', '6', '~', 0, - '\033', '[', 'M', 0, - '\033', '[', 'P', 0, -}; - -char *funcbufptr = func_buf; -int funcbufsize = sizeof(func_buf); -int funcbufleft = 0; /* space left */ - -char *func_table[MAX_NR_FUNC] = { - func_buf + 0, - func_buf + 5, - func_buf + 10, - func_buf + 15, - func_buf + 20, - func_buf + 25, - func_buf + 31, - func_buf + 37, - func_buf + 43, - func_buf + 49, - func_buf + 55, - func_buf + 61, - func_buf + 67, - func_buf + 73, - func_buf + 79, - func_buf + 85, - func_buf + 91, - func_buf + 97, - func_buf + 103, - func_buf + 109, - func_buf + 115, - func_buf + 120, - func_buf + 125, - func_buf + 130, - func_buf + 135, - func_buf + 140, - func_buf + 145, - 0, - 0, - func_buf + 149, - 0, -}; - -struct kbdiacr accent_table[MAX_DIACR] = { - {'`', 'A', '\300'}, {'`', 'a', '\340'}, - {'\'', 'A', '\301'}, {'\'', 'a', '\341'}, - {'^', 'A', '\302'}, {'^', 'a', '\342'}, - {'~', 'A', '\303'}, {'~', 'a', '\343'}, - {'"', 'A', '\304'}, {'"', 'a', '\344'}, - {'O', 'A', '\305'}, {'o', 'a', '\345'}, - {'0', 'A', '\305'}, {'0', 'a', '\345'}, - {'A', 'A', '\305'}, {'a', 'a', '\345'}, - {'A', 'E', '\306'}, {'a', 'e', '\346'}, - {',', 'C', '\307'}, {',', 'c', '\347'}, - {'`', 'E', '\310'}, {'`', 'e', '\350'}, - {'\'', 'E', '\311'}, {'\'', 'e', '\351'}, - {'^', 'E', '\312'}, {'^', 'e', '\352'}, - {'"', 'E', '\313'}, {'"', 'e', '\353'}, - {'`', 'I', '\314'}, {'`', 'i', '\354'}, - {'\'', 'I', '\315'}, {'\'', 'i', '\355'}, - {'^', 'I', '\316'}, {'^', 'i', '\356'}, - {'"', 'I', '\317'}, {'"', 'i', '\357'}, - {'-', 'D', '\320'}, {'-', 'd', '\360'}, - {'~', 'N', '\321'}, {'~', 'n', '\361'}, - {'`', 'O', '\322'}, {'`', 'o', '\362'}, - {'\'', 'O', '\323'}, {'\'', 'o', '\363'}, - {'^', 'O', '\324'}, {'^', 'o', '\364'}, - {'~', 'O', '\325'}, {'~', 'o', '\365'}, - {'"', 'O', '\326'}, {'"', 'o', '\366'}, - {'/', 'O', '\330'}, {'/', 'o', '\370'}, - {'`', 'U', '\331'}, {'`', 'u', '\371'}, - {'\'', 'U', '\332'}, {'\'', 'u', '\372'}, - {'^', 'U', '\333'}, {'^', 'u', '\373'}, - {'"', 'U', '\334'}, {'"', 'u', '\374'}, - {'\'', 'Y', '\335'}, {'\'', 'y', '\375'}, - {'T', 'H', '\336'}, {'t', 'h', '\376'}, - {'s', 's', '\337'}, {'"', 'y', '\377'}, - {'s', 'z', '\337'}, {'i', 'j', '\377'}, -}; - -unsigned int accent_table_size = 68; diff --git a/c/src/lib/libbsp/i386/pc386/console/exar17d15x.c b/c/src/lib/libbsp/i386/pc386/console/exar17d15x.c deleted file mode 100644 index d9929c36b4..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/exar17d15x.c +++ /dev/null @@ -1,224 +0,0 @@ -/** - * @file - * - * @brief Driver for Exar XR17D15x Multiport UARTs - * - * This driver supports 2, 4 or 8 port Exar parts which are NS16550 - * compatible. - */ - -/* - * COPYRIGHT (c) 1989-2012. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h" - -#define MAX_BOARDS 4 - -/* - * This is the rate for the clock internal to the parts. - */ -#define EXAR_CLOCK_RATE (921600*16) - -/* - * Supported PCI Ids - */ -#define PCI_VENDOR_ID_EXAR 0x13A8 -#define PCI_VENDOR_ID_EXAR_XR17D158 0x0158 -#define PCI_VENDOR_ID_EXAR_XR17D154 0x0154 -#define PCI_VENDOR_ID_EXAR_XR17D152 0x0152 - -/* - * Structure to manage each instance found. - */ -typedef struct { - uint16_t vendor; - uint16_t device; - uint8_t ports; -} exar_parts_t; - -static exar_parts_t Supported[] = { - { PCI_VENDOR_ID_EXAR, PCI_VENDOR_ID_EXAR_XR17D158, 8 }, - { PCI_VENDOR_ID_EXAR, PCI_VENDOR_ID_EXAR_XR17D154, 4 }, - { PCI_VENDOR_ID_EXAR, PCI_VENDOR_ID_EXAR_XR17D152, 2 }, - { 0, 0, 0 } -}; - -/* - * Information saved from PCI scan - */ -typedef struct { - bool found; - uint32_t base; - uint8_t irq; - uint8_t bus; - uint8_t slot; - uint8_t ports; -} exar17d15x_conf_t; - -/* - * Register Access Routines - */ -static uint8_t xr17d15x_get_register(uint32_t addr, uint8_t i) -{ - uint8_t val = 0; - volatile uint8_t *reg = (volatile uint8_t *)(addr + i); - - val = *reg; - // printk( "RD %p -> 0x%02x\n", reg, val ); - return val; -} - -static void xr17d15x_set_register(uint32_t addr, uint8_t i, uint8_t val) -{ - volatile uint8_t *reg = (volatile uint8_t *)(addr + i); - - // printk( "WR %p <- 0x%02x\n", reg, val ); - *reg = val; -} - -rtems_device_driver exar17d15x_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor_arg, - void *arg -) -{ - // int pbus, pdev, pfun; - exar17d15x_conf_t conf[MAX_BOARDS]; - int boards = 0; - int b = 0; - int p; - console_tbl *ports; - console_tbl *port_p; - int pbus; - int pdev; - int pfun; - int status; - int instance; - int i; - int total_ports = 0; - - for ( b=0 ; bsDeviceName = strdup( name ); - port_p->deviceType = SERIAL_NS16550; - #if 1 - port_p->pDeviceFns = &ns16550_fns_polled; - #else - port_p->pDeviceFns = &ns16550_fns; - #endif - - port_p->deviceProbe = NULL; - port_p->pDeviceFlow = NULL; - port_p->ulMargin = 16; - port_p->ulHysteresis = 8; - port_p->pDeviceParams = (void *) 9600; - port_p->ulCtrlPort1 = conf[b].base + (p * 0x0200); - port_p->ulCtrlPort2 = 0; /* NA */ - port_p->ulDataPort = 0; /* NA */ - port_p->getRegister = xr17d15x_get_register; - port_p->setRegister = xr17d15x_set_register; - port_p->getData = NULL; /* NA */ - port_p->setData = NULL; /* NA */ - port_p->ulClock = EXAR_CLOCK_RATE; - port_p->ulIntVector = conf[b].irq; - - port_p++; - } /* end ports */ - } /* end boards */ - - /* - * Register the devices - */ - if ( boards ) - console_register_devices( ports, total_ports ); - - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/lib/libbsp/i386/pc386/console/fb_cirrus.c b/c/src/lib/libbsp/i386/pc386/console/fb_cirrus.c deleted file mode 100644 index bb05b5a338..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/fb_cirrus.c +++ /dev/null @@ -1,766 +0,0 @@ -/* - * FB driver for Cirrus GD5446 graphic hardware. - * Tested to be compatible with QEMU GD5446 emulation but not on real HW. - * - * Copyright (c) 2012 - Alexandru-Sever Horin (alex.sever.h@gmail.com). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - * The code is based on next information sources: - * - CL-GD5446 Technical Reference Manual, 1996, Second Edition - * - RTEMS fb_vga.c - Rosimildo da Silva ( rdasilva@connecttel.com ) - * - Cirrus xf86 driver - used as VGA hardware setup sequence documentation - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -/* flag to limit driver to protect against multiple opens */ -static Atomic_Flag driver_mutex; - -/* screen information for the VGA driver - * standard structures - */ -static struct fb_var_screeninfo fb_var; -static struct fb_fix_screeninfo fb_fix; - -#define CIRRUS_VENDOR_ID 0x1013 -#define CIRRUS_GD5446_DEVICE_ID 0x00b8 - -typedef struct _DisplayModeRec { - struct _DisplayModeRec *prev; - struct _DisplayModeRec *next; - char *name; /* identifier for the mode */ - int type; - - /* These are the values that the user sees/provides */ - int Clock; /* pixel clock freq (kHz) */ - int HDisplay; /* horizontal timing */ - int HSyncStart; - int HSyncEnd; - int HTotal; - int HSkew; - int VDisplay; /* vertical timing */ - int VSyncStart; - int VSyncEnd; - int VTotal; - int VScan; - int Flags; - - /* These are the values the hardware uses */ - int ClockIndex; - int SynthClock; /* Actual clock freq to - * be programmed (kHz) */ - int CrtcHDisplay; - int CrtcHBlankStart; - int CrtcHSyncStart; - int CrtcHSyncEnd; - int CrtcHBlankEnd; - int CrtcHTotal; - int CrtcHSkew; - int CrtcVDisplay; - int CrtcVBlankStart; - int CrtcVSyncStart; - int CrtcVSyncEnd; - int CrtcVBlankEnd; - int CrtcVTotal; - int CrtcHAdjusted; - int CrtcVAdjusted; - int PrivSize; - int32_t *Private; - int PrivFlags; - - float HSync, VRefresh; -} DisplayModeRec, *DisplayModePtr; - -static DisplayModeRec available_modes[] = { - { - .Clock = 31500 , - .HDisplay = 640 , - .HSyncStart = 664 , - .HSyncEnd = 704 , - .HTotal = 832 , - .HSkew = 0 , - .VDisplay = 480 , /* vertical timing */ - .VSyncStart = 489 , - .VSyncEnd = 491 , - .VTotal = 520 , - .VScan = 0, - .Flags = 0 - }, - { - .Clock = 40000 , - .HDisplay = 800 , - .HSyncStart = 840 , - .HSyncEnd = 968 , - .HTotal = 1056 , - .HSkew = 0 , - .VDisplay = 600 , /* vertical timing */ - .VSyncStart = 601 , - .VSyncEnd = 605 , - .VTotal = 628 , - .VScan = 0, - .Flags = 0 - }, -}; -static DisplayModePtr active_mode; - -/* The display mode used for the board hardcoded in the following define - * Index in above structure - */ -#define CIRRUS_DISPLAY_MODE 0 - -/* The display bytes per pixel used for the board hardcoded in the following define - * Index in above structure - */ -#define CIRRUS_DEFAULT_BPP 24 - -/* cirrus board information */ -struct cirrus_board_str{ - int pci_bus; - int pci_device; - int pci_function; - void *reg_base; -}; - -static struct cirrus_board_str cirrus_board_info; - -/* - * get information from the board - */ -static int -cirrus_pci_read( struct cirrus_board_str *cirrus_board, uint32_t *mem_base, uint32_t *cirrus_register_base) -{ - int r; - - r = pci_read_config_dword( - cirrus_board->pci_bus, cirrus_board->pci_device, cirrus_board->pci_function, - PCI_BASE_ADDRESS_0, mem_base); - if( r != PCIB_ERR_SUCCESS) - return RTEMS_UNSATISFIED; - - r = pci_read_config_dword( - cirrus_board->pci_bus, cirrus_board->pci_device, cirrus_board->pci_function, - PCI_BASE_ADDRESS_1, cirrus_register_base); - if( r != PCIB_ERR_SUCCESS) - return RTEMS_UNSATISFIED; - - *mem_base &= PCI_BASE_ADDRESS_MEM_MASK; - *cirrus_register_base &= PCI_BASE_ADDRESS_MEM_MASK; - - return RTEMS_SUCCESSFUL; -} - -static inline int -fb_cirrus_read_config_dword( - struct cirrus_board_str *fbst, - unsigned char where, - uint32_t *pval) -{ - return pci_read_config_dword( - fbst->pci_bus, fbst->pci_device, fbst->pci_function, - where, pval); -} - -static inline int -fb_cirrus_write_config_dword( - struct cirrus_board_str *fbst, - unsigned char where, - uint32_t val) -{ - return pci_write_config_dword( - fbst->pci_bus, fbst->pci_device, fbst->pci_function, - where, val); -} - -static inline void -fb_cirrus_write_reg8 ( - const struct cirrus_board_str *fbst, - unsigned int reg, - unsigned int val) -{ - *(volatile uint8_t*)((char *)fbst->reg_base + reg) = val; -} - -static inline unsigned int -fb_cirrus_read_reg8 ( - const struct cirrus_board_str *fbst, - unsigned int reg) -{ - return *(volatile uint8_t*)((char *)fbst->reg_base + reg); -} - -#define SEQ_INDEX 0x04 -#define SEQ_DATA 0x05 - -static inline void -fb_cirrus_write_seq_reg ( - const struct cirrus_board_str *fbst, - unsigned int reg, - unsigned int val) -{ - fb_cirrus_write_reg8(fbst, SEQ_INDEX, reg); - fb_cirrus_write_reg8(fbst, SEQ_DATA, val); -} - -static inline unsigned int -fb_cirrus_read_seq_reg ( - const struct cirrus_board_str *fbst, - unsigned int reg) -{ - fb_cirrus_write_reg8(fbst, SEQ_INDEX, reg); - return fb_cirrus_read_reg8(fbst, SEQ_DATA); -} - -#define CRT_INDEX 0x14 -#define CRT_DATA 0x15 - -static inline void -fb_cirrus_write_crt_reg ( - const struct cirrus_board_str *fbst, - unsigned int reg, - unsigned int val) -{ - fb_cirrus_write_reg8(fbst, CRT_INDEX, reg); - fb_cirrus_write_reg8(fbst, CRT_DATA, val); -} - -static inline unsigned int -fb_cirrus_read_crt_reg ( - const struct cirrus_board_str *fbst, - unsigned int reg) -{ - fb_cirrus_write_reg8(fbst, CRT_INDEX, reg); - return fb_cirrus_read_reg8(fbst, CRT_DATA); -} - -#define GDC_INDEX 0x0E -#define GDC_DATA 0x0F - -static inline void -fb_cirrus_write_gdc_reg ( - const struct cirrus_board_str *fbst, - unsigned int reg, - unsigned int val) -{ - fb_cirrus_write_reg8(fbst, GDC_INDEX, reg); - fb_cirrus_write_reg8(fbst, GDC_DATA, val); -} - -static inline unsigned int -fb_cirrus_read_gdc_reg ( - const struct cirrus_board_str *fbst, - unsigned int reg) -{ - fb_cirrus_write_reg8(fbst, GDC_INDEX, reg); - return fb_cirrus_read_reg8(fbst, GDC_DATA); -} - -#define VGA_DAC_MASK 0x06 - -static inline void -fb_cirrus_write_hdr_reg ( - const struct cirrus_board_str *fbst, - unsigned int val) -{ - volatile unsigned int dummy RTEMS_UNUSED; - dummy = fb_cirrus_read_reg8(fbst, VGA_DAC_MASK); - dummy = fb_cirrus_read_reg8(fbst, VGA_DAC_MASK); - dummy = fb_cirrus_read_reg8(fbst, VGA_DAC_MASK); - dummy = fb_cirrus_read_reg8(fbst, VGA_DAC_MASK); - fb_cirrus_write_reg8(fbst, VGA_DAC_MASK, val); -} - -/* Functionality to support multiple VGA frame buffers can be added easily, - * but is not supported at this moment because there is no need for two or - * more "classic" VGA adapters. Multiple frame buffer drivers may be - * implemented and If we had implement it they would be named as "/dev/fb0", - * "/dev/fb1", "/dev/fb2" and so on. - */ - -/* - * fb_cirrus device driver INITIALIZE entry point. - */ -rtems_device_driver -frame_buffer_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - int res; - - printk( "FB_CIRRUS -- driver initializing..\n" ); - - res = pci_find_device( - CIRRUS_VENDOR_ID, - CIRRUS_GD5446_DEVICE_ID, - minor, - &cirrus_board_info.pci_bus, - &cirrus_board_info.pci_device, - &cirrus_board_info.pci_function - ); - - if ( res != PCIB_ERR_SUCCESS ) { - printk( "FB_CIRRUS initialize -- device not found\n" ); - - return RTEMS_UNSATISFIED; - } - else{ - printk( "FB_CIRRUS -- driver initializing..\n" ); - /* - * Register the device - */ - status = rtems_io_register_name (FRAMEBUFFER_DEVICE_0_NAME, major, 0); - if (status != RTEMS_SUCCESSFUL) { - printk("Error registering " FRAMEBUFFER_DEVICE_0_NAME - " FB_CIRRUS framebuffer device!\n"); - rtems_fatal_error_occurred( status ); - } - - _Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE); - - return RTEMS_SUCCESSFUL; - } -} - -/* - * This function is used to initialize the Start Address - the first - * displayed location in the video memory. - * Usually mandatory - */ -static void -cirrus_adjust_frame( struct cirrus_board_str *board, int x, int y) -{ - uint32_t Base; - uint8_t tmp; - - Base = ((y * fb_var.xres + x) >> 3); - if (fb_var.bits_per_pixel != 1) - Base *= (fb_var.bits_per_pixel >> 2); - - printk("FB_CIRRUS: cirrus_adjust_frame %d %d >>> %d %x\n", x, y, Base, Base); - - if ((Base & ~0x000FFFFF) != 0) { - printk("FB_CIRRUS: Internal error: cirrus_adjust_frame: cannot handle overflow\n"); - return; - } - - fb_cirrus_write_crt_reg( board, 0x0C, (Base >> 8) & 0xff); - fb_cirrus_write_crt_reg( board, 0x0D, Base & 0xff); - - tmp = fb_cirrus_read_crt_reg( board, 0x1B); - tmp &= 0xF2; - tmp |= (Base >> 16) & 0x01; - tmp |= (Base >> 15) & 0x0C; - fb_cirrus_write_crt_reg( board, 0x1B, tmp); - - tmp = fb_cirrus_read_crt_reg( board, 0x1D); - tmp &= 0x7F; - tmp |= (Base >> 12) & 0x80; - fb_cirrus_write_crt_reg( board, 0x1D, tmp); -} - -static int -cirrus_set_mode(DisplayModePtr mode) -{ - int depthcode = fb_var.bits_per_pixel;; - int width; - int HDiv2 = 0, VDiv2 = 0; - const struct cirrus_board_str *cirrus_board_ptr = &cirrus_board_info; - int temp; - int hdr = -1; - - printk("FB_CIRRUS: mode %d bpp, %d Hz %d %d %d %d %d %d %d %d\n", - fb_var.bits_per_pixel, - mode->Clock, - mode->HDisplay, - mode->HSyncStart, - mode->HSyncEnd, - mode->HTotal, - mode->VDisplay, - mode->VSyncStart, - mode->VSyncEnd, - mode->VTotal); - - if ( mode->Clock > 85500 ) { - /* The actual DAC register value is set later. */ - /* The CRTC is clocked at VCLK / 2, so we must half the */ - /* horizontal timings. */ - if (!mode->CrtcHAdjusted) { - mode->HDisplay >>= 1; - mode->HSyncStart >>= 1; - mode->HTotal >>= 1; - mode->HSyncEnd >>= 1; - mode->SynthClock >>= 1; - mode->CrtcHAdjusted = TRUE; - } - depthcode += 64; - HDiv2 = 1; - } - if (mode->VTotal >= 1024 ) { - /* For non-interlaced vertical timing >= 1024, the vertical timings */ - /* are divided by 2 and VGA CRTC 0x17 bit 2 is set. */ - if (!mode->CrtcVAdjusted) { - mode->VDisplay >>= 1; - mode->VSyncStart >>= 1; - mode->VSyncEnd >>= 1; - mode->VTotal >>= 1; - mode->CrtcVAdjusted = TRUE; - } - VDiv2 = 1; - } - - /**************************************************** - * Sequential registers - */ - fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x00, 0x00); - fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x01, 0x01); - fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x02, 0x0F); - fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x03, 0x00); - fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x04, 0x0E); - - /**************************************************** - * CRTC Controller Registers - */ - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x00, (mode->HTotal >> 3) - 5 ); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x01, (mode->HDisplay >> 3) - 1); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x02, (mode->HSyncStart >> 3) - 1); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x03, ((mode->HSyncEnd >> 3) & 0x1F) | 0x80); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x04, (mode->HSyncStart >> 3)); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x05, - (((mode->HSyncEnd >> 3) & 0x20 ) << 2 ) - | (((mode->HSyncEnd >> 3)) & 0x1F)); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x06, (mode->VTotal - 2) & 0xFF); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x07, - (((mode->VTotal -2) & 0x100) >> 8 ) - | (((mode->VDisplay -1) & 0x100) >> 7 ) - | ((mode->VSyncStart & 0x100) >> 6 ) - | (((mode->VSyncStart) & 0x100) >> 5 ) - | 0x10 - | (((mode->VTotal -2) & 0x200) >> 4 ) - | (((mode->VDisplay -1) & 0x200) >> 3 ) - | ((mode->VSyncStart & 0x200) >> 2 )); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x08, 0x00); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x09, ((mode->VSyncStart & 0x200) >>4) | 0x40); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0A, 0x00); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0B, 0x00); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0C, 0x00); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0D, 0x00); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0E, 0x00); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0F, 0x00); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x10, mode->VSyncStart & 0xFF); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x11, (mode->VSyncEnd & 0x0F) | 0x20); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x12, (mode->VDisplay -1) & 0xFF); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x13, 0x00); /* no interlace */ - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x14, 0x00); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x15, mode->VSyncStart & 0xFF); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x16, (mode->VSyncStart +1) & 0xFF); - - temp = 0xAF; - if(VDiv2) - temp |= 0x04; - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x17, temp); - - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x18, 0xFF); - - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x1A , - (((mode->HTotal >> 3) & 0xC0 ) >> 2) - | (((mode->VTotal - 2) & 0x300 ) >> 2)); - - width = fb_fix.line_length >> 3; - if (fb_var.bits_per_pixel == 1) - width <<= 2; - if(width >= 0xFF) - printk("FB_CIRRUS: Warning line size over the limit ... reduce bpp or width resolution"); - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x13, width); - /* Offset extension (see CR13) */ - temp = fb_cirrus_read_crt_reg( cirrus_board_ptr, 0x1B); - temp &= 0xAF; - temp |= (width >> (3+4)) & 0x10; - temp |= (width >> (3+3)) & 0x40; - temp |= 0x22; - fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x1B, temp); - - /**************************************************** - * Sequential register - * Enable linear mode and high-res packed pixel mode - */ - temp = fb_cirrus_read_seq_reg( cirrus_board_ptr, 0x07); - temp &= 0xe0; - switch (depthcode) { - case 1: - case 4: - temp |= 0x10; - break; - case 8: - temp |= 0x11; - break; - case 64+8: - temp |= 0x17; - break; - case 15: - temp |= 0x17; - hdr = 0xC0; /* 5:5:5 Sierra */ - break; - case 16: - temp |= 0x17; - hdr = 0xC1; /* 5:6:5 XGA mode */ - break; - case 24: - temp |= 0x15; - hdr = 0xC5; /* 8:8:8 16M colors */ - break; - case 32: - temp |= 0x19; - hdr = 0xC5; /* 8:8:8 16M colors */ - break; - default: - printk("FB_CIRRUS: Cannot Initialize display to requested mode\n"); - printk("FB_CIRRUS: returning RTEMS_UNSATISFIED on depthcode %d\n", depthcode); - return RTEMS_UNSATISFIED; - } - fb_cirrus_write_seq_reg( cirrus_board_ptr, 0x07, temp); - /* this just set packed pixel mode with according bpp */ - - /**************************************************** - * HDR Register - */ - if(hdr > 0) - fb_cirrus_write_hdr_reg( cirrus_board_ptr, hdr); - - /**************************************************** - * Graphic Data Controller Registers - */ - temp = fb_cirrus_read_gdc_reg( cirrus_board_ptr, 0x12); - if (HDiv2) - temp |= 0x20; - else - temp &= ~0x20; - fb_cirrus_write_gdc_reg( cirrus_board_ptr, 0x12, temp); - - /* Enable high-color modes */ - fb_cirrus_write_gdc_reg(cirrus_board_ptr, 0x05, 0x40); - - /* VGA graphics mode */ - fb_cirrus_write_gdc_reg(cirrus_board_ptr, 0x06, 0x01); - - return TRUE; -} - -static void -cirrus_prepare_mode( void ) -{ - - active_mode = &available_modes[CIRRUS_DISPLAY_MODE]; - - fb_var.bits_per_pixel = CIRRUS_DEFAULT_BPP; - - fb_var.xres = active_mode->HDisplay; - fb_var.yres = active_mode->VDisplay; - - fb_fix.line_length = (fb_var.xres * fb_var.bits_per_pixel + 7) / 8; - - fb_fix.type = FB_TYPE_PACKED_PIXELS; - fb_fix.visual = FB_VISUAL_TRUECOLOR; - -} - -/* - * fb_cirrus device driver OPEN entry point - */ -rtems_device_driver -frame_buffer_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - int r; - uint32_t smem_start, regs_start; - - if (_Atomic_Flag_test_and_set(&driver_mutex, ATOMIC_ORDER_ACQUIRE) != 0 ) { - printk( "FB_CIRRUS could not lock driver_mutex\n" ); - - return RTEMS_UNSATISFIED; - } - - r = cirrus_pci_read(&cirrus_board_info, &smem_start, ®s_start); - if ( r == RTEMS_UNSATISFIED ) - return RTEMS_UNSATISFIED; - - fb_fix.smem_start = (volatile char *)smem_start; - fb_fix.smem_len = 0x1000000; - cirrus_board_info.reg_base = (void *)regs_start; - - cirrus_prepare_mode(); - - cirrus_set_mode( active_mode ); - - cirrus_adjust_frame( &cirrus_board_info, 0, 0); - - if (1) { - uint32_t pixmask; - int x, y; - - if(fb_var.bits_per_pixel == 32) - pixmask = 0xffffff; - else - pixmask = (1 << fb_var.bits_per_pixel) - 1; - - printk("FB_CIRRUS: mode set, test patter output\n"); - - for(y = 0; y < fb_var.yres; y++) { - for(x = 0; x < fb_var.xres; x++) { - uint32_t color; - char *addr = (char *)fb_fix.smem_start; - addr += y * fb_fix.line_length; - addr += x * fb_var.bits_per_pixel / 8; - color = x & 1 ? 0 : y & 1 ? pixmask & 0x000ff00f : pixmask; - if(y == fb_var.yres - 1) { - if((x > 0) && (x < fb_var.xres-1)) - color = pixmask & 0x00555555; - } - switch (fb_var.bits_per_pixel) { - case 8: *(volatile uint8_t*) addr = color; - break; - case 16: *(volatile uint16_t*) addr = color; - break; - case 24: *(volatile uint32_t*) addr = - (*(volatile uint32_t*) addr & 0xff000000) | color; - break; - case 32: *(volatile uint32_t*) addr = color; - break; - } - } - } - } - - return RTEMS_SUCCESSFUL; - -} - -/* - * fb_cirrus device driver CLOSE entry point - */ -rtems_device_driver -frame_buffer_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - _Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE); - - /* restore previous state. for VGA this means return to text mode. - * leave out if graphics hardware has been initialized in - * frame_buffer_initialize() */ - - /* VGA text mode */ - fb_cirrus_write_gdc_reg(&cirrus_board_info, 0x06, 0x00); - - printk( "FB_CIRRUS: close called.\n" ); - return RTEMS_SUCCESSFUL; -} - -/* - * fb_cirrus device driver READ entry point. - */ -rtems_device_driver -frame_buffer_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; - rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count; - memcpy(rw_args->buffer, (const void *) (fb_fix.smem_start + rw_args->offset), rw_args->bytes_moved); - return RTEMS_SUCCESSFUL; -} - -/* - * frame_buffer device driver WRITE entry point. - */ -rtems_device_driver -frame_buffer_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; - rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count; - memcpy( (void *) (fb_fix.smem_start + rw_args->offset), rw_args->buffer, rw_args->bytes_moved); - return RTEMS_SUCCESSFUL; -} - -static int -get_fix_screen_info( struct fb_fix_screeninfo *info ) -{ - *info = fb_fix; - return 0; -} - -static int -get_var_screen_info( struct fb_var_screeninfo *info ) -{ - *info = fb_var; - return 0; -} - -/* - * IOCTL entry point -- This method is called to carry - * all services of this interface. - */ -rtems_device_driver -frame_buffer_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_libio_ioctl_args_t *args = arg; - - printk( "FB_CIRRUS ioctl called, cmd=%x\n", args->command ); - - switch( args->command ) { - case FBIOGET_FSCREENINFO: - args->ioctl_return = get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer ); - break; - case FBIOGET_VSCREENINFO: - args->ioctl_return = get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer ); - break; - case FBIOPUT_VSCREENINFO: - /* not implemented yet */ - args->ioctl_return = -1; - return RTEMS_UNSATISFIED; - case FBIOGETCMAP: - /* no palette - truecolor mode */ - args->ioctl_return = -1; - return RTEMS_UNSATISFIED; - case FBIOPUTCMAP: - /* no palette - truecolor mode */ - args->ioctl_return = -1; - return RTEMS_UNSATISFIED; - default: - args->ioctl_return = 0; - break; - } - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/lib/libbsp/i386/pc386/console/fb_vesa_rm.c b/c/src/lib/libbsp/i386/pc386/console/fb_vesa_rm.c deleted file mode 100644 index 1c42956fce..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/fb_vesa_rm.c +++ /dev/null @@ -1,1004 +0,0 @@ -/** - * @file fb_vesa_rm.c - * - * @ingroup i386_pc386 - * - * @brief FB driver for graphic hardware compatible with VESA Bios Extension - * Real mode interface utilized - * Tested on real HW. - * - * Public sources related: - * - VESA BIOS EXTENSION (VBE) Core Function Standard, Ver: 3.0, Sep 16, 1998 - * - VESA Enhanced Extended Display Identification Data (E-EDID) Standard - * Release A, Revision 2, September 25, 2006 - * - * Hardware is completely initialized upon boot of the system. - * Therefore there is no way to change graphics mode later. - * - * Interrupt 0x10 is used for entering graphics BIOS. - * - * Driver reads parameter from multiboot command line to setup video: - * "--video=x[-]" - * "--video=auto" - try EDID to find mode that fits the display attached best - * "--video=none" / "--video=off" - do not initialize the driver - * If cmdline parameter is not specified the rtems_fb_default_mode - * variable content is tested (see doc below). - * Command line option has higher priority. rtems_fb_default_mode is probed - * only if cmdline "--video=" is not specified at all. - * - * If neither of the above options is specified the driver is not initialized. - */ - -/* - * Copyright (c) 2014 - CTU in Prague - * Jan Doležal ( dolezj21@fel.cvut.cz ) - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - * The code for rtems_buffer_* functions was greatly - * inspired or coppied from: - * - RTEMS fb_cirrus.c - Alexandru-Sever Horin (alex.sever.h@gmail.com) - */ - -#include - -#include - -#include -#include -#include - -#include - -#include - -#include -#include - -#include - -#include - -#define FB_VESA_NAME "FB_VESA_RM" - -/** - * @brief Allows to enable initialization of VESA real mode driver from - * an application by setting the value of this variable to non null value in - * user's module. The value of this variable will be then updated - * when linked with application's object. - * - * Further the value should point to string in the following format: - * "x[-]" - e.g. "1024x768-32" - * "auto" - try EDID to find mode that fits the display attached best - * "none" / "off" - do not initialize the driver - * the given parameters are used if applicable. - * - * Command line argument "--video=" has priority over this string. - */ -const char * const rtems_fb_default_mode; - -/** - * @brief Initializes VBE framebuffer during bootup. - * - * utilizes switches to real mode interrupts and therefore must be - * called during bootup before tick is set up and real-time - * interrupt vectors utilized - */ -void vesa_realmode_bootup_init(void); - -/* flag to limit driver to protect against multiple opens */ -static Atomic_Flag driver_mutex; - -/* screen information for the VGA driver - * standard structures - from RTEMS fb interface - */ -static struct fb_var_screeninfo fb_var; -static struct fb_fix_screeninfo fb_fix; - -static int32_t vbe_used_mode; - -uint32_t VBE_controller_information( VBE_vbe_info_block *info_block, - uint16_t queried_VBE_Version) -{ - uint16_t size; - VBE_vbe_info_block *VBE_buffer = - (VBE_vbe_info_block *)i386_get_default_rm_buffer(&size); - i386_realmode_interrupt_registers parret; - parret.reg_eax = VBE_RetVBEConInf; - uint16_t seg, off; - i386_Physical_to_real(VBE_buffer, &seg, &off); - parret.reg_edi = (uint32_t)off; - parret.reg_es = seg; - /* indicate to graphic's bios that VBE2.0 extended information is desired */ - if (queried_VBE_Version >= 0x200) - { - memcpy( - &VBE_buffer->VbeSignature, - VBE20plus_SIGNATURE, - sizeof(VBE_buffer->VbeSignature) - ); - } - if (i386_real_interrupt_call(INTERRUPT_NO_VIDEO_SERVICES, &parret) == 0) - return -1; - if ((parret.reg_eax & 0xFFFF) == - (VBE_callSuccessful<<8 | VBE_functionSupported)) - { - *info_block = *VBE_buffer; - } - return (parret.reg_eax & 0xFFFF); -} - -uint32_t VBE_mode_information( VBE_mode_info_block *info_block, - uint16_t mode_number) -{ - uint16_t size; - VBE_mode_info_block *VBE_buffer = - (VBE_mode_info_block *)i386_get_default_rm_buffer(&size); - i386_realmode_interrupt_registers parret; - parret.reg_eax = VBE_RetVBEModInf; - parret.reg_ecx = mode_number; - uint16_t seg, off; - i386_Physical_to_real(VBE_buffer, &seg, &off); - parret.reg_edi = (uint32_t)off; - parret.reg_es = seg; - if (i386_real_interrupt_call(INTERRUPT_NO_VIDEO_SERVICES, &parret) == 0) - return -1; - if ((parret.reg_eax & 0xFFFF) == - (VBE_callSuccessful<<8 | VBE_functionSupported)) - { - *info_block = *VBE_buffer; - } - return (parret.reg_eax & 0xFFFF); -} - -uint32_t VBE_set_mode( uint16_t mode_number, - VBE_CRTC_info_block *info_block) -{ - uint16_t size; - VBE_CRTC_info_block *VBE_buffer = - (VBE_CRTC_info_block *)i386_get_default_rm_buffer(&size); - i386_realmode_interrupt_registers parret; - /* copy CRTC */ - *VBE_buffer = *info_block; - parret.reg_eax = VBE_SetVBEMod; - parret.reg_ebx = mode_number; - uint16_t seg, off; - i386_Physical_to_real(VBE_buffer, &seg, &off); - parret.reg_edi = (uint32_t)off; - parret.reg_es = seg; - if (i386_real_interrupt_call(INTERRUPT_NO_VIDEO_SERVICES, &parret) == 0) - return -1; - return (parret.reg_eax & 0xFFFF); -} - -uint32_t VBE_current_mode(uint16_t *mode_number) -{ - i386_realmode_interrupt_registers parret; - parret.reg_eax = VBE_RetCurVBEMod; - if (i386_real_interrupt_call(INTERRUPT_NO_VIDEO_SERVICES, &parret) == 0) - return -1; - *mode_number = (uint16_t)parret.reg_ebx; - return (parret.reg_eax & 0xFFFF); -} - -uint32_t VBE_report_DDC_capabilities(uint16_t controller_unit_number, - uint8_t *seconds_to_transfer_EDID_block, - uint8_t *DDC_level_supported) -{ - i386_realmode_interrupt_registers parret; - parret.reg_eax = VBE_DisDatCha; - parret.reg_ebx = VBEDDC_Capabilities; - parret.reg_ecx = controller_unit_number; - parret.reg_edi = 0; - parret.reg_es = 0; - if (i386_real_interrupt_call(INTERRUPT_NO_VIDEO_SERVICES, &parret) == 0) - return -1; - *seconds_to_transfer_EDID_block = (uint8_t)parret.reg_ebx >> 8; - *DDC_level_supported = (uint8_t)parret.reg_ebx; - return (parret.reg_eax & 0xFFFF); -} - -uint32_t VBE_read_EDID(uint16_t controller_unit_number, - uint16_t EDID_block_number, - EDID_edid1 *buffer) -{ - uint16_t size; - EDID_edid1 *VBE_buffer = (EDID_edid1*)i386_get_default_rm_buffer(&size); - i386_realmode_interrupt_registers parret; - parret.reg_eax = VBE_DisDatCha; - parret.reg_ebx = VBEDDC_ReadEDID; - parret.reg_ecx = controller_unit_number; - parret.reg_edx = EDID_block_number; - uint16_t seg, off; - i386_Physical_to_real(VBE_buffer, &seg, &off); - parret.reg_edi = (uint32_t)off; - parret.reg_es = seg; - if (i386_real_interrupt_call(INTERRUPT_NO_VIDEO_SERVICES, &parret) == 0) - return -1; - if ((parret.reg_eax & 0xFFFF) == - (VBE_callSuccessful<<8 | VBE_functionSupported)) - { - *buffer = *VBE_buffer; - } - return (parret.reg_eax & 0xFFFF); -} - -/** - * @brief Basic graphic's mode parameters - */ -typedef struct { - /** number of the graphic's mode */ - uint16_t mode_number; - /** number of pixels in one line */ - uint16_t resX; - /** number of lines */ - uint16_t resY; - /** bits per pixel */ - uint8_t bpp; -} Mode_params; - -typedef enum { - NO_SUITABLE_MODE = -1, - BAD_FORMAT = -2, - AUTO_SELECT = -3, - DONT_INIT = -4, - NO_MODE_REQ = -5, -} mode_err_ret_val; - -/** - * @brief Find mode by resolution in the given list of modes - * - * finds mode in \p mode_list of \p list_length length according to resolution - * given in \p searched_resolution . If bpp is given in that struct as well - * mode with such color depth and resolution is searched for. Otherwise bpp - * has to be zero. Mode number found is returned and also filled into - * \p searched_resolution . bpp is also filled into \p searchedResolution if it - * was 0 before call. - * - * @param[in] mode_list list of modes to be searched - * @param[in] list_length number of modes in the list - * @param[in,out] searched_resolution element filled with searched resolution - * or/and bpp; mode_number is filled in if appropriate mode found - * @retval mode number satisfying given parameters - * @retval -1 no suitable mode found - */ -static int32_t find_mode_by_resolution(Mode_params *mode_list, - uint8_t list_length, - Mode_params *searched_resolution) -{ - uint8_t i = 0; - while (i < list_length) - { - if (searched_resolution->resX == mode_list[i].resX && - searched_resolution->resY == mode_list[i].resY) - { - if (searched_resolution->bpp==0 || - searched_resolution->bpp==mode_list[i].bpp) - { - searched_resolution->bpp = mode_list[i].bpp; - searched_resolution->mode_number = mode_list[i].mode_number; - return mode_list[i].mode_number; - } - } - i++; - } - return NO_SUITABLE_MODE; -} - -/** - * @brief Find mode given in string format. - * - * expected format - * x[-] - * numbers , and are decadic - * - * @param[in] mode_list list of modes to be searched - * @param[in] list_length number of modes in the list - * @param[in] video_string string to be parsed - * @retval video mode number to be set - * @retval -1 no suitable mode found - * @retval -2 bad format of the video_string - * @retval -3 automatic mode selection requested - * @retval -4 request to not initialize graphics - * @retval -5 no mode requested/empty video string - */ -static int32_t find_mode_from_string(Mode_params *mode_list, - uint8_t list_length, - const char *video_string) -{ - const char* opt; - Mode_params cmdline_mode; - char* endptr; - cmdline_mode.bpp = 16; /* default bpp */ - opt = video_string; - if (opt) - { - if (strncmp(opt, "auto", 4) == 0) - return AUTO_SELECT; - if (strncmp(opt, "none", 4) == 0 || - strncmp(opt, "off", 3) == 0) - { - return DONT_INIT; - } - cmdline_mode.resX = strtol(opt, &endptr, 10); - if (*endptr != 'x') - { - return BAD_FORMAT; - } - opt = endptr+1; - cmdline_mode.resY = strtol(opt, &endptr, 10); - switch (*endptr) - { - case '-': - opt = endptr+1; - if (strlen(opt) <= 2) - cmdline_mode.bpp = strtol(opt, &endptr, 10); - else - { - cmdline_mode.bpp = strtol(opt, &endptr, 10); - if (*endptr != ' ') - { - return BAD_FORMAT; - } - } - case ' ': - case 0: - break; - default: - return BAD_FORMAT; - } - - return find_mode_by_resolution(mode_list, list_length, &cmdline_mode); - } - return NO_MODE_REQ; -} - -/** - * @brief Find mode given within command line. - * - * Parse command line option "--video=" if available. - * expected format - * --video=x[-] - * numbers , and are decadic - * - * @param[in] mode_list list of modes to be searched - * @param[in] list_length number of modes in the list - * @retval video mode number to be set - * @retval -1 no suitable mode found - * @retval -2 bad format of the video_string - * @retval -3 automatic mode selection requested - * @retval -4 request to not initialize graphics - * @retval -5 no mode requested/empty video string - */ -static int32_t find_mode_using_cmdline(Mode_params *mode_list, - uint8_t list_length) -{ - const char* opt; - opt = bsp_cmdline_arg("--video="); - if (opt) - { - opt += sizeof("--video=")-1; - return find_mode_from_string(mode_list, list_length, opt); - } - return NO_MODE_REQ; -} - -/** - * @brief Find mode number best fitting to monitor attached - * - * @param[in] mode_list list of modes to be searched - * @param[in] list_length number of modes in the list - * @retval video mode number to be set - * @retval -1 on parsing error or when no suitable mode found - */ -static int32_t find_mode_using_EDID( Mode_params *mode_list, - uint8_t list_length) -{ - EDID_edid1 edid; - uint8_t checksum, iterator; - uint8_t index, j; - Mode_params EDIDmode; - checksum = 0; - iterator = 0; - EDIDmode.bpp = 0; - if (VBE_read_EDID(0, 0, &edid) != - (VBE_callSuccessful<<8 | VBE_functionSupported)) - { - printk(FB_VESA_NAME " Function 15h (read EDID) not supported.\n"); - return -1; - } -/* version of EDID structure */ - if (edid.Version == 1) - { /* EDID version 1 */ - while (iterator < sizeof(EDID_edid1)) - { - checksum += *((uint8_t *)&edid+iterator); - iterator++; - } - if (checksum) - /* not implemented: try to read EDID again */ - printk(FB_VESA_NAME " EDID v1 checksum failed\n"); - - /* try to find Detailed Timing Descriptor (defined in BASE EDID) - in controller mode list; first should be preffered mode */ - index = 0; - while (index < 4) - { - /* skip if it is monitor descriptor */ - if (edid.dtd_md[index].md.Flag0[0] == 0 && - edid.dtd_md[index].md.Flag0[1] == 0 && - edid.dtd_md[index].md.Flag1 == 0) - { - index++; - continue; - } - EDIDmode.resX = DTD_horizontal_active(&edid.dtd_md[0].dtd); - EDIDmode.resY = DTD_vertical_active(&edid.dtd_md[0].dtd); - if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != - -1) - return EDIDmode.mode_number; - - index++; - } - /* try to find Detailed Timing Descriptor (defined in optional EXTENSION - Blocks) in controller mode list */ - if (edid.ExtensionFlag > 0) - { - /* not implemented */ - } - /* try to find CVT (defined in BASE EDID) in controller mode list */ - index = 1; - while (index < 4) - { - if (edid.dtd_md[index].md.DataTypeTag == - EDID_DTT_CVT3ByteTimingCodes && - edid.dtd_md[index].md.Flag0[0] == 0 && - edid.dtd_md[index].md.Flag0[1] == 0 && - edid.dtd_md[index].md.Flag1 == 0 && - edid.dtd_md[index].md.Flag2 == 0) - { - EDID_CVT_timing_codes_3B *cvt = (EDID_CVT_timing_codes_3B *) - &edid.dtd_md[index].md.DescriptorData[0]; - j = 0; - while (j < 4) - { - EDIDmode.resY = edid1_CVT_addressable_lines_high( - &cvt->cvt[j] - ); - switch (edid1_CVT_aspect_ratio(&cvt->cvt[j])) - { - case EDID_CVT_AspectRatio_4_3: - EDIDmode.resX = (EDIDmode.resY*4)/3; - break; - case EDID_CVT_AspectRatio_16_9: - EDIDmode.resX = (EDIDmode.resY*16)/9; - break; - case EDID_CVT_AspectRatio_16_10: - EDIDmode.resX = (EDIDmode.resY*16)/10; - break; - case EDID_CVT_AspectRatio_15_9: - EDIDmode.resX = (EDIDmode.resY*15)/9; - break; - } - EDIDmode.resX = (EDIDmode.resX/8)*8; - if (find_mode_by_resolution( - mode_list, list_length, &EDIDmode) != -1) - return EDIDmode.mode_number; - - j++; - } - } - index++; - } - /* try to find CVT (defined in optional EXTENSION Blocks) - in controller mode list */ - /* not implemented */ - /* try to find Standard Timings (listed in BASE EDID) - in controller mode list */ - index = 0; - while (index < 8) - { - /* check if descriptor is unused */ - if (edid1_STI_is_unused(&edid.STI[index])) - { - index++; - continue; - } - EDIDmode.resX = (edid.STI[index].HorizontalActivePixels+31)*8; - switch (edid.STI[index].ImageAspectRatio_RefreshRate & - EDID1_STI_ImageAspectRatioMask) - { - case EDID_STI_AspectRatio_16_10: - EDIDmode.resY = (EDIDmode.resX*10)/16; - break; - case EDID_STI_AspectRatio_4_3: - EDIDmode.resY = (EDIDmode.resX*3)/4; - break; - case EDID_STI_AspectRatio_5_4: - EDIDmode.resY = (EDIDmode.resX*4)/5; - break; - case EDID_STI_AspectRatio_16_9: - EDIDmode.resY = (EDIDmode.resX*9)/16; - break; - } - if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != - -1) - return EDIDmode.mode_number; - - index++; - } - /* try to find Standard Timings (listed in optional EXTENSION Blocks) - in controller mode list */ - /* not implemented */ - /* use Established Timings */ - if (edid1_established_tim(&edid, EST_1280x1024_75Hz)) - { - EDIDmode.resX = 1280; - EDIDmode.resY = 1024; - EDIDmode.bpp = 0; - if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != - -1) - return EDIDmode.mode_number; - } - if (edid1_established_tim(&edid, EST_1152x870_75Hz)) - { - EDIDmode.resX = 1152; - EDIDmode.resY = 870; - EDIDmode.bpp = 0; - if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != - -1) - return EDIDmode.mode_number; - } - if (edid1_established_tim(&edid, EST_1024x768_75Hz) || - edid1_established_tim(&edid, EST_1024x768_70Hz) || - edid1_established_tim(&edid, EST_1024x768_60Hz) || - edid1_established_tim(&edid, EST_1024x768_87Hz)) - { - EDIDmode.resX = 1024; - EDIDmode.resY = 768; - EDIDmode.bpp = 0; - if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != - -1) - return EDIDmode.mode_number; - } - if (edid1_established_tim(&edid, EST_832x624_75Hz)) - { - EDIDmode.resX = 832; - EDIDmode.resY = 624; - EDIDmode.bpp = 0; - if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != - -1) - return EDIDmode.mode_number; - } - if (edid1_established_tim(&edid, EST_800x600_60Hz) || - edid1_established_tim(&edid, EST_800x600_56Hz) || - edid1_established_tim(&edid, EST_800x600_75Hz) || - edid1_established_tim(&edid, EST_800x600_72Hz)) - { - EDIDmode.resX = 800; - EDIDmode.resY = 600; - EDIDmode.bpp = 0; - if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != - -1) - return EDIDmode.mode_number; - } - if (edid1_established_tim(&edid, EST_720x400_88Hz) || - edid1_established_tim(&edid, EST_720x400_70Hz)) - { - EDIDmode.resX = 720; - EDIDmode.resY = 400; - EDIDmode.bpp = 0; - if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != - -1) - return EDIDmode.mode_number; - } - if (edid1_established_tim(&edid, EST_640x480_75Hz) || - edid1_established_tim(&edid, EST_640x480_72Hz) || - edid1_established_tim(&edid, EST_640x480_67Hz) || - edid1_established_tim(&edid, EST_640x480_60Hz)) - { - EDIDmode.resX = 640; - EDIDmode.resY = 480; - EDIDmode.bpp = 0; - if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != - -1) - return EDIDmode.mode_number; - } - } - else - printk(FB_VESA_NAME " error reading EDID: unsupported version\n"); - return -1; -} - -void vesa_realmode_bootup_init(void) -{ - uint32_t vbe_ret_val; - uint16_t size; - VBE_vbe_info_block *vib = (VBE_vbe_info_block *) - i386_get_default_rm_buffer(&size); - vbe_ret_val = VBE_controller_information(vib, 0x300); - if (vbe_ret_val == -1) - { - printk(FB_VESA_NAME " error calling real mode interrupt.\n"); - return; - } - if (vbe_ret_val != (VBE_callSuccessful<<8 | VBE_functionSupported)) - { - printk(FB_VESA_NAME " Function 00h (read VBE info block)" - "not supported.\n"); - } -/* Helper array is later filled with mode numbers and their parameters - sorted from the biggest values to the smalest where priorities of - parameters are from the highest to the lowest: resolution X, - resolution Y, bits per pixel. - The array is used for search the monitor provided parameters in EDID - structure and if found we set such mode using corresponding - VESA function. */ -#define MAX_NO_OF_SORTED_MODES 100 - Mode_params sorted_mode_params[MAX_NO_OF_SORTED_MODES]; - - uint16_t *vmpSegOff = (uint16_t *)&vib->VideoModePtr; - uint16_t *modeNOPtr = (uint16_t*) - i386_Real_to_physical(*(vmpSegOff+1), *vmpSegOff); - uint16_t iterator = 0; - - if (*(uint16_t*)vib->VideoModePtr == VBE_STUB_VideoModeList) - { - printk(FB_VESA_NAME " VBE Core not implemented!\n"); - } - else - { - /* prepare list of modes */ - while (*(modeNOPtr+iterator) != VBE_END_OF_VideoModeList && - *(modeNOPtr+iterator) != 0) - { /* some bios implementations ends the list incorrectly with 0 */ - if (iterator < MAX_NO_OF_SORTED_MODES) - { - sorted_mode_params[iterator].mode_number =*(modeNOPtr+iterator); - iterator ++; - } - else - break; - } - if (iterator < MAX_NO_OF_SORTED_MODES) - sorted_mode_params[iterator].mode_number = 0; - } - - VBE_mode_info_block *mib = (VBE_mode_info_block *) - i386_get_default_rm_buffer(&size); - iterator = 0; - uint8_t nextFilteredMode = 0; - uint16_t required_mode_attributes = VBE_modSupInHWMask | - VBE_ColorModeMask | VBE_GraphicsModeMask | VBE_LinFraBufModeAvaiMask; - /* get parameters of modes and filter modes according to set - required parameters */ - while (iterator < MAX_NO_OF_SORTED_MODES && - sorted_mode_params[iterator].mode_number!=0) - { - VBE_mode_information(mib, sorted_mode_params[iterator].mode_number); - if ((mib->ModeAttributes&required_mode_attributes) == - required_mode_attributes) - { - sorted_mode_params[nextFilteredMode].mode_number = - sorted_mode_params[iterator].mode_number; - sorted_mode_params[nextFilteredMode].resX = mib->XResolution; - sorted_mode_params[nextFilteredMode].resY = mib->YResolution; - sorted_mode_params[nextFilteredMode].bpp = mib->BitsPerPixel; - nextFilteredMode ++; - } - iterator ++; - } - sorted_mode_params[nextFilteredMode].mode_number = 0; - - uint8_t number_of_modes = nextFilteredMode; - - /* first search for video argument in multiboot options */ - vbe_used_mode = find_mode_using_cmdline(sorted_mode_params, - number_of_modes); - - if (vbe_used_mode == NO_MODE_REQ) { - vbe_used_mode = find_mode_from_string(sorted_mode_params, - number_of_modes, rtems_fb_default_mode); - if (vbe_used_mode != NO_MODE_REQ) { - printk(FB_VESA_NAME " using application option to select" - " video mode\n"); - } - } - else - { - printk(FB_VESA_NAME " using command line option '--video='" - "to select video mode\n"); - } - - switch (vbe_used_mode) { - case NO_SUITABLE_MODE: - printk(FB_VESA_NAME " requested mode not found\n"); - return; - case BAD_FORMAT: - printk(FB_VESA_NAME " bad format of video requested\n"); - return; - case DONT_INIT: - printk(FB_VESA_NAME " selected not to initialize graphics\n"); - return; - case NO_MODE_REQ: - printk(FB_VESA_NAME " not initialized, no video selected\n"); - return; - } - - /* sort filtered modes */ - Mode_params modeXchgPlace; - iterator = 0; - uint8_t j; - uint8_t idxBestMode; - while (iterator < number_of_modes) - { - idxBestMode = iterator; - j = iterator+1; - while (j < number_of_modes) - { - if (sorted_mode_params[j].resX > - sorted_mode_params[idxBestMode].resX) - idxBestMode = j; - else if (sorted_mode_params[j].resX == - sorted_mode_params[idxBestMode].resX) - { - if (sorted_mode_params[j].resY > - sorted_mode_params[idxBestMode].resY) - idxBestMode = j; - else if (sorted_mode_params[j].resY == - sorted_mode_params[idxBestMode].resY) - { - if (sorted_mode_params[j].bpp > - sorted_mode_params[idxBestMode].bpp) - idxBestMode = j; - } - } - j++; - } - if (idxBestMode != iterator) - { - modeXchgPlace = sorted_mode_params[iterator]; - sorted_mode_params[iterator] = sorted_mode_params[idxBestMode]; - sorted_mode_params[idxBestMode] = modeXchgPlace; - } - iterator++; - } - - if (vbe_used_mode == AUTO_SELECT) - { - printk(FB_VESA_NAME " auto video mode selected" - "\n\ttrying EDID ...\n"); - /* second search monitor for good resolution */ - vbe_used_mode = find_mode_using_EDID(sorted_mode_params, - number_of_modes); - if (vbe_used_mode == -1) - { - printk(FB_VESA_NAME" monitor's EDID video parameters not supported" - "\n\tusing mode with highest resolution, bpp\n"); - /* third set highest values */ - vbe_used_mode = sorted_mode_params[0].mode_number; - } - } - - /* fill framebuffer structs with info about selected mode */ - vbe_ret_val = VBE_mode_information(mib, vbe_used_mode); - if ((vbe_ret_val&0xff)!=VBE_functionSupported || - (vbe_ret_val>>8)!=VBE_callSuccessful) - { - printk(FB_VESA_NAME " Cannot get mode info anymore. ax=0x%lx\n", - vbe_ret_val); - } - - fb_var.xres = mib->XResolution; - fb_var.yres = mib->YResolution; - fb_var.bits_per_pixel = mib->BitsPerPixel; - fb_var.red.offset = mib->LinRedFieldPosition; - fb_var.red.length = mib->LinRedMaskSize; - fb_var.red.msb_right = 0; - fb_var.green.offset = mib->LinGreenFieldPosition; - fb_var.green.length = mib->LinGreenMaskSize; - fb_var.green.msb_right = 0; - fb_var.blue.offset = mib->LinBlueFieldPosition; - fb_var.blue.length = mib->LinBlueMaskSize; - fb_var.blue.msb_right = 0; - fb_var.transp.offset = mib->LinRsvdFieldPosition; - fb_var.transp.length = mib->LinRsvdMaskSize; - fb_var.transp.msb_right =0; - - fb_fix.smem_start = (char *)mib->PhysBasePtr; - fb_fix.line_length = mib->LinBytesPerScanLine; - fb_fix.smem_len = fb_fix.line_length*fb_var.yres; - fb_fix.type = FB_TYPE_PACKED_PIXELS; - if (fb_var.bits_per_pixel < 24) - fb_fix.visual = FB_VISUAL_DIRECTCOLOR; - else - fb_fix.visual = FB_VISUAL_TRUECOLOR; - - /* set selected mode */ - vbe_ret_val = VBE_set_mode(vbe_used_mode | VBE_linearFlatFrameBufMask, - (VBE_CRTC_info_block *)(i386_get_default_rm_buffer(&size))); - if (vbe_ret_val>>8 == VBE_callFailed) - printk(FB_VESA_NAME " VBE: Requested mode is not available."); - - if ((vbe_ret_val&0xff)!= (VBE_functionSupported | VBE_callSuccessful<<8)) - printk(FB_VESA_NAME " Call to function 2h (set VBE mode) failed. " - "ax=0x%" PRIx32 "\n", vbe_ret_val); - - vib = (void *) 0; - mib = (void *) 0; -} - -/* - * fb_vesa device driver INITIALIZE entry point. - */ -rtems_device_driver -frame_buffer_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - - printk(FB_VESA_NAME " frame buffer -- driver initializing..\n" ); - - /* - * Register the device. - */ - status = rtems_io_register_name(FRAMEBUFFER_DEVICE_0_NAME, major, 0); - if (status != RTEMS_SUCCESSFUL) - { - printk("Error registering " FRAMEBUFFER_DEVICE_0_NAME - " - " FB_VESA_NAME " frame buffer device!\n"); - rtems_fatal_error_occurred( status ); - } - - _Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE); - - return RTEMS_SUCCESSFUL; -} - -/* - * fb_vesa device driver OPEN entry point - */ -rtems_device_driver -frame_buffer_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - printk( FB_VESA_NAME " open device\n" ); - - if (_Atomic_Flag_test_and_set(&driver_mutex, ATOMIC_ORDER_ACQUIRE) != 0 ) - { - printk( FB_VESA_NAME " could not lock vesa_mutex\n" ); - - return RTEMS_UNSATISFIED; - } - - return RTEMS_SUCCESSFUL; - -} - -/* - * fb_vesa device driver CLOSE entry point - */ -rtems_device_driver -frame_buffer_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - printk( FB_VESA_NAME " close device\n" ); - _Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE); - /* restore previous state. for VGA this means return to text mode. - * leave out if graphics hardware has been initialized in - * frame_buffer_initialize() */ - - printk(FB_VESA_NAME ": close called.\n" ); - return RTEMS_SUCCESSFUL; -} - -/* - * fb_vesa device driver READ entry point. - */ -rtems_device_driver -frame_buffer_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - printk( FB_VESA_NAME " read device\n" ); - rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; - rw_args->bytes_moved = - ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? - (fb_fix.smem_len - rw_args->offset) : - rw_args->count; - memcpy(rw_args->buffer, (const void *) - (fb_fix.smem_start + rw_args->offset), rw_args->bytes_moved); - return RTEMS_SUCCESSFUL; -} - -/* - * frame_vesa device driver WRITE entry point. - */ -rtems_device_driver -frame_buffer_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - printk( FB_VESA_NAME " write device\n" ); - rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; - rw_args->bytes_moved = - ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? - (fb_fix.smem_len - rw_args->offset) : - rw_args->count; - memcpy( (void *) (fb_fix.smem_start + rw_args->offset), - rw_args->buffer, rw_args->bytes_moved); - return RTEMS_SUCCESSFUL; -} - -static int get_fix_screen_info( struct fb_fix_screeninfo *info ) -{ - *info = fb_fix; - return 0; -} - -static int get_var_screen_info( struct fb_var_screeninfo *info ) -{ - *info = fb_var; - return 0; -} - -/* - * IOCTL entry point -- This method is called to carry - * all services of this interface. - */ -rtems_device_driver -frame_buffer_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_libio_ioctl_args_t *args = arg; - - printk( FB_VESA_NAME " ioctl called, cmd=%" PRIx32 "\n", args->command ); - printk("fbxres %lu, fbyres %lu\n", fb_var.xres, fb_var.yres); - printk("fbbpp %lu\n", fb_var.bits_per_pixel); - - switch (args->command) - { - case FBIOGET_FSCREENINFO: - args->ioctl_return = - get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer ); - break; - case FBIOGET_VSCREENINFO: - args->ioctl_return = - get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer ); - break; - case FBIOPUT_VSCREENINFO: - /* not implemented yet */ - args->ioctl_return = -1; - return RTEMS_UNSATISFIED; - case FBIOGETCMAP: - /* no palette - truecolor mode */ - args->ioctl_return = -1; - return RTEMS_UNSATISFIED; - case FBIOPUTCMAP: - /* no palette - truecolor mode */ - args->ioctl_return = -1; - return RTEMS_UNSATISFIED; - default: - args->ioctl_return = 0; - break; - } - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/lib/libbsp/i386/pc386/console/fb_vga.c b/c/src/lib/libbsp/i386/pc386/console/fb_vga.c deleted file mode 100644 index 75ad56eb98..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/fb_vga.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (c) 2000 - Rosimildo da Silva ( rdasilva@connecttel.com ) - * - * MODULE DESCRIPTION: - * This module implements FB driver for "Bare VGA". It uses the - * routines for "bare hardware" found in vgainit.c. - * - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include - -/* these routines are defined in vgainit.c.*/ -extern void ega_hwinit( void ); -extern void ega_hwterm( void ); - -/* flag to limit driver to protect against multiple opens */ -static Atomic_Flag driver_mutex; - -/* screen information for the VGA driver */ -static struct fb_var_screeninfo fb_var = -{ - .xres = 640, - .yres = 480, - .bits_per_pixel = 4 -}; - -static struct fb_fix_screeninfo fb_fix = -{ - .smem_start = (volatile char *)0xA0000, /* buffer pointer */ - .smem_len = 0x10000, /* buffer size */ - .type = FB_TYPE_VGA_PLANES, /* type of dsplay */ - .visual = FB_VISUAL_PSEUDOCOLOR, /* color scheme used */ - .line_length = 80 /* chars per line */ -}; - - -static uint16_t red16[] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, - 0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff -}; -static uint16_t green16[] = { - 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa, - 0x5555, 0x5555, 0xffff, 0xffff, 0x5555, 0x5555, 0xffff, 0xffff -}; -static uint16_t blue16[] = { - 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, - 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff -}; - -/* Functionality to support multiple VGA frame buffers can be added easily, - * but is not supported at this moment because there is no need for two or - * more "classic" VGA adapters. Multiple frame buffer drivers may be - * implemented and If we had implement it they would be named as "/dev/fb0", - * "/dev/fb1", "/dev/fb2" and so on. - */ -/* - * fbvga device driver INITIALIZE entry point. - */ -rtems_device_driver frame_buffer_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - - printk( "FBVGA -- driver initializing..\n" ); - - /* - * Register the device - */ - status = rtems_io_register_name (FRAMEBUFFER_DEVICE_0_NAME, major, 0); - if (status != RTEMS_SUCCESSFUL) { - printk("Error registering " FRAMEBUFFER_DEVICE_0_NAME - " FBVGA framebuffer device!\n"); - rtems_fatal_error_occurred( status ); - } - - _Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE); - - return RTEMS_SUCCESSFUL; -} - -/* - * fbvga device driver OPEN entry point - */ -rtems_device_driver frame_buffer_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - if (_Atomic_Flag_test_and_set(&driver_mutex, ATOMIC_ORDER_ACQUIRE) != 0 ) { - /* restore previous state. for VGA this means return to text mode. - * leave out if graphics hardware has been initialized in - * frame_buffer_initialize() - */ - ega_hwinit(); - printk( "FBVGA open called.\n" ); - return RTEMS_SUCCESSFUL; - } - - return RTEMS_UNSATISFIED; -} - -/* - * fbvga device driver CLOSE entry point - */ -rtems_device_driver frame_buffer_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - _Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE); - /* restore previous state. for VGA this means return to text mode. - * leave out if graphics hardware has been initialized in - * frame_buffer_initialize() */ - ega_hwterm(); - printk( "FBVGA close called.\n" ); - return RTEMS_SUCCESSFUL; - -/* - * fbvga device driver READ entry point. - */ -rtems_device_driver frame_buffer_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; - rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count; - memcpy(rw_args->buffer, (const void *) (fb_fix.smem_start + rw_args->offset), rw_args->bytes_moved); - return RTEMS_SUCCESSFUL; -} - -/* - * frame_buffer device driver WRITE entry point. - */ -rtems_device_driver frame_buffer_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; - rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count; - memcpy( (void *) (fb_fix.smem_start + rw_args->offset), rw_args->buffer, rw_args->bytes_moved); - return RTEMS_SUCCESSFUL; -} - -static int get_fix_screen_info( struct fb_fix_screeninfo *info ) -{ - *info = fb_fix; - return 0; -} - -static int get_var_screen_info( struct fb_var_screeninfo *info ) -{ - *info = fb_var; - return 0; -} - -static int get_palette( struct fb_cmap *cmap ) -{ - uint32_t i; - - if ( cmap->start + cmap->len >= 16 ) - return 1; - - for( i = 0; i < cmap->len; i++ ) { - cmap->red[ cmap->start + i ] = red16[ cmap->start + i ]; - cmap->green[ cmap->start + i ] = green16[ cmap->start + i ]; - cmap->blue[ cmap->start + i ] = blue16[ cmap->start + i ]; - } - return 0; -} - -static int set_palette( struct fb_cmap *cmap ) -{ - uint32_t i; - - if ( cmap->start + cmap->len >= 16 ) - return 1; - - for( i = 0; i < cmap->len; i++ ) { - red16[ cmap->start + i ] = cmap->red[ cmap->start + i ]; - green16[ cmap->start + i ] = cmap->green[ cmap->start + i ]; - blue16[ cmap->start + i ] = cmap->blue[ cmap->start + i ]; - } - return 0; -} - -/* - * IOCTL entry point -- This method is called to carry - * all services of this interface. - */ -rtems_device_driver frame_buffer_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_libio_ioctl_args_t *args = arg; - - printk( "FBVGA ioctl called, cmd=%x\n", args->command ); - - switch( args->command ) { - case FBIOGET_FSCREENINFO: - args->ioctl_return = get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer ); - break; - case FBIOGET_VSCREENINFO: - args->ioctl_return = get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer ); - break; - case FBIOPUT_VSCREENINFO: - /* not implemented yet*/ - args->ioctl_return = -1; - return RTEMS_UNSATISFIED; - case FBIOGETCMAP: - args->ioctl_return = get_palette( ( struct fb_cmap * ) args->buffer ); - break; - case FBIOPUTCMAP: - args->ioctl_return = set_palette( ( struct fb_cmap * ) args->buffer ); - break; - - default: - args->ioctl_return = 0; - break; - } - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/lib/libbsp/i386/pc386/console/gdb_select.c b/c/src/lib/libbsp/i386/pc386/console/gdb_select.c deleted file mode 100644 index adc996913b..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/gdb_select.c +++ /dev/null @@ -1,170 +0,0 @@ -/** - * @file - * - * @ingroup GDB - * - * @brief pc386 gdb select - * - * This file contains a routine to enable and select the UART the gdb stub - * connects too. Currently limited to COM1 and COM2. See - * shared/comm/i386-stub-glue.c file. - */ - -/* - * COPYRIGHT (c) 2016. - * Chris Johns - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h" - -/* - * Used in the stub to print output. - */ -int remote_debug; -/* - * Defined in the stub, used here. - */ -void set_debug_traps(void); - -/* - * Added here to get a valid baudrate. Needs to go once we - * move to the standard UART driver. - */ -int BSPBaseBaud; - -static bool gdb_port_probe(int minor) -{ - /* Return false as GDB has claimed the port */ - return false; -} - -void pc386_parse_gdb_arguments(void) -{ - static const char *opt; - - /* - * Check the command line to see if com1-com4 are disabled. - */ - opt = bsp_cmdline_arg("--gdb="); - if ( opt ) { - const char *option; - const char *comma; - size_t length; - size_t index; - rtems_device_minor_number minor; - uint32_t baudrate = 115200; - bool halt = false; - console_tbl *port; - - /* - * Fine the length, there can be more command line visible. - */ - length = 0; - while ((opt[length] != ' ') && (opt[length] != '\0')) { - ++length; - if (length > NAME_MAX) { - printk("invalid option (--gdb): too long\n"); - return; - } - } - - /* - * Only match up to a comma or NULL - */ - index = 0; - while ((opt[index] != '=') && (index < length)) { - ++index; - } - - if (opt[index] != '=') { - printk("invalid option (--gdb): no equals\n"); - return; - } - - ++index; - option = &opt[index]; - - while ((opt[index] != ',') && (index < length)) { - ++index; - } - - if (opt[index] == ',') - comma = &opt[index]; - else - comma = NULL; - - length = &opt[index] - option; - - port = console_find_console_entry( option, length, &minor ); - - if ( port == NULL ) { - printk("invalid option (--gdb): port not found\n"); - return; - } - - if (comma) { - option = comma + 1; - baudrate = strtoul(option, 0, 10); - switch (baudrate) { - case 115200: - case 57600: - case 38400: - case 19200: - case 9600: - case 4800: - port->pDeviceParams = (void*) baudrate; - BSPBaseBaud = baudrate; /* REMOVE ME */ - break; - default: - printk("invalid option (--gdb): bad baudrate\n"); - return; - } - } - - /* - * Provide a probe that fails so the device is not part of termios. All - * functions are polling. - */ - port->deviceProbe = gdb_port_probe; - port->pDeviceFns = &ns16550_fns_polled; - - opt = bsp_cmdline_arg("--gdb-remote-debug"); - if ( opt ) { - remote_debug = 1; - } - - opt = bsp_cmdline_arg("--gdb-break"); - if ( opt ) { - halt = true; - } - - printk("GDB stub: enable %s%s%s\n", - port->sDeviceName, - remote_debug ? ", remote-debug" : "", - halt ? ", halting" : ""); - - i386_stub_glue_init(minor); - set_debug_traps(); - i386_stub_glue_init_breakin(); - - if ( halt ) { - printk("GDB stub: waiting for remote connection..\n"); - breakpoint(); - } - } -} diff --git a/c/src/lib/libbsp/i386/pc386/console/i386kbd.h b/c/src/lib/libbsp/i386/pc386/console/i386kbd.h deleted file mode 100644 index 627b37c750..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/i386kbd.h +++ /dev/null @@ -1,192 +0,0 @@ -/** - * @file - * - * @ingroup i386_pc386 - * - * @brief I386 keyboard definitions. - */ - -/* - * linux/include/asm-i386/keyboard.h - * - * Created 3 Nov 1996 by Geert Uytterhoeven - */ - -/* - * This file contains the i386 architecture specific keyboard definitions - */ - -#ifndef _I386_KEYBOARD_H -#define _I386_KEYBOARD_H - -#include - -#define KEYBOARD_IRQ 1 -#define DISABLE_KBD_DURING_INTERRUPTS 0 - -extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); -extern int pckbd_getkeycode(unsigned int scancode); -extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, - char raw_mode); -extern char pckbd_unexpected_up(unsigned char keycode); -extern void pckbd_leds(unsigned char leds); -extern void pckbd_init_hw(void); -extern unsigned char pckbd_sysrq_xlate[128]; - -#define kbd_setkeycode pckbd_setkeycode -#define kbd_getkeycode pckbd_getkeycode -#define kbd_translate pckbd_translate -#define kbd_unexpected_up pckbd_unexpected_up -#define kbd_leds pckbd_leds -#define kbd_init_hw pckbd_init_hw -#define kbd_sysrq_xlate pckbd_sysrq_xlate - -#define SYSRQ_KEY 0x54 - -/* resource allocation */ -#define kbd_request_region() /* request_region(0x60, 16, "keyboard") */ -#define kbd_request_irq(handler) /* request_irq(KEYBOARD_IRQ, handler, 0, "keyboard", NULL) */ - -/* How to access the keyboard macros on this platform. */ -#define kbd_read_input() inb(KBD_DATA_REG) -#define kbd_read_status() inb(KBD_STATUS_REG) -#define kbd_write_output(val) outb(val, KBD_DATA_REG) -#define kbd_write_command(val) outb(val, KBD_CNTL_REG) - -/* Some stoneage hardware needs delays after some operations. */ -#define kbd_pause() do { } while(0) - -/* - * Machine specific bits for the PS/2 driver - */ - -#define AUX_IRQ 12 - -#define aux_request_irq(hand, dev_id) /* request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id) */ - -#define aux_free_irq(dev_id) /* free_irq(AUX_IRQ, dev_id) */ - -/* - * include/linux/pc_keyb.h - * - * PC Keyboard And Keyboard Controller - * - * (c) 1997 Martin Mares - */ - -/* - * Configuration Switches - */ - -#undef KBD_REPORT_ERR /* Report keyboard errors */ -#define KBD_REPORT_UNKN /* Report unknown scan codes */ -#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */ -#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */ -#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */ - -#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */ -#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */ -#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */ - -/* - * Internal variables of the driver - */ - -extern unsigned char pckbd_read_mask; -extern unsigned char aux_device_present; - -/* - * Keyboard Controller Registers on normal PCs. - */ - -#define KBD_STATUS_REG 0x64 /* Status register (R) */ -#define KBD_CNTL_REG 0x64 /* Controller command register (W) */ -#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */ - -/* - * Keyboard Controller Commands - */ - -#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */ -#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */ -#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */ -#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */ -#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */ -#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */ -#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */ -#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */ -#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */ -#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */ -#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if - initiated by the auxiliary device */ -#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */ - -/* - * Keyboard Commands - */ - -#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */ -#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */ -#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */ -#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */ -#define KBD_CMD_RESET 0xFF /* Reset */ - -/* - * Keyboard Replies - */ - -#define KBD_REPLY_POR 0xAA /* Power on reset */ -#define KBD_REPLY_ACK 0xFA /* Command ACK */ -#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */ - -/* - * Status Register Bits - */ - -#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */ -#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */ -#define KBD_STAT_SELFTEST 0x04 /* Self test successful */ -#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */ -#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */ -#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */ -#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */ -#define KBD_STAT_PERR 0x80 /* Parity error */ - -#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF) - -/* - * Controller Mode Register Bits - */ - -#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */ -#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */ -#define KBD_MODE_SYS 0x04 /* The system flag (?) */ -#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */ -#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */ -#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */ -#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */ -#define KBD_MODE_RFU 0x80 - -/* - * Mouse Commands - */ - -#define AUX_SET_RES 0xE8 /* Set resolution */ -#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */ -#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */ -#define AUX_GET_SCALE 0xE9 /* Get scaling factor */ -#define AUX_SET_STREAM 0xEA /* Set stream mode */ -#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */ -#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */ -#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */ -#define AUX_RESET 0xFF /* Reset aux device */ -#define AUX_ACK 0xFA /* Command byte ACK. */ - -#define AUX_BUF_SIZE 2048 /* This might be better divisible by - three to make overruns stay in sync - but then the read function would need - a lock etc - ick */ - -#define mark_bh(x) - -#endif /* _I386_KEYBOARD_H */ diff --git a/c/src/lib/libbsp/i386/pc386/console/inch.c b/c/src/lib/libbsp/i386/pc386/console/inch.c deleted file mode 100644 index f5d5079236..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/inch.c +++ /dev/null @@ -1,300 +0,0 @@ -/*-------------------------------------------------------------------------+ -| inch.c v1.1 - PC386 BSP - 1997/08/07 -+--------------------------------------------------------------------------+ -| (C) Copyright 1997 - -| - NavIST Group - Real-Time Distributed Systems and Industrial Automation -| -| http://pandora.ist.utl.pt -| -| Instituto Superior Tecnico * Lisboa * PORTUGAL -+--------------------------------------------------------------------------+ -| Disclaimer: -| -| This file is provided "AS IS" without warranty of any kind, either -| expressed or implied. -+--------------------------------------------------------------------------+ -| This code is based on: -| inch.c,v 1.3 1995/12/19 20:07:25 joel Exp - go32 BSP -| With the following copyright notice: -| With the following copyright notice: -| ************************************************************************** -| * COPYRIGHT (c) 1989-1998. -| * On-Line Applications Research Corporation (OAR). -| * -| * The license and distribution terms for this file may be -| * found in the file LICENSE in this distribution or at -| * http://www.rtems.org/license/LICENSE. -| ************************************************************************** -+--------------------------------------------------------------------------*/ - -#include -#include -#include - -/*-------------------------------------------------------------------------+ -| Constants -+--------------------------------------------------------------------------*/ -#define KBD_CTL 0x61 /* -------------------------------- */ -#define KBD_DATA 0x60 /* Ports for PC keyboard controller */ -#define KBD_STATUS 0x64 /* -------------------------------- */ - -#define KBD_BUF_SIZE 256 - -/*-------------------------------------------------------------------------+ -| Global Variables -+--------------------------------------------------------------------------*/ -static char key_map[] = -{ - 0,033,'1','2','3','4','5','6','7','8','9','0','-','=','\b','\t', - 'q','w','e','r','t','y','u','i','o','p','[',']',015,0x80, - 'a','s','d','f','g','h','j','k','l',';',047,0140,0x80, - 0134,'z','x','c','v','b','n','m',',','.','/',0x80, - '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, - 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, - 0x80,0x80,0x80,'0',0177 -}; /* Keyboard scancode -> character map with no modifiers. */ - -static char shift_map[] = -{ - 0,033,'!','@','#','$','%','^','&','*','(',')','_','+','\b','\t', - 'Q','W','E','R','T','Y','U','I','O','P','{','}',015,0x80, - 'A','S','D','F','G','H','J','K','L',':',042,'~',0x80, - '|','Z','X','C','V','B','N','M','<','>','?',0x80, - '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, - 0x80,0x80,0x80,0x80,'7','8','9',0x80,'4','5','6',0x80, - '1','2','3','0',177 -}; /* Keyboard scancode -> character map with SHIFT key modifier. */ - -static unsigned short kbd_buffer[KBD_BUF_SIZE]; -static uint16_t kbd_first = 0; -static uint16_t kbd_last = 0; -static uint16_t kbd_end = KBD_BUF_SIZE - 1; - -/*-------------------------------------------------------------------------+ -| Function: _IBMPC_scankey -| Description: This function can be called during a poll for input, or by -| an ISR. Basically any time you want to process a keypress. -| Global Variables: key_map, shift_map. -| Arguments: outChar - character read in case of a valid reading, -| otherwise unchanged. -| Returns: TRUE in case a valid character has been read, -| FALSE otherwise. -+--------------------------------------------------------------------------*/ -static bool -_IBMPC_scankey(char *outChar) -{ - unsigned char inChar; - static int alt_pressed = 0; - static int ctrl_pressed = 0; - static int shift_pressed = 0; - static int caps_pressed = 0; - static int extended = 0; - - *outChar = '\0'; /* default value if we return false */ - - /* Read keyboard controller, toggle enable */ - inport_byte(KBD_CTL, inChar); - outport_byte(KBD_CTL, inChar & ~0x80); - outport_byte(KBD_CTL, inChar | 0x80); - outport_byte(KBD_CTL, inChar & ~0x80); - - /* See if it has data */ - inport_byte(KBD_STATUS, inChar); - if ((inChar & 0x01) == 0) - return false; - - /* Read the data. Handle nonsense with shift, control, etc. */ - inport_byte(KBD_DATA, inChar); - - if (extended) - extended--; - - switch (inChar) - { - case 0xe0: - extended = 2; - return false; - break; - - case 0x38: - alt_pressed = 1; - return false; - break; - case 0xb8: - alt_pressed = 0; - return false; - break; - - case 0x1d: - ctrl_pressed = 1; - return false; - break; - case 0x9d: - ctrl_pressed = 0; - return false; - break; - - case 0x2a: - if (extended) - return false; - case 0x36: - shift_pressed = 1; - return false; - break; - case 0xaa: - if (extended) - return false; - case 0xb6: - shift_pressed = 0; - return false; - break; - - case 0x3a: - caps_pressed = 1; - return false; - break; - case 0xba: - caps_pressed = 0; - return false; - break; - - case 0x53: - if (ctrl_pressed && alt_pressed) - bsp_reset(); /* ctrl+alt+del -> reboot */ - break; - - /* - * Ignore unrecognized keys--usually arrow and such - */ - default: - if ((inChar & 0x80) || (inChar > 0x39)) - /* High-bit on means key is being released, not pressed */ - return false; - break; - } /* switch */ - - /* Strip high bit, look up in our map */ - inChar &= 0x7f; - if (ctrl_pressed) - { - *outChar = key_map[inChar]; - *outChar &= 037; - } - else - { - *outChar = shift_pressed ? shift_map[inChar] : key_map[inChar]; - if (caps_pressed) - { - if (*outChar >= 'A' && *outChar <= 'Z') - *outChar += 'a' - 'A'; - else if (*outChar >= 'a' && *outChar <= 'z') - *outChar -= 'a' - 'A'; - } - } - - return true; -} /* _IBMPC_scankey */ - -/*-------------------------------------------------------------------------+ -| Function: _IBMPC_chrdy -| Description: Check keyboard ISR buffer and return character if not empty. -| Global Variables: kbd_buffer, kbd_first, kbd_last. -| Arguments: c - character read if keyboard buffer not empty, otherwise -| unchanged. -| Returns: TRUE if keyboard buffer not empty, FALSE otherwise. -+--------------------------------------------------------------------------*/ -static bool -_IBMPC_chrdy(char *c) -{ -#if CCJ_REMOVED_NO_IDEA_ABOUT_THIS_CODE_OR_COMMENT - /* FIX ME!!! It doesn't work without something like the following line. - Find out why! */ - printk(""); -#endif - - /* Check buffer our ISR builds */ - if (kbd_first != kbd_last) - { - *c = kbd_buffer[kbd_first]; - - kbd_first = (kbd_first + 1) % KBD_BUF_SIZE; - return true; - } - else - return false; -} /* _IBMPC_chrdy */ - -/*-------------------------------------------------------------------------+ -| Function: _IBMPC_inch -| Description: Poll keyboard until a character is ready and return it. -| Global Variables: None. -| Arguments: None. -| Returns: character read from keyboard. -+--------------------------------------------------------------------------*/ -char -_IBMPC_inch(void) -{ - char c; - while (!_IBMPC_chrdy(&c)) - continue; - - return c; -} /* _IBMPC_inch */ - -/* - * Routine that can be used before interrupt management is initialized. - */ -int BSP_wait_polled_input(void) -{ - char c; - while (!_IBMPC_scankey(&c)) - continue; - - return c; -} - -/* - * Check if a key has been pressed. This is a non-destructive - * call, meaning, it keeps the key in the buffer. - */ -int rtems_kbpoll( void ) -{ - int rc; - - /* - * The locking or disable of interrupts does not help - * there because if interrupts are enabled after leave of this - * function the state can change without notice anyway. - */ - RTEMS_COMPILER_MEMORY_BARRIER(); - - rc = ( kbd_first != kbd_last ) ? TRUE : FALSE; - - RTEMS_COMPILER_MEMORY_BARRIER(); - - return rc; -} - -int getch( void ) -{ - int c; - - while( kbd_first == kbd_last ) - { - rtems_task_wake_after( 10 ); - } - c = kbd_buffer[ kbd_first ]; - kbd_first = (kbd_first + 1) % KBD_BUF_SIZE; - return c; -} - -void add_to_queue( unsigned short b ) -{ - unsigned int next; - kbd_buffer[ kbd_last ] = b; - next = (kbd_last == kbd_end) ? 0 : kbd_last + 1; - if( next != kbd_first ) - { - kbd_last = next; - } -} diff --git a/c/src/lib/libbsp/i386/pc386/console/kbd_parser.c b/c/src/lib/libbsp/i386/pc386/console/kbd_parser.c deleted file mode 100644 index f3d2f9c55a..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/kbd_parser.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * The contents of this file were formerly in console.c which - * had the following copyright notice: - * - * (C) Copyright 1997 - * NavIST Group - Real-Time Distributed Systems and Industrial Automation - * http://pandora.ist.utl.pt - * Instituto Superior Tecnico * Lisboa * PORTUGAL - * - * The original code and subsequent modifications are: - * - * COPYRIGHT (c) 1989-2011. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include - -/* adds a kbd message to the queue */ -static void kbd_parser( void *ptr, unsigned short keycode, unsigned long mods ) -{ - struct MW_UID_MESSAGE m; - struct kbd_struct * kbd = (struct kbd_struct *)ptr; - - m.type = MV_UID_KBD; - m.m.kbd.code = keycode; - m.m.kbd.modifiers = kbd->ledflagstate; - m.m.kbd.mode = kbd->kbdmode; - /* printk( "kbd: msg: keycode=%X, mod=%X\n", keycode, mods ); */ - - uid_send_message( &m ); -} - -void register_kbd_msg_queue( char *q_name, int port ) -{ - kbd_set_driver_handler( kbd_parser ); -} - -void unregister_kbd_msg_queue( int port ) -{ - kbd_set_driver_handler( NULL ); -} diff --git a/c/src/lib/libbsp/i386/pc386/console/keyboard.c b/c/src/lib/libbsp/i386/pc386/console/keyboard.c deleted file mode 100644 index 0c8991b829..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/keyboard.c +++ /dev/null @@ -1,881 +0,0 @@ -/* - * Rosimildo da Silva: rdasilva@connecttel.com - */ - -#include -#include -#include -#include "i386kbd.h" -#include -#include -#include -#include - -#define SIZE(x) (sizeof(x)/sizeof((x)[0])) - -#ifndef KBD_DEFMODE -#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META)) -#endif - -#ifndef KBD_DEFLEDS -/* - * Some laptops take the 789uiojklm,. keys as number pad when NumLock - * is on. This seems a good reason to start with NumLock off. - */ -#define KBD_DEFLEDS 0 -#endif - -#ifndef KBD_DEFLOCK -#define KBD_DEFLOCK 0 -#endif - -static int kbd_test_and_set_bit(int nr, atomic_uint_least32_t * addr) -{ - uint_least32_t mask; - int retval; - - addr += nr >> 5; - mask = 1UL << (nr & 0x1f); - - retval = (atomic_fetch_or(addr, mask) & mask) != 0; - - return retval; -} - -static int kbd_test_and_clear_bit(int nr, atomic_uint_least32_t * addr) -{ - uint_least32_t mask; - int retval; - - addr += nr >> 5; - mask = 1UL << (nr & 0x1f); - - retval = (atomic_fetch_and(addr, ~mask) & mask) != 0; - - return retval; -} - -static int kbd_test_bit(int nr, atomic_uint_least32_t * addr) -{ - unsigned long mask; - - addr += nr >> 5; - mask = 1 << (nr & 0x1f); - return ((mask & atomic_load(addr)) != 0); -} - -/* - * global state includes the following, and various static variables - * in this module: prev_scancode, shift_state, diacr, npadch, dead_key_next. - * (last_console is now a global variable) - */ -#define KBD_BITS_PER_ELEMENT (sizeof(atomic_uint_least32_t)*CHAR_BIT) - -/* shift state counters.. */ -static unsigned char k_down[NR_SHIFT] = {0, }; -/* keyboard key bitmap */ -static atomic_uint_least32_t - key_down[(256 + KBD_BITS_PER_ELEMENT - 1) / KBD_BITS_PER_ELEMENT] = { 0, }; - -static int dead_key_next = 0; -/* - * In order to retrieve the shift_state (for the mouse server), either - * the variable must be global, or a new procedure must be created to - * return the value. I chose the former way. - */ -int shift_state = 0; -static int npadch = -1; /* -1 or number assembled on pad */ -static unsigned char diacr = 0; -static char rep = 0; /* flag telling character repeat */ - -/* default console for RTEMS */ -static int fg_console = 0; - -struct kbd_struct kbd_table[MAX_NR_CONSOLES]; -static struct kbd_struct * kbd = kbd_table; - -void compute_shiftstate(void); - -typedef void (*k_hand)(unsigned char value, char up_flag); -typedef void (k_handfn)(unsigned char value, char up_flag); - -static k_handfn - do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift, - do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2, - do_ignore; - -static k_hand key_handler[16] = { - do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift, - do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2, - do_ignore, do_ignore -}; - -/* Key types processed even in raw modes */ - -#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT)) - -typedef void (*void_fnp)(void); -typedef void (void_fn)(void); - -static void show_mem(void) -{ -} -static void show_state(void) -{ -} - -static void_fn do_null, enter, show_ptregs, send_intr, lastcons, caps_toggle, - num, hold, scroll_forw, scroll_back, caps_on, compose, - SAK, decr_console, incr_console, spawn_console, bare_num; - -static void_fnp spec_fn_table[] = { - do_null, enter, show_ptregs, show_mem, - show_state, send_intr, lastcons, caps_toggle, - num, hold, scroll_forw, scroll_back, - bsp_reset, caps_on, compose, SAK, - decr_console, incr_console, spawn_console, bare_num -}; - -#define SPECIALS_ALLOWED_IN_RAW_MODE (1 << KVAL(K_SAK)) - -/* maximum values each key_handler can handle */ -const int max_vals[] = { - 255, SIZE(func_table) - 1, SIZE(spec_fn_table) - 1, NR_PAD - 1, - NR_DEAD - 1, 255, 3, NR_SHIFT - 1, - 255, NR_ASCII - 1, NR_LOCK - 1, 255, - NR_LOCK - 1, 255 -}; - -const int NR_TYPES = SIZE(max_vals); - -/* N.B. drivers/macintosh/mac_keyb.c needs to call put_queue */ -static void put_queue(int); -static unsigned char handle_diacr(unsigned char); - -#ifdef CONFIG_MAGIC_SYSRQ -static int sysrq_pressed; -#endif - -/* - * Many other routines do put_queue, but I think either - * they produce ASCII, or they produce some user-assigned - * string, and in both cases we might assume that it is - * in utf-8 already. - */ -static void to_utf8(ushort c) -{ - if (c < 0x80) - put_queue(c); /* 0******* */ - else if (c < 0x800) { - put_queue(0xc0 | (c >> 6)); /* 110***** 10****** */ - put_queue(0x80 | (c & 0x3f)); - } else { - put_queue(0xe0 | (c >> 12)); /* 1110**** 10****** 10****** */ - put_queue(0x80 | ((c >> 6) & 0x3f)); - put_queue(0x80 | (c & 0x3f)); - } - /* UTF-8 is defined for words of up to 31 bits, - but we need only 16 bits here */ -} - -/* - * Translation of escaped scancodes to keycodes. - * This is now user-settable (for machines were it makes sense). - */ - -int setkeycode(unsigned int scancode, unsigned int keycode) -{ - return kbd_setkeycode(scancode, keycode); -} - -int getkeycode(unsigned int scancode) -{ - return kbd_getkeycode(scancode); -} - -void handle_scancode(unsigned char scancode, int down) -{ - unsigned char keycode; - char up_flag = down ? 0 : 0200; - char raw_mode; - - mark_bh(CONSOLE_BH); - -#if 0 - tty = ttytab? ttytab[fg_console]: NULL; - if (tty && (!tty->driver_data)) { - /* - * We touch the tty structure via the the ttytab array - * without knowing whether or not tty is open, which - * is inherently dangerous. We currently rely on that - * fact that console_open sets tty->driver_data when - * it opens it, and clears it when it closes it. - */ - tty = NULL; - } -#endif - - kbd = kbd_table + fg_console; - if ((raw_mode = (kbd->kbdmode == VC_RAW))) { - put_queue(scancode | up_flag); - /* we do not return yet, because we want to maintain - the key_down array, so that we have the correct - values when finishing RAW mode or when changing VT's */ - } - - /* - * Convert scancode to keycode - */ - if (!kbd_translate(scancode, &keycode, raw_mode)) - return; - - /* - * At this point the variable `keycode' contains the keycode. - * Note: the keycode must not be 0 (++Geert: on m68k 0 is valid). - * We keep track of the up/down status of the key, and - * return the keycode if in MEDIUMRAW mode. - */ - - if (up_flag) { - rep = 0; - if(!kbd_test_and_clear_bit(keycode, key_down)) - up_flag = kbd_unexpected_up(keycode); - } else - rep = kbd_test_and_set_bit(keycode, key_down); - -#ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */ - if (keycode == SYSRQ_KEY) { - sysrq_pressed = !up_flag; - return; - } else if (sysrq_pressed) { - if (!up_flag && sysrq_enabled) - handle_sysrq(kbd_sysrq_xlate[keycode], kbd_pt_regs, kbd, tty); - return; - } -#endif - - if (kbd->kbdmode == VC_MEDIUMRAW) { - /* soon keycodes will require more than one byte */ - put_queue(keycode + up_flag); - raw_mode = 1; /* Most key classes will be ignored */ - } - /* - * Small change in philosophy: earlier we defined repetition by - * rep = keycode == prev_keycode; - * prev_keycode = keycode; - * but now by the fact that the depressed key was down already. - * Does this ever make a difference? Yes. - */ - - /* - * Repeat a key only if the input buffers are empty or the - * characters get echoed locally. This makes key repeat usable - * with slow applications and under heavy loads. - */ - if (!rep || vc_kbd_mode(kbd,VC_REPEAT) ) { -/* - || (vc_kbd_mode(kbd,VC_REPEAT) && tty && - (L_ECHO(tty) || (tty->driver.chars_in_buffer(tty) == 0)))) { -*/ - u_short keysym; - u_char type; - - /* the XOR below used to be an OR */ - int shift_final = shift_state ^ kbd->lockstate ^ kbd->slockstate; - ushort *key_map = key_maps[shift_final]; - - if (key_map != NULL) { - keysym = key_map[keycode]; - type = KTYP(keysym); - - if (type >= 0xf0) { - type -= 0xf0; - if (raw_mode && ! (TYPES_ALLOWED_IN_RAW_MODE & (1 << type))) - return; - if (type == KT_LETTER) { - type = KT_LATIN; - if (vc_kbd_led(kbd, VC_CAPSLOCK)) { - key_map = key_maps[shift_final ^ (1<slockstate = 0; - - } else { - /* maybe only if (kbd->kbdmode == VC_UNICODE) ? */ - if (!up_flag && !raw_mode) - to_utf8(keysym); - } - } else { - /* maybe beep? */ - /* we have at least to update shift_state */ -#if 1 /* how? two almost equivalent choices follow */ - compute_shiftstate(); -#else - keysym = U(plain_map[keycode]); - type = KTYP(keysym); - if (type == KT_SHIFT) - (*key_handler[type])(keysym & 0xff, up_flag); -#endif - } - } -} - -static void ( *driver_input_handler_kbd )( void *, unsigned short, unsigned long ) = 0; -/* - */ -void kbd_set_driver_handler( - void ( *handler )( void *, unsigned short, unsigned long ) -) -{ - driver_input_handler_kbd = handler; -} - -static void put_queue(int ch) -{ - if ( driver_input_handler_kbd ) { - driver_input_handler_kbd( ( void *)kbd, (unsigned short)ch, 0 ); - } else { - add_to_queue( ch ); - } -} - -static void puts_queue(char *cp) -{ - while (*cp) { - put_queue( *cp ); - cp++; - } -} - -static void applkey(int key, char mode) -{ - static char buf[] = { 0x1b, 'O', 0x00, 0x00 }; - - buf[1] = (mode ? 'O' : '['); - buf[2] = key; - puts_queue(buf); -} - -static void enter(void) -{ - if (diacr) { - put_queue(diacr); - diacr = 0; - } - put_queue(13); - - if (vc_kbd_mode(kbd,VC_CRLF)) - put_queue(10); -} - -static void caps_toggle(void) -{ - if (rep) - return; - chg_vc_kbd_led(kbd, VC_CAPSLOCK); -} - -static void caps_on(void) -{ - if (rep) - return; - set_vc_kbd_led(kbd, VC_CAPSLOCK); -} - -static void show_ptregs(void) -{ -} - -static void hold(void) -{ - if (rep ) - return; - chg_vc_kbd_led(kbd, VC_SCROLLOCK ); -} - -static void num(void) -{ - if (vc_kbd_mode(kbd,VC_APPLIC)) - applkey('P', 1); - else - bare_num(); -} - -/* - * Bind this to Shift-NumLock if you work in application keypad mode - * but want to be able to change the NumLock flag. - * Bind this to NumLock if you prefer that the NumLock key always - * changes the NumLock flag. - */ -static void bare_num(void) -{ - if (!rep) - chg_vc_kbd_led(kbd,VC_NUMLOCK); -} - -static void lastcons(void) -{ -} - -static void decr_console(void) -{ -} - -static void incr_console(void) -{ -} - -static void send_intr(void) -{ -} - -static void scroll_forw(void) -{ -} - -static void scroll_back(void) -{ -} - -static void compose(void) -{ - dead_key_next = 1; -} - -int spawnpid, spawnsig; - -static void spawn_console(void) -{ -} - -static void SAK(void) -{ -} - -static void do_ignore(unsigned char value, char up_flag) -{ -} - -static void do_null() -{ - compute_shiftstate(); -} - -static void do_spec(unsigned char value, char up_flag) -{ - if (up_flag) - return; - if (value >= SIZE(spec_fn_table)) - return; - - if ((kbd->kbdmode == VC_RAW || kbd->kbdmode == VC_MEDIUMRAW) && - !(SPECIALS_ALLOWED_IN_RAW_MODE & (1 << value))) - return; - - spec_fn_table[value](); -} - -static void do_lowercase(unsigned char value, char up_flag) -{ -} - -static void do_self(unsigned char value, char up_flag) -{ - if (up_flag) - return; /* no action, if this is a key release */ - - if (diacr) - value = handle_diacr(value); - - if (dead_key_next) { - dead_key_next = 0; - diacr = value; - return; - } - put_queue(value); -} - -#define A_GRAVE '`' -#define A_ACUTE '\'' -#define A_CFLEX '^' -#define A_TILDE '~' -#define A_DIAER '"' -#define A_CEDIL ',' -static unsigned char ret_diacr[NR_DEAD] = - {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER, A_CEDIL }; - -/* Obsolete - for backwards compatibility only */ -static void do_dead(unsigned char value, char up_flag) -{ - value = ret_diacr[value]; - printk( " do_dead( %X ) ", value ); - do_dead2(value,up_flag); -} - -/* - * Handle dead key. Note that we now may have several - * dead keys modifying the same character. Very useful - * for Vietnamese. - */ -static void do_dead2(unsigned char value, char up_flag) -{ - if (up_flag) - return; - diacr = (diacr ? handle_diacr(value) : value); -} - -/* - * We have a combining character DIACR here, followed by the character CH. - * If the combination occurs in the table, return the corresponding value. - * Otherwise, if CH is a space or equals DIACR, return DIACR. - * Otherwise, conclude that DIACR was not combining after all, - * queue it and return CH. - */ -unsigned char handle_diacr(unsigned char ch) -{ - int d = diacr; - int i; - - diacr = 0; - - for (i = 0; i < accent_table_size; i++) { - if (accent_table[i].diacr == d && accent_table[i].base == ch) - return accent_table[i].result; - } - if (ch == ' ' || ch == d) - return d; - - put_queue(d); - return ch; -} - -static void do_cons(unsigned char value, char up_flag) -{ - if (up_flag) - return; -} - -static void do_fn(unsigned char value, char up_flag) -{ - if (up_flag) - return; - - if (value < SIZE(func_table)) { - if (func_table[value]) - puts_queue(func_table[value]); - } else - printk( "do_fn called with value=%d\n", value); -} - -static void do_pad(unsigned char value, char up_flag) -{ - static const char *pad_chars = "0123456789+-*/\015,.?()"; - static const char *app_map = "pqrstuvwxylSRQMnnmPQ"; - - if (up_flag) - return; /* no action, if this is a key release */ - - /* kludge... shift forces cursor/number keys */ - if (vc_kbd_mode(kbd,VC_APPLIC) && !k_down[KG_SHIFT]) { - applkey(app_map[value], 1); - return; - } - if (!vc_kbd_led(kbd,VC_NUMLOCK)) - switch (value) { - case KVAL(K_PCOMMA): - case KVAL(K_PDOT): - do_fn(KVAL(K_REMOVE), 0); - return; - case KVAL(K_P0): - do_fn(KVAL(K_INSERT), 0); - return; - case KVAL(K_P1): - do_fn(KVAL(K_SELECT), 0); - return; - case KVAL(K_P2): - do_cur(KVAL(K_DOWN), 0); - return; - case KVAL(K_P3): - do_fn(KVAL(K_PGDN), 0); - return; - case KVAL(K_P4): - do_cur(KVAL(K_LEFT), 0); - return; - case KVAL(K_P6): - do_cur(KVAL(K_RIGHT), 0); - return; - case KVAL(K_P7): - do_fn(KVAL(K_FIND), 0); - return; - case KVAL(K_P8): - do_cur(KVAL(K_UP), 0); - return; - case KVAL(K_P9): - do_fn(KVAL(K_PGUP), 0); - return; - case KVAL(K_P5): - applkey('G', vc_kbd_mode(kbd, VC_APPLIC)); - return; - } - - put_queue(pad_chars[value]); - - if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF)) - put_queue(10); - -} - -static void do_cur(unsigned char value, char up_flag) -{ - static const char *cur_chars = "BDCA"; - if (up_flag) - return; - - applkey(cur_chars[value], vc_kbd_mode(kbd,VC_CKMODE)); -} - -static void do_shift(unsigned char value, char up_flag) -{ - int old_state = shift_state; - - if (rep) - return; - - /* Mimic typewriter: - a CapsShift key acts like Shift but undoes CapsLock */ - if (value == KVAL(K_CAPSSHIFT)) { - value = KVAL(K_SHIFT); - if (!up_flag) - clr_vc_kbd_led(kbd, VC_CAPSLOCK); - } - - if (up_flag) { - /* handle the case that two shift or control - keys are depressed simultaneously */ - if (k_down[value]) - k_down[value]--; - } else - k_down[value]++; - - if (k_down[value]) - shift_state |= (1 << value); - else - shift_state &= ~ (1 << value); - - /* kludge */ - if (up_flag && shift_state != old_state && npadch != -1) { - if (kbd->kbdmode == VC_UNICODE) - to_utf8(npadch & 0xffff); - else - put_queue(npadch & 0xff); - npadch = -1; - } -} - -/* called after returning from RAW mode or when changing consoles - - recompute k_down[] and shift_state from key_down[] */ -/* maybe called when keymap is undefined, so that shiftkey release is seen */ -void compute_shiftstate(void) -{ - int i, j, k, sym, val; - - shift_state = 0; - for(i=0; i < SIZE(k_down); i++) - k_down[i] = 0; - - for(i=0; i < SIZE(key_down); i++) - if(atomic_load(key_down + i)) { /* skip this word if not a single bit on */ - k = i*KBD_BITS_PER_ELEMENT; - for(j=0; jledmode = LED_SHOW_IOCTL; - } else - ; - kbd->ledmode = LED_SHOW_FLAGS; - set_leds(); -} - -static struct ledptr { - unsigned int *addr; - unsigned int mask; - unsigned char valid:1; -} ledptrs[3]; - -void register_leds( - int console, - unsigned int led, - unsigned int *addr, - unsigned int mask -) -{ - struct kbd_struct *kbd = kbd_table + console; - - if (led < 3) { - ledptrs[led].addr = addr; - ledptrs[led].mask = mask; - ledptrs[led].valid = 1; - kbd->ledmode = LED_SHOW_MEM; - } else - kbd->ledmode = LED_SHOW_FLAGS; -} - -static inline unsigned char getleds(void) -{ - - struct kbd_struct *kbd = kbd_table + fg_console; - - unsigned char leds; - - if (kbd->ledmode == LED_SHOW_IOCTL) - return ledioctl; - leds = kbd->ledflagstate; - if (kbd->ledmode == LED_SHOW_MEM) { - if (ledptrs[0].valid) { - if (*ledptrs[0].addr & ledptrs[0].mask) - leds |= 1; - else - leds &= ~1; - } - if (ledptrs[1].valid) { - if (*ledptrs[1].addr & ledptrs[1].mask) - leds |= 2; - else - leds &= ~2; - } - if (ledptrs[2].valid) { - if (*ledptrs[2].addr & ledptrs[2].mask) - leds |= 4; - else - leds &= ~4; - } - } - return leds; -} - -/* - * This routine is the bottom half of the keyboard interrupt - * routine, and runs with all interrupts enabled. It does - * console changing, led setting and copy_to_cooked, which can - * take a reasonably long time. - * - * Aside from timing (which isn't really that important for - * keyboard interrupts as they happen often), using the software - * interrupt routines for this thing allows us to easily mask - * this when we don't want any of the above to happen. Not yet - * used, but this allows for easy and efficient race-condition - * prevention later on. - */ -static void kbd_bh(void) -{ - unsigned char leds = getleds(); - if (leds != ledstate) { - ledstate = leds; - kbd_leds(leds); - } -} - -void set_leds(void) -{ - kbd_bh(); -} - -int kbd_init(void) -{ - - int i; - struct kbd_struct kbd0; - kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS; - kbd0.ledmode = LED_SHOW_MEM; - kbd0.lockstate = KBD_DEFLOCK; - kbd0.slockstate = 0; - kbd0.modeflags = KBD_DEFMODE; - kbd0.kbdmode = VC_XLATE; - - for (i = 0 ; i < MAX_NR_CONSOLES ; i++) - kbd_table[i] = kbd0; - - kbd_init_hw(); - mark_bh(KEYBOARD_BH); - return 0; -} diff --git a/c/src/lib/libbsp/i386/pc386/console/outch.c b/c/src/lib/libbsp/i386/pc386/console/outch.c deleted file mode 100644 index 90ffedf250..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/outch.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * outch.c - This file contains code for displaying characters - * on the console uisng information that should be - * maintained by the BIOS in its data Area. - * - * Copyright (C) 1998 Eric Valette (valette@crf.canon.fr) - * Canon Centre Recherche France. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - * Till Straumann , 2003/9: - * - added handling of basic escape sequences (cursor movement - * and erasing; just enough for the line editor 'libtecla' to - * work...) - */ - -#include - -#include -#include - -#include - -extern void wr_cursor(int, unsigned short); - -#define TAB_SPACE 4 -static unsigned short *bitMapBaseAddr; -static unsigned short ioCrtBaseAddr; -static unsigned short maxCol; -static unsigned short maxRow; -static unsigned char row; -static unsigned char column; -static unsigned short attribute; -static unsigned int nLines; - -static void -scroll(void) -{ - int i, j; /* Counters */ - unsigned short *pt_scroll, *pt_bitmap; /* Pointers on the bit-map */ - - pt_bitmap = bitMapBaseAddr; - j = 0; - pt_bitmap = pt_bitmap + j; - pt_scroll = pt_bitmap + maxCol; - for (i = j; i < (maxRow - 1) * maxCol; i++) { - *pt_bitmap++ = *pt_scroll++; - } - - /* - * Blank characters are displayed on the last line. - */ - for (i = 0; i < maxCol; i++) { - *pt_bitmap++ = (short) (' ' | attribute); - } -} - -static void -doCRNL(int cr, int nl) -{ - if (nl) { - if (++row == maxRow) { - scroll(); /* Scroll the screen now */ - row = maxRow - 1; - } - nLines++; - } - if (cr) - column = 0; - /* Move cursor on the next location */ - if (cr || nl) - wr_cursor(row * maxCol + column, ioCrtBaseAddr); -} - -int (*videoHook)(char, int *)=0; - -static void -advanceCursor(void) -{ - if (++column == maxCol) - doCRNL(1,1); - else - wr_cursor(row * maxCol + column, ioCrtBaseAddr); -} - -static void -gotorc(int r, int c) -{ - column = c; - row = r; - - wr_cursor(row * maxCol + column, ioCrtBaseAddr); -} - -#define ESC ((char)27) -/* erase current location without moving the cursor */ -#define BLANK ((char)0x7f) - -static void -videoPutChar(char car) -{ - unsigned short *pt_bitmap = bitMapBaseAddr + row * maxCol + column; - - switch (car) { - case '\b': { - if (column) column--; - /* Move cursor on the previous location */ - wr_cursor(row * maxCol + column, ioCrtBaseAddr); - return; - } - case '\t': { - int i; - - i = TAB_SPACE - (column & (TAB_SPACE - 1)); - column += i; - if (column >= maxCol) { - doCRNL(1,1); - return; - } - while (i--) *pt_bitmap++ = ' ' | attribute; - wr_cursor(row * maxCol + column, ioCrtBaseAddr); - return; - } - case '\n': { - doCRNL(0,1); - return; - } - case 7: { /* Bell code must be inserted here */ - return; - } - case '\r' : { - doCRNL(1,0); - return; - } - case BLANK: { - *pt_bitmap = ' ' | attribute; - /* DONT move the cursor... */ - return; - } - default: { - *pt_bitmap = (unsigned char)car | attribute; - advanceCursor(); - return; - } - } -} - -/* trivial state machine to handle escape sequences: - * - * --------------------------------- - * | | - * | | - * KEY: esc V [ DCABHKJ esc | - * STATE: 0 -----> 27 -----> '[' ----------> -1 ----- - * ^\ \ \ \ - * KEY: | \other \ other \ other \ other - * <------------------------------------- - * - * in state '-1', the DCABHKJ cases are handled - * - * (cursor motion and screen clearing) - */ - -#define DONE (-1) - -static int -handleEscape(int oldState, char car) -{ -int rval = 0; -int ro,co; - - switch ( oldState ) { - case DONE: /* means the previous char terminated an ESC sequence... */ - case 0: - if ( 27 == car ) { - rval = 27; /* START of an ESC sequence */ - } - break; - - case 27: - if ( '[' == car ) { - rval = car; /* received ESC '[', so far */ - } else { - /* dump suppressed 'ESC'; outch will append the char */ - videoPutChar(ESC); - } - break; - - case '[': - /* handle 'ESC' '[' sequences here */ - ro = row; co = column; - rval = DONE; /* done */ - - switch (car) { - case 'D': /* left */ - if ( co > 0 ) co--; - break; - case 'C': /* right */ - if ( co < maxCol ) co++; - break; - case 'A': /* up */ - if ( ro > 0 ) ro--; - break; - case 'B': /* down */ - if ( ro < maxRow ) ro++; - break; - case 'H': /* home */ - ro = co = 0; - break; - case 'K': /* clear to end of line */ - while ( column < maxCol - 1 ) - videoPutChar(' '); - videoPutChar(BLANK); - break; - case 'J': /* clear to end of screen */ - while ( ((row < maxRow-1) || (column < maxCol-1)) ) - videoPutChar(' '); - videoPutChar(BLANK); - break; - default: - videoPutChar(ESC); - videoPutChar('['); - /* DONT move the cursor */ - ro = -1; - rval = 0; - break; - } - /* reset cursor */ - if ( ro >= 0) - gotorc(ro,co); - - default: - break; - - } - - return rval; -} - -static void -clear_screen(void) -{ - int i,j; - - for (j = 0; j <= maxRow; j++) { - for (i = 0; i <= maxCol; i++) { - videoPutChar(' '); - } - } - column = 0; - row = 0; -} - -/*-------------------------------------------------------------------------+ -| Function: _IBMPC_outch -| Description: Higher level (console) interface to consPutc. -| Global Variables: None. -| Arguments: c - character to write to console. -| Returns: Nothing. -+--------------------------------------------------------------------------*/ -void -_IBMPC_outch(char c) -{ -static int escaped = 0; - - if ( ! (escaped = handleEscape(escaped, c)) ) { - if ( '\n' == c ) - videoPutChar('\r'); - videoPutChar(c); - } -} /* _IBMPC_outch */ - -/*-------------------------------------------------------------------------+ -| Function: _IBMPC_initVideo -| Description: Video system initialization. Hook for any early setup. -| Global Variables: bitMapBaseAddr, ioCrtBaseAddr, maxCol, maxRow, row -| column, attribute, nLines; -| Arguments: None. -| Returns: Nothing. -+--------------------------------------------------------------------------*/ -void -_IBMPC_initVideo(void) -{ - unsigned char* pt = (unsigned char*) (VIDEO_MODE_ADDR); - - if (*pt == VGAMODE7) { - bitMapBaseAddr = (unsigned short*) V_MONO; - } - else { - bitMapBaseAddr = (unsigned short*) V_COLOR; - } - ioCrtBaseAddr = *(unsigned short*) DISPLAY_CRT_BASE_IO_ADDR; - maxCol = * (unsigned short*) NB_MAX_COL_ADDR; - maxRow = * (unsigned char*) NB_MAX_ROW_ADDR; - column = 0; - row = 0; - attribute = ((BLACK << 4) | WHITE)<<8; - nLines = 0; - clear_screen(); -#ifdef DEBUG_EARLY_STAGE - printk("bitMapBaseAddr = %X, display controller base IO = %X\n", - (unsigned) bitMapBaseAddr, - (unsigned) ioCrtBaseAddr); - videoPrintf("maxCol = %d, maxRow = %d\n", (unsigned) maxCol, (unsigned) maxRow); -#endif -} /* _IBMPC_initVideo */ - -/* for old DOS compatibility n-curses type of applications */ -void gotoxy( int x, int y ); -int whereX( void ); -int whereY( void ); - -void gotoxy( int x, int y ) -{ - gotorc(y,x); -} - -int whereX( void ) -{ - return row; -} - -int whereY( void ) -{ - return column; -} diff --git a/c/src/lib/libbsp/i386/pc386/console/pc_keyb.c b/c/src/lib/libbsp/i386/pc386/console/pc_keyb.c deleted file mode 100644 index b6f0eb216a..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/pc_keyb.c +++ /dev/null @@ -1,627 +0,0 @@ -/* - * linux/drivers/char/pc_keyb.c - * - * Separation of the PC low-level part by Geert Uytterhoeven, May 1997 - * See keyboard.c for the whole history. - * - * Major cleanup by Martin Mares, May 1997 - * - * Combined the keyboard and PS/2 mouse handling into one file, - * because they share the same hardware. - * Johan Myreen 1998-10-08. - * - * Code fixes to handle mouse ACKs properly. - * C. Scott Ananian 1999-01-29. - * - * Ported to RTEMS by Rosimildo da Silva - */ - -#include -#include -#include - -#include -#include -#include "i386kbd.h" - -static unsigned char handle_kbd_event(void); -static void kbd_write_command_w(int data); -static void kbd_write_output_w(int data); - -/* Some configuration switches are present in the include file... */ - -/* Simple translation table for the SysRq keys */ - -#ifdef CONFIG_MAGIC_SYSRQ -unsigned char pckbd_sysrq_xlate[128] = - "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */ - "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */ - "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */ - "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */ - "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */ - "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ - "\r\000/"; /* 0x60 - 0x6f */ -#endif - -/* used only by send_data - set by keyboard_interrupt */ -static volatile unsigned char reply_expected = 0; -static volatile unsigned char acknowledge = 0; -static volatile unsigned char resend = 0; - -/* - * Translation of escaped scancodes to keycodes. - * This is now user-settable. - * The keycodes 1-88,96-111,119 are fairly standard, and - * should probably not be changed - changing might confuse X. - * X also interprets scancode 0x5d (KEY_Begin). - * - * For 1-88 keycode equals scancode. - */ - -#define E0_KPENTER 96 -#define E0_RCTRL 97 -#define E0_KPSLASH 98 -#define E0_PRSCR 99 -#define E0_RALT 100 -#define E0_BREAK 101 /* (control-pause) */ -#define E0_HOME 102 -#define E0_UP 103 -#define E0_PGUP 104 -#define E0_LEFT 105 -#define E0_RIGHT 106 -#define E0_END 107 -#define E0_DOWN 108 -#define E0_PGDN 109 -#define E0_INS 110 -#define E0_DEL 111 - -#define E1_PAUSE 119 - -/* - * The keycodes below are randomly located in 89-95,112-118,120-127. - * They could be thrown away (and all occurrences below replaced by 0), - * but that would force many users to use the `setkeycodes' utility, where - * they needed not before. It does not matter that there are duplicates, as - * long as no duplication occurs for any single keyboard. - */ -#define SC_LIM 89 - -#define FOCUS_PF1 85 /* actual code! */ -#define FOCUS_PF2 89 -#define FOCUS_PF3 90 -#define FOCUS_PF4 91 -#define FOCUS_PF5 92 -#define FOCUS_PF6 93 -#define FOCUS_PF7 94 -#define FOCUS_PF8 95 -#define FOCUS_PF9 120 -#define FOCUS_PF10 121 -#define FOCUS_PF11 122 -#define FOCUS_PF12 123 - -#define JAP_86 124 -/* tfj@olivia.ping.dk: - * The four keys are located over the numeric keypad, and are - * labelled A1-A4. It's an rc930 keyboard, from - * Regnecentralen/RC International, Now ICL. - * Scancodes: 59, 5a, 5b, 5c. - */ -#define RGN1 124 -#define RGN2 125 -#define RGN3 126 -#define RGN4 127 - -static unsigned char high_keys[128 - SC_LIM] = { - RGN1, RGN2, RGN3, RGN4, 0, 0, 0, /* 0x59-0x5f */ - 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */ - 0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12, /* 0x68-0x6f */ - 0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3, /* 0x70-0x77 */ - FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7, /* 0x78-0x7b */ - FOCUS_PF8, JAP_86, FOCUS_PF10, 0 /* 0x7c-0x7f */ -}; - -/* BTC */ -#define E0_MACRO 112 -/* LK450 */ -#define E0_F13 113 -#define E0_F14 114 -#define E0_HELP 115 -#define E0_DO 116 -#define E0_F17 117 -#define E0_KPMINPLUS 118 -/* - * My OmniKey generates e0 4c for the "OMNI" key and the - * right alt key does nada. [kkoller@nyx10.cs.du.edu] - */ -#define E0_OK 124 -/* - * New microsoft keyboard is rumoured to have - * e0 5b (left window button), e0 5c (right window button), - * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU] - * [or: Windows_L, Windows_R, TaskMan] - */ -#define E0_MSLW 125 -#define E0_MSRW 126 -#define E0_MSTM 127 - -static unsigned char e0_keys[128] = { - 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */ - 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */ - 0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0, /* 0x18-0x1f */ - 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */ - 0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR, /* 0x30-0x37 */ - E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP, /* 0x38-0x3f */ - E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME, /* 0x40-0x47 */ - E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */ - E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0, /* 0x50-0x57 */ - 0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0, /* 0x58-0x5f */ - 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */ - 0, 0, 0, 0, 0, 0, 0, E0_MACRO, /* 0x68-0x6f */ - 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */ - 0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */ -}; - -static void mdelay( unsigned long t ) -{ - Wait_X_ms( t ); -} - -int pckbd_setkeycode(unsigned int scancode, unsigned int keycode) -{ - if (scancode < SC_LIM || scancode > 255 || keycode > 127) - return -EINVAL; - if (scancode < 128) - high_keys[scancode - SC_LIM] = keycode; - else - e0_keys[scancode - 128] = keycode; - return 0; -} - -int pckbd_getkeycode(unsigned int scancode) -{ - return - (scancode < SC_LIM || scancode > 255) ? -EINVAL : - (scancode < 128) ? high_keys[scancode - SC_LIM] : - e0_keys[scancode - 128]; -} - -static int do_acknowledge(unsigned char scancode) -{ - if (reply_expected) { - /* Unfortunately, we must recognise these codes only if we know they - * are known to be valid (i.e., after sending a command), because there - * are some brain-damaged keyboards (yes, FOCUS 9000 again) which have - * keys with such codes :( - */ - if (scancode == KBD_REPLY_ACK) { - acknowledge = 1; - reply_expected = 0; - return 0; - } else if (scancode == KBD_REPLY_RESEND) { - resend = 1; - reply_expected = 0; - return 0; - } - /* Should not happen... */ - printk( "keyboard reply expected - got %02x\n", scancode); - } - return 1; -} - -int pckbd_translate(unsigned char scancode, unsigned char *keycode, - char raw_mode) -{ - static int prev_scancode = 0; - - /* special prefix scancodes.. */ - if (scancode == 0xe0 || scancode == 0xe1) { - prev_scancode = scancode; - return 0; - } - - /* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */ - if (scancode == 0x00 || scancode == 0xff) { - prev_scancode = 0; - return 0; - } - - scancode &= 0x7f; - - if (prev_scancode) { - /* - * usually it will be 0xe0, but a Pause key generates - * e1 1d 45 e1 9d c5 when pressed, and nothing when released - */ - if (prev_scancode != 0xe0) { - if (prev_scancode == 0xe1 && scancode == 0x1d) { - prev_scancode = 0x100; - return 0; - } else if (prev_scancode == 0x100 && scancode == 0x45) { - *keycode = E1_PAUSE; - prev_scancode = 0; - } else { -#ifdef KBD_REPORT_UNKN - if (!raw_mode) - printk("keyboard: unknown e1 escape sequence\n"); -#endif - prev_scancode = 0; - return 0; - } - } else { - prev_scancode = 0; - /* - * The keyboard maintains its own internal caps lock and - * num lock statuses. In caps lock mode E0 AA precedes make - * code and E0 2A follows break code. In num lock mode, - * E0 2A precedes make code and E0 AA follows break code. - * We do our own book-keeping, so we will just ignore these. - */ - /* - * For my keyboard there is no caps lock mode, but there are - * both Shift-L and Shift-R modes. The former mode generates - * E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs. - * So, we should also ignore the latter. - aeb@cwi.nl - */ - if (scancode == 0x2a || scancode == 0x36) - return 0; - - if (e0_keys[scancode]) - *keycode = e0_keys[scancode]; - else { -#ifdef KBD_REPORT_UNKN - if (!raw_mode) - printk( "keyboard: unknown scancode e0 %02x\n", - scancode); -#endif - return 0; - } - } - } else if (scancode >= SC_LIM) { - /* This happens with the FOCUS 9000 keyboard - Its keys PF1..PF12 are reported to generate - 55 73 77 78 79 7a 7b 7c 74 7e 6d 6f - Moreover, unless repeated, they do not generate - key-down events, so we have to zero up_flag below */ - /* Also, Japanese 86/106 keyboards are reported to - generate 0x73 and 0x7d for \ - and \ | respectively. */ - /* Also, some Brazilian keyboard is reported to produce - 0x73 and 0x7e for \ ? and KP-dot, respectively. */ - - *keycode = high_keys[scancode - SC_LIM]; - if (!*keycode) { - if (!raw_mode) { -#ifdef KBD_REPORT_UNKN - printk( "keyboard: unrecognized scancode (%02x)" - " - ignored\n", scancode); -#endif - } - return 0; - } - } else - *keycode = scancode; - return 1; -} - -char pckbd_unexpected_up(unsigned char keycode) -{ - /* unexpected, but this can happen: maybe this was a key release for a - FOCUS 9000 PF key; if we want to see it, we have to clear up_flag */ - if (keycode >= SC_LIM || keycode == 85) - return 0; - else - return 0200; -} - -static void kb_wait(void) -{ - unsigned long timeout = KBC_TIMEOUT; - - do { - /* - * "handle_kbd_event()" will handle any incoming events - * while we wait - keypresses or mouse movement. - */ - unsigned char status = handle_kbd_event(); - - if (! (status & KBD_STAT_IBF)) - return; - mdelay(1); - timeout--; - } while (timeout); -#ifdef KBD_REPORT_TIMEOUTS - printk( "Keyboard timed out[1]\n"); -#endif -} - -/* - * This reads the keyboard status port, and does the - * appropriate action. - * - * It requires that we hold the keyboard controller - * spinlock. - */ -static unsigned char handle_kbd_event(void) -{ - unsigned char status = kbd_read_status(); - unsigned int work = 10000; - - while (status & KBD_STAT_OBF) { - unsigned char scancode; - - scancode = kbd_read_input(); - if (status & KBD_STAT_MOUSE_OBF) { -#if 0 - handle_mouse_event(scancode); -#endif - } else { - if (do_acknowledge(scancode)) - handle_scancode(scancode, !(scancode & 0x80)); - mark_bh(KEYBOARD_BH); - } - - status = kbd_read_status(); - - if(!work--) - { - printk( "pc_keyb: controller jammed (0x%02X).\n", status); - break; - } - return status; - } - - /* - * the commands to set the leds for some reason, returns 0x14, 0x16 - * and I am intepreting as an ACK, because the original code from - * Linux was timeing out here... - */ - acknowledge = 1; - reply_expected = 0; - resend = 0; - return status; -} - -void keyboard_interrupt(void *unused) -{ - handle_kbd_event(); -} - -/* - * send_data sends a character to the keyboard and waits - * for an acknowledge, possibly retrying if asked to. Returns - * the success status. - * - * Don't use 'jiffies', so that we don't depend on interrupts - */ -static int send_data(unsigned char data) -{ - int retries = 3; - - do { - unsigned long timeout = KBD_TIMEOUT; - - acknowledge = 0; /* Set by interrupt routine on receipt of ACK. */ - resend = 0; - reply_expected = 1; - kbd_write_output_w(data); - for (;;) { - if (acknowledge) - return 1; - if (resend) - break; - mdelay(1); - if (!--timeout) { -#ifdef KBD_REPORT_TIMEOUTS - printk("Keyboard timeout[2]\n"); -#endif - return 0; - } - } - } while (retries-- > 0); -#ifdef KBD_REPORT_TIMEOUTS - printk( "keyboard: Too many NACKs -- noisy kbd cable?\n"); -#endif - return 0; -} - -void pckbd_leds(unsigned char leds) -{ - if (!send_data(KBD_CMD_SET_LEDS) || !send_data(leds)) - send_data(KBD_CMD_ENABLE); /* re-enable kbd if any errors */ -} - -/* - * In case we run on a non-x86 hardware we need to initialize both the - * keyboard controller and the keyboard. On a x86, the BIOS will - * already have initialized them. - * - * Some x86 BIOSes do not correctly initialize the keyboard, so the - * "kbd-reset" command line options can be given to force a reset. - * [Ranger] - */ -#ifdef __i386__ - int kbd_startup_reset = 0; -#else - int kbd_startup_reset = 1; -#endif - -/* for "kbd-reset" cmdline param */ -void kbd_reset_setup(char *str, int *ints) -{ - kbd_startup_reset = 1; -} - -#define KBD_NO_DATA (-1) /* No data */ -#define KBD_BAD_DATA (-2) /* Parity or other error */ - -static int kbd_read_data(void) -{ - int retval = KBD_NO_DATA; - unsigned char status; - - status = kbd_read_status(); - if (status & KBD_STAT_OBF) { - unsigned char data = kbd_read_input(); - - retval = data; - if (status & (KBD_STAT_GTO | KBD_STAT_PERR)) - retval = KBD_BAD_DATA; - } - return retval; -} - -static void kbd_clear_input(void) -{ - int maxread = 100; /* Random number */ - - do { - if (kbd_read_data() == KBD_NO_DATA) - break; - } while (--maxread); -} - -static int kbd_wait_for_input(void) -{ - long timeout = KBD_INIT_TIMEOUT; - - do { - int retval = kbd_read_data(); - if (retval >= 0) - return retval; - mdelay(1); - } while (--timeout); - return -1; -} - -static void kbd_write_command_w(int data) -{ - kb_wait(); - kbd_write_command(data); -} - -static void kbd_write_output_w(int data) -{ - kb_wait(); - kbd_write_output(data); -} - -static char * initialize_kbd(void) -{ - int status; - - /* - * Test the keyboard interface. - * This seems to be the only way to get it going. - * If the test is successful a x55 is placed in the input buffer. - */ - kbd_write_command_w(KBD_CCMD_SELF_TEST); - if (kbd_wait_for_input() != 0x55) - return "Keyboard failed self test"; - - /* - * Perform a keyboard interface test. This causes the controller - * to test the keyboard clock and data lines. The results of the - * test are placed in the input buffer. - */ - kbd_write_command_w(KBD_CCMD_KBD_TEST); - if (kbd_wait_for_input() != 0x00) - return "Keyboard interface failed self test"; - - /* - * Enable the keyboard by allowing the keyboard clock to run. - */ - kbd_write_command_w(KBD_CCMD_KBD_ENABLE); - - /* - * Reset keyboard. If the read times out - * then the assumption is that no keyboard is - * plugged into the machine. - * This defaults the keyboard to scan-code set 2. - * - * Set up to try again if the keyboard asks for RESEND. - */ - do { - kbd_write_output_w(KBD_CMD_RESET); - status = kbd_wait_for_input(); - if (status == KBD_REPLY_ACK) - break; - if (status != KBD_REPLY_RESEND) - return "Keyboard reset failed, no ACK"; - } while (1); - - if (kbd_wait_for_input() != KBD_REPLY_POR) - return "Keyboard reset failed, no POR"; - - /* - * Set keyboard controller mode. During this, the keyboard should be - * in the disabled state. - * - * Set up to try again if the keyboard asks for RESEND. - */ - do { - kbd_write_output_w(KBD_CMD_DISABLE); - status = kbd_wait_for_input(); - if (status == KBD_REPLY_ACK) - break; - if (status != KBD_REPLY_RESEND) - return "Disable keyboard: no ACK"; - } while (1); - - kbd_write_command_w(KBD_CCMD_WRITE_MODE); - kbd_write_output_w(KBD_MODE_KBD_INT - | KBD_MODE_SYS - | KBD_MODE_DISABLE_MOUSE - | KBD_MODE_KCC); - - /* ibm powerpc portables need this to use scan-code set 1 -- Cort */ - kbd_write_command_w(KBD_CCMD_READ_MODE); - if (!(kbd_wait_for_input() & KBD_MODE_KCC)) { - /* - * If the controller does not support conversion, - * Set the keyboard to scan-code set 1. - */ - kbd_write_output_w(0xF0); - kbd_wait_for_input(); - kbd_write_output_w(0x01); - kbd_wait_for_input(); - } - - kbd_write_output_w(KBD_CMD_ENABLE); - if (kbd_wait_for_input() != KBD_REPLY_ACK) - return "Enable keyboard: no ACK"; - /* - * Finally, set the typematic rate to maximum. - */ - kbd_write_output_w(KBD_CMD_SET_RATE); - if (kbd_wait_for_input() != KBD_REPLY_ACK) - return "Set rate: no ACK"; - kbd_write_output_w(0x00); - if (kbd_wait_for_input() != KBD_REPLY_ACK) - return "Set rate: no ACK"; - return NULL; -} - -void pckbd_init_hw(void) -{ - /* kbd_request_region(); */ - - /* Flush any pending input. */ - kbd_clear_input(); - - if (kbd_startup_reset) { - char *msg = initialize_kbd(); - if (msg) - printk( "initialize_kbd: %s\n", msg); - } - -#if defined CONFIG_PSMOUSE - psaux_init(); -#endif - - /* Ok, finally allocate the IRQ, and off we go.. */ -#if 0 - kbd_request_irq( keyboard_interrupt ); -#endif - -} diff --git a/c/src/lib/libbsp/i386/pc386/console/printk_support.c b/c/src/lib/libbsp/i386/pc386/console/printk_support.c deleted file mode 100644 index f6ef656583..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/printk_support.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * @file - * - * @ingroup Console - * - * @brief printk support routines - * - * This file contains the required printk support. - */ - -/* - * COPYRIGHT (c) 1989-2012. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#if BSP_ENABLE_VGA - #include -#endif -#include -#include -#include -#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h" - -rtems_device_minor_number BSPPrintkPort = 0; - -void BSP_outch(char ch); -int BSP_inch(void); - -void BSP_outch(char ch) -{ - #if BSP_ENABLE_VGA - bool isVga = BSPPrintkPort == BSP_CONSOLE_VGA; - #else - bool isVga = false; - #endif - - if ( !isVga ) { - console_tbl *port = Console_Port_Tbl[BSPPrintkPort]; - if (port->pDeviceFns && port->pDeviceFns->deviceWritePolled) { - port->pDeviceFns->deviceWritePolled( BSPPrintkPort, ch ); - } - return; - } - - #if BSP_ENABLE_VGA - _IBMPC_outch( ch ); - #endif -} - -int BSP_inch(void) -{ - #if BSP_ENABLE_VGA - bool isVga = BSPPrintkPort == BSP_CONSOLE_VGA; - #else - bool isVga = false; - #endif - - int result = -1; - - if ( !isVga ) { - console_tbl *port = Console_Port_Tbl[BSPPrintkPort]; - if (port->pDeviceFns && port->pDeviceFns->deviceRead) { - do { - result = port->pDeviceFns->deviceRead( BSPPrintkPort ); - } while (result == -1); - return result; - } - } - - #if BSP_ENABLE_VGA - result = BSP_wait_polled_input(); - #endif - - return result; -} - -BSP_output_char_function_type BSP_output_char = BSP_outch; -BSP_polling_getchar_function_type BSP_poll_char = BSP_inch; diff --git a/c/src/lib/libbsp/i386/pc386/console/ps2_mouse.c b/c/src/lib/libbsp/i386/pc386/console/ps2_mouse.c deleted file mode 100644 index 6a3f8551b4..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/ps2_mouse.c +++ /dev/null @@ -1,562 +0,0 @@ -/* - * linux/drivers/char/pc_keyb.c - * Separation of the PC low-level part by Geert Uytterhoeven, May 1997 - * See keyboard.c for the whole history. - * Major cleanup by Martin Mares, May 1997 - * Combined the keyboard and PS/2 mouse handling into one file, - * because they share the same hardware. - * Johan Myreen 1998-10-08. - * Code fixes to handle mouse ACKs properly. - * C. Scott Ananian 1999-01-29. - * - * RTEMS port: by Rosimildo da Silva. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define INITIALIZE_MOUSE -/* Some configuration switches are present in the include file... */ -#include -#include "ps2_mouse.h" - -static void kbd_write_command_w(int data); -#if 0 -static void kbd_write_output_w(int data); -#endif - -static unsigned char handle_kbd_event(void); -static void ps2_set_driver_handler(int port, mouse_parser_enqueue_handler handler); - -/* used only by send_data - set by keyboard_interrupt */ -static volatile unsigned char reply_expected = 0; -static volatile unsigned char acknowledge = 0; -static volatile unsigned char resend = 0; - -/* - * PS/2 Auxiliary Device - */ -static int psaux_init(void); - -static struct aux_queue *queue; /* Mouse data buffer. */ -static int aux_count = 0; -/* used when we send commands to the mouse that expect an ACK. */ -static unsigned char mouse_reply_expected = 0; - -#define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT) -#define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT) -#define MAX_RETRIES 60 /* some aux operations take long time*/ - -static void ps2_mouse_interrupt(void *); -static mouse_parser_enqueue_handler driver_input_handler_ps2 = NULL; - -/* - * This routine sets the handler to handle the characters received - * from the serial port. - */ -static void ps2_set_driver_handler( - int port, - mouse_parser_enqueue_handler handler -) -{ - driver_input_handler_ps2 = handler; -} - -static void mdelay( unsigned long t ) -{ - Wait_X_ms( t ); -} - -static void* termios_ttyp_paux = NULL; - -/* - * Wait for keyboard controller input buffer to drain. - * - * Don't use 'jiffies' so that we don't depend on - * interrupts.. - * - * Quote from PS/2 System Reference Manual: - * - * "Address hex 0060 and address hex 0064 should be written only when - * the input-buffer-full bit and output-buffer-full bit in the - * Controller Status register are set 0." - */ - -static void kb_wait(void) -{ - unsigned long timeout = KBC_TIMEOUT; - - do { - /* - * "handle_kbd_event()" will handle any incoming events - * while we wait - keypresses or mouse movement. - */ - unsigned char status = handle_kbd_event(); - - if (! (status & KBD_STAT_IBF)) - return; - - mdelay(1); - timeout--; - } while (timeout); - - #ifdef KBD_REPORT_TIMEOUTS - printk( "Keyboard timed out[1]\n"); - #endif -} - -static int do_acknowledge(unsigned char scancode) -{ - if (reply_expected) { - - /* Unfortunately, we must recognise these codes only if we know they - * are known to be valid (i.e., after sending a command), because there - * are some brain-damaged keyboards (yes, FOCUS 9000 again) which have - * keys with such codes :( - */ - if (scancode == KBD_REPLY_ACK) { - acknowledge = 1; - reply_expected = 0; - return 0; - } else if (scancode == KBD_REPLY_RESEND) { - resend = 1; - reply_expected = 0; - return 0; - } - - /* Should not happen... */ - #if 0 - printk( "keyboard reply expected - got %02x\n", scancode); - #endif - } - return 1; -} - -static inline void handle_mouse_event(unsigned char scancode) -{ - if (mouse_reply_expected) { - if (scancode == AUX_ACK) { - mouse_reply_expected--; - return; - } - mouse_reply_expected = 0; - } - - if (aux_count) { - int head = queue->head; - queue->buf[head] = scancode; - head = (head + 1) & (AUX_BUF_SIZE-1); - if (head != queue->tail) { - queue->head = head; - } - - /* if the input queue is active, add to it */ - if( driver_input_handler_ps2 ) { - driver_input_handler_ps2( &scancode, 1 ); - } else { - /* post this byte to termios */ - rtems_termios_enqueue_raw_characters( termios_ttyp_paux, (char *)&scancode, 1 ); - } - } -} - -/* - * This reads the keyboard status port, and does the - * appropriate action. - * - * It requires that we hold the keyboard controller - * spinlock. - */ -static unsigned char handle_kbd_event(void) -{ - unsigned char status = kbd_read_status(); - unsigned int work = 10000; - - while (status & KBD_STAT_OBF) { - unsigned char scancode; - scancode = kbd_read_input(); - if (status & KBD_STAT_MOUSE_OBF) { - handle_mouse_event(scancode); - } else { - do_acknowledge(scancode); - printk("pc_keyb: %X ", scancode ); - } - status = kbd_read_status(); - if(!work--) { - printk("pc_keyb: controller jammed (0x%02X).\n", status); - break; - } - } - return status; -} - -static void ps2_mouse_interrupt(void * unused) -{ - handle_kbd_event(); -} - -static void kbd_write_command_w(int data) -{ - kb_wait(); - kbd_write_command(data); -} - -static void kbd_write_cmd(int cmd) -{ - kb_wait(); - kbd_write_command(KBD_CCMD_WRITE_MODE); - kb_wait(); - kbd_write_output(cmd); -} - -/* - * Check if this is a dual port controller. - */ -static int detect_auxiliary_port(void) -{ - int loops = 10; - int retval = 0; - - /* Put the value 0x5A in the output buffer using the "Write - * Auxiliary Device Output Buffer" command (0xD3). Poll the - * Status Register for a while to see if the value really - * turns up in the Data Register. If the KBD_STAT_MOUSE_OBF - * bit is also set to 1 in the Status Register, we assume this - * controller has an Auxiliary Port (a.k.a. Mouse Port). - */ - kb_wait(); - kbd_write_command(KBD_CCMD_WRITE_AUX_OBUF); - - kb_wait(); - kbd_write_output(0x5a); /* 0x5a is a random dummy value. */ - - do { - unsigned char status = kbd_read_status(); - if (status & KBD_STAT_OBF) { - kbd_read_input(); - if (status & KBD_STAT_MOUSE_OBF) { - printk( "Detected PS/2 Mouse Port.\n"); - retval = 1; - } - break; - } - mdelay(1); - } while (--loops); - return retval; -} - -/* - * Send a byte to the mouse. - */ -static void aux_write_dev(int val) -{ - kb_wait(); - kbd_write_command(KBD_CCMD_WRITE_MOUSE); - kb_wait(); - kbd_write_output(val); -} - -/* - * Send a byte to the mouse & handle returned ack - */ -static void aux_write_ack(int val) -{ - kb_wait(); - kbd_write_command(KBD_CCMD_WRITE_MOUSE); - kb_wait(); - kbd_write_output(val); - /* we expect an ACK in response. */ - mouse_reply_expected++; - kb_wait(); -} - -static unsigned char get_from_queue(void) -{ - unsigned char result; - result = queue->buf[queue->tail]; - queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1); - return result; -} - -static int queue_empty(void) -{ - return queue->head == queue->tail; -} - -/* - * Random magic cookie for the aux device - */ -#define AUX_DEV ((void *)queue) - -static int release_aux(void) -{ - rtems_status_code status; - if (--aux_count) - return 0; - kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints */ - kbd_write_command_w(KBD_CCMD_MOUSE_DISABLE); - status = rtems_interrupt_handler_remove( - AUX_IRQ, - ps2_mouse_interrupt, - NULL - ); - assert(status == RTEMS_SUCCESSFUL); - return 0; -} - -/* - * Install interrupt handler. - * Enable auxiliary device. - */ - -static int open_aux(void) -{ - rtems_status_code status; - - if (aux_count++) { - return 0; - } - queue->head = queue->tail = 0; /* Flush input queue */ - - status = rtems_interrupt_handler_install( - AUX_IRQ, - "ps2_mouse", - RTEMS_INTERRUPT_UNIQUE, - ps2_mouse_interrupt, - NULL - ); - assert(status == RTEMS_SUCCESSFUL); - - kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable the auxiliary port on - controller. */ - aux_write_ack(AUX_ENABLE_DEV); /* Enable aux device */ - kbd_write_cmd(AUX_INTS_ON); /* Enable controller ints */ - return 0; -} - -/* - * Put bytes from input queue to buffer. - */ -size_t read_aux(char * buffer, size_t count ) -{ - size_t i = count; - unsigned char c; - - if (queue_empty()) { - return 0; - } - while (i > 0 && !queue_empty()) { - c = get_from_queue(); - *buffer++ = c; - i--; - } - return count-i; -} - -/* - * Write to the aux device. - */ -static int write_aux( int minor, const char * buffer, int count ) -{ - int retval = 0; - - if (count) { - int written = 0; - if (count > 32) - count = 32; /* Limit to 32 bytes. */ - do { - char c; - c = *buffer++; - aux_write_dev(c); - written++; - } while (--count); - retval = -EIO; - if (written) { - retval = written; - } - } - return retval; -} - -static int psaux_init( void ) -{ - if( !detect_auxiliary_port() ) { - printk( "PS/2 - mouse not found.\n" ); - return -EIO; - } - queue = (struct aux_queue *)malloc( sizeof(*queue) ); - memset(queue, 0, sizeof(*queue)); - queue->head = queue->tail = 0; - queue->proc_list = NULL; - - #ifdef INITIALIZE_MOUSE - kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable Aux. */ - aux_write_ack(AUX_SET_SAMPLE); - aux_write_ack(100); /* 100 samples/sec */ - aux_write_ack(AUX_SET_RES); - aux_write_ack(3); /* 8 counts per mm */ - aux_write_ack(AUX_SET_SCALE21); /* 2:1 scaling */ - #endif /* INITIALIZE_MOUSE */ - kbd_write_command(KBD_CCMD_MOUSE_DISABLE); /* Disable aux device. */ - kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints. */ - return 0; -} - -/* - * paux device driver INITIALIZE entry point. - */ -rtems_device_driver paux_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - rtems_status_code status; - - /* - * Set up TERMIOS - */ - rtems_termios_initialize(); - - printk( "PS/2 mouse probe.\n" ); - if( psaux_init() < 0 ) { - printk("Error detecting PS/2 mouse --\n"); - /* we might want to finish the application here !!! */ - } - open_aux(); - - /* - * Register the device - */ - status = rtems_io_register_name ("/dev/mouse", major, 0); - if (status != RTEMS_SUCCESSFUL) { - printk("Error registering paux device!\n"); - rtems_fatal_error_occurred (status); - } - return RTEMS_SUCCESSFUL; -} /* tty_initialize */ - -static int paux_last_close(int major, int minor, void *arg) -{ - release_aux(); - return 0; -} - -/* - * Write to the aux device. This routine is invoked by the - * termios framework whenever the "ECHO" feature is on. - * It does nothing write now. - */ -static ssize_t write_aux_echo( int minor, const char * buffer, size_t count ) -{ - return 0; -} - -/* - * paux device driver OPEN entry point - */ -rtems_device_driver paux_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - rtems_status_code status; - static rtems_termios_callbacks cb = - { - NULL, /* firstOpen */ - paux_last_close, /* lastClose */ - NULL, /* poll read */ - write_aux_echo, /* write */ - NULL, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - 0 /* outputUsesInterrupts */ - }; - - status = rtems_termios_open (major, minor, arg, &cb ); - termios_ttyp_paux = ( (rtems_libio_open_close_args_t *)arg)->iop->data1; - return status; -} - -/* - * paux device driver CLOSE entry point - */ -rtems_device_driver paux_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - return (rtems_termios_close (arg)); -} - -/* - * paux device driver READ entry point. - * Read characters from the PS/2 mouse. - */ -rtems_device_driver paux_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - return rtems_termios_read (arg); -} /* tty_read */ - -/* - * paux device driver WRITE entry point. - * Write characters to the PS/2 mouse. - */ -rtems_device_driver paux_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; - char *buffer = rw_args->buffer; - int maximum = rw_args->count; - rw_args->bytes_moved = write_aux( minor, buffer, maximum ); - return RTEMS_SUCCESSFUL; -} /* tty_write */ - -/* - * Handle ioctl request. - */ -rtems_device_driver paux_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_libio_ioctl_args_t *args = arg; - - switch( args->command ) { - default: - return rtems_termios_ioctl (arg); - break; - - case MW_UID_REGISTER_DEVICE: - printk( "PS2 Mouse: registering\n" ); - mouse_parser_initialize( "ps2" ); - ps2_set_driver_handler( minor, mouse_parser_enqueue ); - break; - - case MW_UID_UNREGISTER_DEVICE: -/* - unregister_mou_msg_queue( -1 ); -*/ - ps2_set_driver_handler( minor, NULL ); - break; - } - args->ioctl_return = 0; - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/lib/libbsp/i386/pc386/console/ps2_mouse.h b/c/src/lib/libbsp/i386/pc386/console/ps2_mouse.h deleted file mode 100644 index dd61e8a367..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/ps2_mouse.h +++ /dev/null @@ -1,151 +0,0 @@ -/** - * @file - * - * @ingroup i386_pc386 - * - * @brief Keyboard and mouse definitions. - */ - -/* - * include/linux/pc_keyb.h - * PC Keyboard And Keyboard Controller - * (c) 1997 Martin Mares - * - * RTEMS port: by Rosimildo da Silva. - * - * This module was ported from Linux. - * - */ - -/* - * Configuration Switches - */ - -#undef KBD_REPORT_ERR /* Report keyboard errors */ -#define KBD_REPORT_UNKN /* Report unknown scan codes */ -#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */ -#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */ -#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */ - -#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */ -#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */ -#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */ - -/* - * Internal variables of the driver - */ - -extern unsigned char pckbd_read_mask; -extern unsigned char aux_device_present; - -/* - * Keyboard Controller Registers on normal PCs. - */ - -#define KBD_STATUS_REG 0x64 /* Status register (R) */ -#define KBD_CNTL_REG 0x64 /* Controller command register (W) */ -#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */ - -/* - * Keyboard Controller Commands - */ - -#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */ -#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */ -#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */ -#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */ -#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */ -#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */ -#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */ -#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */ -#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */ -#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */ -#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if - initiated by the auxiliary device */ -#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */ - -/* - * Keyboard Commands - */ - -#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */ -#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */ -#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */ -#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */ -#define KBD_CMD_RESET 0xFF /* Reset */ - -/* - * Keyboard Replies - */ - -#define KBD_REPLY_POR 0xAA /* Power on reset */ -#define KBD_REPLY_ACK 0xFA /* Command ACK */ -#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */ - -/* - * Status Register Bits - */ - -#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */ -#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */ -#define KBD_STAT_SELFTEST 0x04 /* Self test successful */ -#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */ -#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */ -#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */ -#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */ -#define KBD_STAT_PERR 0x80 /* Parity error */ - -#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF) - -/* - * Controller Mode Register Bits - */ - -#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */ -#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */ -#define KBD_MODE_SYS 0x04 /* The system flag (?) */ -#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */ -#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */ -#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */ -#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */ -#define KBD_MODE_RFU 0x80 - -/* - * Mouse Commands - */ - -#define AUX_SET_RES 0xE8 /* Set resolution */ -#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */ -#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */ -#define AUX_GET_SCALE 0xE9 /* Get scaling factor */ -#define AUX_SET_STREAM 0xEA /* Set stream mode */ -#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */ -#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */ -#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */ -#define AUX_RESET 0xFF /* Reset aux device */ -#define AUX_ACK 0xFA /* Command byte ACK. */ - -#define AUX_BUF_SIZE 512 /* This might be better divisible by - three to make overruns stay in sync - but then the read function would need - a lock etc - ick */ - -struct aux_queue { - unsigned long head; - unsigned long tail; - struct wait_queue *proc_list; - struct fasync_struct *fasync; - unsigned char buf[AUX_BUF_SIZE]; -}; - -/* How to access the keyboard macros on this platform. */ -#define kbd_read_input() inb(KBD_DATA_REG) -#define kbd_read_status() inb(KBD_STATUS_REG) -#define kbd_write_output(val) outb(val, KBD_DATA_REG) -#define kbd_write_command(val) outb(val, KBD_CNTL_REG) - -/* - * Machine specific bits for the PS/2 driver - */ - -#define AUX_IRQ 12 diff --git a/c/src/lib/libbsp/i386/pc386/console/rtd316.c b/c/src/lib/libbsp/i386/pc386/console/rtd316.c deleted file mode 100644 index 3b4e3c6ab4..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/rtd316.c +++ /dev/null @@ -1,109 +0,0 @@ -/** - * @file - * - * @brief Driver for RTD316 ISA SCC Board - * - * The RTD316 has a single Z85C30. - */ - -/* - * COPYRIGHT (c) 1989-2014. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h" - -#define RTD_CLOCK_RATE (460800 * 32) - -uint8_t rtd316_com_get_register(uint32_t addr, uint8_t reg) -{ - register uint8_t val = 0; - - outport_byte( addr, reg ); - /* It appears the no delay is needed between the accesses. */ - inport_byte( addr, val ); - - return val; -} - -void rtd316_com_set_register(uint32_t addr,uint8_t reg, uint8_t val) -{ - outport_byte( addr, reg ); - /* It appears the no delay is needed between the accesses. */ - outport_byte( addr, val ); -} - -rtems_device_driver rtd316_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor_arg, - void *arg -) -{ - int p; - console_tbl *ports; - console_tbl *port_p; - - /* - * Now allocate array of device structures and fill them in - */ - ports = calloc( 2, sizeof( console_tbl ) ); - port_p = ports; - - for ( p=0 ; p<2 ; p++ ) { - char name[32]; - sprintf( name, "/dev/rtd316_1_%d", p ); - printk("Found %s\n", name ); - port_p->sDeviceName = strdup( name ); - port_p->deviceType = SERIAL_Z85C30; - #if 0 - port_p->pDeviceFns = &z85c30_fns_polled; - #else - port_p->pDeviceFns = &z85c30_fns; - #endif - - port_p->deviceProbe = NULL; - port_p->pDeviceFlow = NULL; - port_p->ulMargin = 16; - port_p->ulHysteresis = 8; - port_p->pDeviceParams = (void *) 9600; - port_p->getRegister = rtd316_com_get_register; - port_p->setRegister = rtd316_com_set_register; - port_p->getData = NULL; - port_p->setData = NULL; - port_p->ulClock = RTD_CLOCK_RATE; - port_p->ulIntVector = 9; - - if ( p==0 ) { - port_p->ulDataPort = 0; - port_p->ulCtrlPort1 = 0x340; - port_p->ulCtrlPort2 = 0x341; - } else { - port_p->ulDataPort = 1; - port_p->ulCtrlPort1 = 0x342; - port_p->ulCtrlPort2 = 0x343; - } - port_p++; - } /* end ports */ - - /* - * Register the devices - */ - console_register_devices( ports, 2 ); - - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/lib/libbsp/i386/pc386/console/serial_mouse_config.c b/c/src/lib/libbsp/i386/pc386/console/serial_mouse_config.c deleted file mode 100644 index 492d038bd4..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/serial_mouse_config.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * COPYRIGHT (c) 1989-2011. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h" - -/* select which serial port the mouse is connected to */ -#if defined(SERIAL_MOUSE_COM2) - #define MOUSE_DEVICE "/dev/com2" -#else - #define MOUSE_DEVICE "/dev/com1" -#endif - -static const char *SerialMouseDevice = MOUSE_DEVICE; - -bool bsp_get_serial_mouse_device( - const char **name, - const char **type -) -{ - const char *consname; - - *name = SerialMouseDevice; - *type = "ms"; - - /* Check if this port is not been used as console */ - consname = Console_Port_Tbl[ Console_Port_Minor ]->sDeviceName; - if ( !strcmp(MOUSE_DEVICE, consname) ) { - printk( "SERIAL MOUSE: port selected as console.(%s)\n", *name ); - rtems_fatal_error_occurred( -1 ); - } - - printk("Mouse Device: %s\n", *name ); - return name; -} diff --git a/c/src/lib/libbsp/i386/pc386/console/uart_bus_pci.c b/c/src/lib/libbsp/i386/pc386/console/uart_bus_pci.c deleted file mode 100644 index ac0c3bf86e..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/uart_bus_pci.c +++ /dev/null @@ -1,477 +0,0 @@ -/* - * This file was brought over from FreeBSD for the PCI device table. - * The code for using the table is RTEMS specific is also under the - * FreeBSD license. - * - * COPYRIGHT (c) 1989-2012. - * On-Line Applications Research Corporation (OAR). - */ - -/*- - * Copyright (c) 2006 Marcel Moolenaar - * Copyright (c) 2001 M. Warner Losh - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifdef __rtems__ -#include -#include -#include -#else -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#endif - -#define DEFAULT_RCLK 1843200 - -#ifndef __rtems__ -static int uart_pci_probe(device_t dev); - -static device_method_t uart_pci_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, uart_pci_probe), - DEVMETHOD(device_attach, uart_bus_attach), - DEVMETHOD(device_detach, uart_bus_detach), - DEVMETHOD(device_resume, uart_bus_resume), - DEVMETHOD_END -}; - -static driver_t uart_pci_driver = { - uart_driver_name, - uart_pci_methods, - sizeof(struct uart_softc), -}; -#endif - -struct pci_id { - uint16_t vendor; - uint16_t device; - uint16_t subven; - uint16_t subdev; - const char *desc; - int rid; - int rclk; - int regshft; -}; - -static const struct pci_id pci_ns8250_ids[] = { -{ 0x1028, 0x0008, 0xffff, 0, "Dell Remote Access Card III", 0x14, - 128 * DEFAULT_RCLK }, -{ 0x1028, 0x0012, 0xffff, 0, "Dell RAC 4 Daughter Card Virtual UART", 0x14, - 128 * DEFAULT_RCLK }, -{ 0x1033, 0x0074, 0x1033, 0x8014, "NEC RCV56ACF 56k Voice Modem", 0x10 }, -{ 0x1033, 0x007d, 0x1033, 0x8012, "NEC RS232C", 0x10 }, -{ 0x103c, 0x1048, 0x103c, 0x1227, "HP Diva Serial [GSP] UART - Powerbar SP2", - 0x10 }, -{ 0x103c, 0x1048, 0x103c, 0x1301, "HP Diva RMP3", 0x14 }, -{ 0x103c, 0x1290, 0xffff, 0, "HP Auxiliary Diva Serial Port", 0x18 }, -{ 0x103c, 0x3301, 0xffff, 0, "HP iLO serial port", 0x10 }, -{ 0x11c1, 0x0480, 0xffff, 0, "Agere Systems Venus Modem (V90, 56KFlex)", 0x14 }, -{ 0x115d, 0x0103, 0xffff, 0, "Xircom Cardbus Ethernet + 56k Modem", 0x10 }, -{ 0x1282, 0x6585, 0xffff, 0, "Davicom 56PDV PCI Modem", 0x10 }, -{ 0x12b9, 0x1008, 0xffff, 0, "3Com 56K FaxModem Model 5610", 0x10 }, -{ 0x131f, 0x1000, 0xffff, 0, "Siig CyberSerial (1-port) 16550", 0x18 }, -{ 0x131f, 0x1001, 0xffff, 0, "Siig CyberSerial (1-port) 16650", 0x18 }, -{ 0x131f, 0x1002, 0xffff, 0, "Siig CyberSerial (1-port) 16850", 0x18 }, -{ 0x131f, 0x2000, 0xffff, 0, "Siig CyberSerial (1-port) 16550", 0x10 }, -{ 0x131f, 0x2001, 0xffff, 0, "Siig CyberSerial (1-port) 16650", 0x10 }, -{ 0x131f, 0x2002, 0xffff, 0, "Siig CyberSerial (1-port) 16850", 0x10 }, -{ 0x135c, 0x0190, 0xffff, 0, "Quatech SSCLP-100", 0x18 }, -{ 0x135c, 0x01c0, 0xffff, 0, "Quatech SSCLP-200/300", 0x18 }, -{ 0x135e, 0x7101, 0xffff, 0, "Sealevel Systems Single Port RS-232/422/485/530", - 0x18 }, -{ 0x1407, 0x0110, 0xffff, 0, "Lava Computer mfg DSerial-PCI Port A", 0x10 }, -{ 0x1407, 0x0111, 0xffff, 0, "Lava Computer mfg DSerial-PCI Port B", 0x10 }, -{ 0x1407, 0x0510, 0xffff, 0, "Lava SP Serial 550 PCI", 0x10 }, -{ 0x1409, 0x7168, 0x1409, 0x4025, "Timedia Technology Serial Port", 0x10, - 8 * DEFAULT_RCLK }, -{ 0x1409, 0x7168, 0x1409, 0x4027, "Timedia Technology Serial Port", 0x10, - 8 * DEFAULT_RCLK }, -{ 0x1409, 0x7168, 0x1409, 0x4028, "Timedia Technology Serial Port", 0x10, - 8 * DEFAULT_RCLK }, -{ 0x1409, 0x7168, 0x1409, 0x5025, "Timedia Technology Serial Port", 0x10, - 8 * DEFAULT_RCLK }, -{ 0x1409, 0x7168, 0x1409, 0x5027, "Timedia Technology Serial Port", 0x10, - 8 * DEFAULT_RCLK }, -{ 0x1415, 0x950b, 0xffff, 0, "Oxford Semiconductor OXCB950 Cardbus 16950 UART", - 0x10, 16384000 }, -{ 0x1415, 0xc120, 0xffff, 0, "Oxford Semiconductor OXPCIe952 PCIe 16950 UART", - 0x10 }, -{ 0x14e4, 0x4344, 0xffff, 0, "Sony Ericsson GC89 PC Card", 0x10}, -{ 0x151f, 0x0000, 0xffff, 0, "TOPIC Semiconductor TP560 56k modem", 0x10 }, -{ 0x1fd4, 0x1999, 0x1fd4, 0x0001, "Sunix SER5xxxx Serial Port", 0x10, - 8 * DEFAULT_RCLK }, -{ 0x8086, 0x0f0a, 0xffff, 0, "Intel ValleyView LPIO1 HSUART#1", 0x10, - 24 * DEFAULT_RCLK, 2 }, -{ 0x8086, 0x0f0c, 0xffff, 0, "Intel ValleyView LPIO1 HSUART#2", 0x10, - 24 * DEFAULT_RCLK, 2 }, -{ 0x8086, 0x1c3d, 0xffff, 0, "Intel AMT - KT Controller", 0x10 }, -{ 0x8086, 0x1d3d, 0xffff, 0, "Intel C600/X79 Series Chipset KT Controller", 0x10 }, -{ 0x8086, 0x2a07, 0xffff, 0, "Intel AMT - PM965/GM965 KT Controller", 0x10 }, -{ 0x8086, 0x2a47, 0xffff, 0, "Mobile 4 Series Chipset KT Controller", 0x10 }, -{ 0x8086, 0x2e17, 0xffff, 0, "4 Series Chipset Serial KT Controller", 0x10 }, -{ 0x8086, 0x3b67, 0xffff, 0, "5 Series/3400 Series Chipset KT Controller", - 0x10 }, -{ 0x8086, 0x8811, 0xffff, 0, "Intel EG20T Serial Port 0", 0x10 }, -{ 0x8086, 0x8812, 0xffff, 0, "Intel EG20T Serial Port 1", 0x10 }, -{ 0x8086, 0x8813, 0xffff, 0, "Intel EG20T Serial Port 2", 0x10 }, -{ 0x8086, 0x8814, 0xffff, 0, "Intel EG20T Serial Port 3", 0x10 }, -{ 0x8086, 0x8c3d, 0xffff, 0, "Intel Lynx Point KT Controller", 0x10 }, -{ 0x8086, 0x8cbd, 0xffff, 0, "Intel Wildcat Point KT Controller", 0x10 }, -{ 0x8086, 0x9c3d, 0xffff, 0, "Intel Lynx Point-LP HECI KT", 0x10 }, -{ 0x9710, 0x9820, 0x1000, 1, "NetMos NM9820 Serial Port", 0x10 }, -{ 0x9710, 0x9835, 0x1000, 1, "NetMos NM9835 Serial Port", 0x10 }, -{ 0x9710, 0x9865, 0xa000, 0x1000, "NetMos NM9865 Serial Port", 0x10 }, -{ 0x9710, 0x9900, 0xa000, 0x1000, - "MosChip MCS9900 PCIe to Peripheral Controller", 0x10 }, -{ 0x9710, 0x9901, 0xa000, 0x1000, - "MosChip MCS9901 PCIe to Peripheral Controller", 0x10 }, -{ 0x9710, 0x9904, 0xa000, 0x1000, - "MosChip MCS9904 PCIe to Peripheral Controller", 0x10 }, -{ 0x9710, 0x9922, 0xa000, 0x1000, - "MosChip MCS9922 PCIe to Peripheral Controller", 0x10 }, -{ 0xdeaf, 0x9051, 0xffff, 0, "Middle Digital PC Weasel Serial Port", 0x10 }, -{ 0xffff, 0, 0xffff, 0, NULL, 0, 0} -}; - -#ifndef __rtems__ -const static struct pci_id * -uart_pci_match(device_t dev, const struct pci_id *id) -{ - uint16_t device, subdev, subven, vendor; - - vendor = pci_get_vendor(dev); - device = pci_get_device(dev); - while (id->vendor != 0xffff && - (id->vendor != vendor || id->device != device)) - id++; - if (id->vendor == 0xffff) - return (NULL); - if (id->subven == 0xffff) - return (id); - subven = pci_get_subvendor(dev); - subdev = pci_get_subdevice(dev); - while (id->vendor == vendor && id->device == device && - (id->subven != subven || id->subdev != subdev)) - id++; - return ((id->vendor == vendor && id->device == device) ? id : NULL); -} - -static int -uart_pci_probe(device_t dev) -{ - struct uart_softc *sc; - const struct pci_id *id; - int result; - - sc = device_get_softc(dev); - - id = uart_pci_match(dev, pci_ns8250_ids); - if (id != NULL) { - sc->sc_class = &uart_ns8250_class; - goto match; - } - /* Add checks for non-ns8250 IDs here. */ - return (ENXIO); - - match: - result = uart_bus_probe(dev, id->regshft, id->rclk, id->rid, 0); - /* Bail out on error. */ - if (result > 0) - return (result); - /* Set/override the device description. */ - if (id->desc) - device_set_desc(dev, id->desc); - return (result); -} - -DRIVER_MODULE(uart, pci, uart_pci_driver, uart_devclass, NULL, NULL); -#endif - -#ifdef __rtems__ - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h" - -#define MAX_BOARDS 4 - -/* - * Information saved from PCI scan - */ -typedef struct { - bool found; - const char* desc; - uint32_t base; - uint8_t irq; - uint8_t bus; - uint8_t slot; - int ports; - uint32_t clock; -} port_instance_conf_t; - -/* - * Memory Mapped Register Access Routines - */ - -#define UART_PCI_IO (0) - -static uint8_t pci_ns16550_mem_get_register(uint32_t addr, uint8_t i) -{ - uint8_t val = 0; - volatile uint32_t *reg = (volatile uint32_t *)(addr + (i*4)); - val = *reg; - if (UART_PCI_IO) - printk( "RD(%p -> 0x%02x) ", reg, val ); - return val; -} - -static void pci_ns16550_mem_set_register(uint32_t addr, uint8_t i, uint8_t val) -{ - volatile uint32_t *reg = (volatile uint32_t *)(addr + (i*4)); - if (UART_PCI_IO) - printk( "WR(%p <- 0x%02x) ", reg, val ); - *reg = val; -} - -/* - * IO Register Access Routines - */ -static uint8_t pci_ns16550_io_get_register(uint32_t addr, uint8_t i) -{ - uint8_t val = rtems_inb(addr + i); - if (UART_PCI_IO) - printk( "RD(%p -> 0x%02x) ", (void*) addr + i, val ); - return val; -} - -static void pci_ns16550_io_set_register(uint32_t addr, uint8_t i, uint8_t val) -{ - if (UART_PCI_IO) - printk( "WR(%p <- 0x%02x) ", (void*) addr + i, val ); - rtems_outb(addr + i, val); -} - -void pci_uart_probe(void) -{ - port_instance_conf_t conf[MAX_BOARDS]; - int boards = 0; - int b = 0; - console_tbl *ports; - console_tbl *port_p; - int bus; - int dev; - int fun; - int status; - int instance; - int i; - int total_ports = 0; - - for ( b=0 ; b> 1) & 3) != 2))) { - boards++; - conf[instance].found = true; - conf[instance].desc = pci_ns8250_ids[i].desc; - conf[instance].clock = pci_ns8250_ids[i].rclk; - conf[instance].ports = 1; - total_ports += conf[instance].ports; - - pci_read_config_byte( bus, dev, fun, PCI_INTERRUPT_LINE, &irq ); - - conf[instance].irq = irq; - conf[instance].base = base; - } - } - } - } - - /* - * Now allocate array of device structures and fill them in - */ - if (boards) { - int device_instance; - - ports = calloc( total_ports, sizeof( console_tbl ) ); - if (ports != NULL) { - port_p = ports; - device_instance = 1; - for (b = 0; b < MAX_BOARDS; b++) { - uint32_t base = 0; - bool io; - const char* locatable = ""; - const char* prefectable = locatable; - char name[32]; - if ( conf[b].found == false ) - continue; - sprintf( name, "/dev/pcicom%d", device_instance++ ); - port_p->sDeviceName = strdup( name ); - port_p->deviceType = SERIAL_NS16550; - if ( conf[b].irq <= 15 ) { - port_p->pDeviceFns = &ns16550_fns; - } else { - printk( - "%s IRQ=%d >= 16 requires APIC support, using polling\n", - name, - conf[b].irq - ); - port_p->pDeviceFns = &ns16550_fns_polled; - } - - /* - * PCI BAR (http://wiki.osdev.org/PCI#Base_Address_Registers): - * - * Bit 0: 0 = memory, 1 = IO - * - * Memory: - * Bit 2-1 : 0 = any 32bit address, - * 1 = < 1M - * 2 = any 64bit address - * Bit 3 : 0 = no, 1 = yes - * Bit 31-4 : base address (16-byte aligned) - * - * IO: - * Bit 1 : reserved - * Bit 31-2 : base address (4-byte aligned) - */ - - io = (conf[b].base & 1) == 1; - - if (io) { - base = conf[b].base & 0xfffffffc; - } else { - int loc = (conf[b].base >> 1) & 3; - if (loc == 0) { - base = conf[b].base & 0xfffffff0; - locatable = ",A32"; - } else if (loc == 1) { - base = conf[b].base & 0x0000fff0; - locatable = ",A16"; - } - prefectable = (conf[b].base & (1 << 3)) == 0 ? ",no-prefech" : ",prefetch"; - } - - port_p->deviceProbe = NULL; - port_p->pDeviceFlow = NULL; - port_p->ulMargin = 16; - port_p->ulHysteresis = 8; - port_p->pDeviceParams = (void *) 9600; - port_p->ulCtrlPort1 = base; - port_p->ulCtrlPort2 = 0; /* NA */ - port_p->ulDataPort = 0; /* NA */ - if (io) { - port_p->getRegister = pci_ns16550_io_get_register; - port_p->setRegister = pci_ns16550_io_set_register; - } else { - port_p->getRegister = pci_ns16550_mem_get_register; - port_p->setRegister = pci_ns16550_mem_set_register; - } - port_p->getData = NULL; /* NA */ - port_p->setData = NULL; /* NA */ - port_p->ulClock = conf[b].clock; - port_p->ulIntVector = conf[b].irq; - - - printk( - "%s:%d:%s,%s:0x%lx%s%s,irq:%d,clk:%lu\n", /* */ - name, b, conf[b].desc, - io ? "io" : "mem", base, locatable, prefectable, - conf[b].irq, conf[b].clock - ); - - - port_p++; - } /* end boards */ - - /* - * Register the devices - */ - console_register_devices( ports, total_ports ); - - /* - * Do not free the ports memory, the console hold this memory for-ever. - */ - } - } -} -#endif diff --git a/c/src/lib/libbsp/i386/pc386/console/vgacons.c b/c/src/lib/libbsp/i386/pc386/console/vgacons.c deleted file mode 100644 index 2886496e51..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/vgacons.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * This file contains the termios TTY driver for the i386 - * vga. - * - * COPYRIGHT (c) 1989-2011. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define VGACONS_STATIC static - -/* - * vgacons_init - * - * This function initializes the VGA console to a quiecsent state. - */ -VGACONS_STATIC void vgacons_init(int minor) -{ - /* - * Note: We do not initialize the KBD interface here since - * it was initialized regardless of whether the - * vga is available or not. Therefore it is initialized - * in bsp_start. - */ -} - -/* - * vgacons_open - * - * This function opens a port for communication. - * - * Default state is 9600 baud, 8 bits, No parity, and 1 stop bit. - */ -VGACONS_STATIC int vgacons_open( - int major, - int minor, - void *arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * vgacons_close - * - * This function shuts down the requested port. - */ -VGACONS_STATIC int vgacons_close( - int major, - int minor, - void *arg -) -{ - return(RTEMS_SUCCESSFUL); -} - -/* - * vgacons_write_polled - * - * This routine polls out the requested character. - */ -VGACONS_STATIC void vgacons_write_polled( - int minor, - char c -) -{ - _IBMPC_outch( c ); - if( c == '\n') - _IBMPC_outch( '\r' ); /* LF = LF + CR */ -} - -/* - * vgacons_write_support_polled - * - * Console Termios output entry point when using polled output. - * - */ -VGACONS_STATIC ssize_t vgacons_write_support_polled( - int minor, - const char *buf, - size_t len -) -{ - int nwrite = 0; - - /* - * poll each byte in the string out of the port. - */ - while (nwrite < len) { - vgacons_write_polled(minor, *buf++); - nwrite++; - } - - /* - * return the number of bytes written. - */ - return nwrite; -} - -/* - * vgacons_inbyte_nonblocking_polled - * - * Console Termios polling input entry point. - */ -VGACONS_STATIC int vgacons_inbyte_nonblocking_polled( - int minor -) -{ - if( rtems_kbpoll() ) { - int c = getch(); - return c; - } - - return -1; -} - -/* - * vgacons_set_attributes - * - * This function sets the UART channel to reflect the requested termios - * port settings. - */ -VGACONS_STATIC int vgacons_set_attributes( - int minor, - const struct termios *t -) -{ - return 0; -} - -bool vgacons_probe( - int minor -) -{ - rtems_status_code status; - static bool firstTime = true; - - if ((*(unsigned char*) NB_MAX_ROW_ADDR == 0) && - (*(unsigned short*)NB_MAX_COL_ADDR == 0)) { - return false; - } - - /* - * If there is a video card, let's assume there is also a keyboard. - * The means that we need the ISR installed in case someone wants to - * use the Keyboard or PS2 Mouse. With Microwindows, the console - * can be COM1 and you can still use the mouse/VGA for graphics. - */ - if ( firstTime ) { - status = rtems_interrupt_handler_install( - BSP_KEYBOARD, - "vgacons", - RTEMS_INTERRUPT_UNIQUE, - keyboard_interrupt, - NULL - ); - assert(status == RTEMS_SUCCESSFUL); - } - firstTime = false; - - return true; -} - -const console_fns vgacons_fns = -{ - libchip_serial_default_probe, /* deviceProbe */ - vgacons_open, /* deviceFirstOpen */ - vgacons_close, /* deviceLastClose */ - vgacons_inbyte_nonblocking_polled, /* deviceRead */ - vgacons_write_support_polled, /* deviceWrite */ - vgacons_init, /* deviceInitialize */ - vgacons_write_polled, /* deviceWritePolled */ - vgacons_set_attributes, /* deviceSetAttributes */ - FALSE, /* deviceOutputUsesInterrupts */ -}; diff --git a/c/src/lib/libbsp/i386/pc386/console/vgainit.c b/c/src/lib/libbsp/i386/pc386/console/vgainit.c deleted file mode 100644 index ce83ae59b1..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/vgainit.c +++ /dev/null @@ -1,757 +0,0 @@ -/* - * Copyright (c) 1999 Greg Haerr - * Copyright (c) 1991 David I. Bell - * Permission is granted to use, distribute, or modify this source, - * provided that this copyright notice remains intact. - * - * Alternate EGA/VGA Screen Driver Init, direct hw programming - */ -#include - -#ifdef __rtems__ -#define ROMFONT 0 /* =0 no bios rom fonts available*/ -#else -#define ROMFONT 1 /* =1 uses PC rom fonts */ -#endif - -/* defines are defined in device.h of the MicroWindows package */ -#define MODE_SET 0 /* draw pixels as given (default) */ -#define MODE_XOR 1 /* draw pixels using XOR */ -#define MODE_OR 2 /* draw pixels using OR (notimp)*/ -#define MODE_AND 3 /* draw pixels using AND (notimp)*/ -#define MODE_MAX 3 -typedef int MODE; /* drawing mode*/ - -/* Define one and only one of the following to be nonzero*/ -#define VGA_ET4000 0 /* TSENG LABS ET4000 chip 800x600*/ -#define VGA_STANDARD 1 /* standard VGA 640x480*/ -#define EGA_STANDARD 0 /* standard EGA 640x350*/ - -#define DONE 0 -#define IN 1 -#define OUT 2 - -#define RAM_SCAN_LINES 32 /* number of scan lines in fonts in RAM */ -#define FONT_CHARS 256 /* number of characters in font tables */ -#define CHAR_WIDTH 8 /* number of pixels for character width */ - -#define PALREG 0x3c0 -#define SEQREG 0x3c4 -#define SEQVAL 0x3c5 -#define GRREG 0x3ce -#define GRVAL 0x3cf -#define ATTRREG 0x3da -#define CRTCREG 0x3d4 -#define CRTCVAL 0x3d5 - -#define GENREG1 0x3c2 -#define GENREG2 0x3cc -#define GENREG3 0x3ca - -#define DATA_ROTATE 3 /* register number for data rotate */ - -typedef struct { - int action; - int port1; - int data1; - int port2; - int data2; -} REGIO; - -#if ROMFONT -extern FARADDR rom_char_addr; /* address of ROM font*/ -extern int ROM_CHAR_HEIGHT; /* ROM character height*/ -#endif - -/* local data*/ -static REGIO graphics_on[]; -static REGIO graph_off[]; - -/* entry points*/ -void ega_hwinit(void); -void ega_hwterm(void); - -/* local routines*/ -static void writeregs(REGIO *rp); -static void out_word(unsigned int p,unsigned int d); -static void setmode(MODE mode); - -void -ega_hwinit(void) -{ - writeregs(graphics_on); -} - -void -ega_hwterm(void) -{ - setmode(MODE_SET); - - /* Copy character table from ROM back into bit plane 2 before turning - * off graphics. - */ - out_word(SEQREG, 0x0100); /* syn reset */ - out_word(SEQREG, 0x0402); /* cpu writes only to map 2 */ - out_word(SEQREG, 0x0704); /* sequential addressing */ - out_word(SEQREG, 0x0300); /* clear synchronous reset */ - - out_word(GRREG, 0x0204); /* select map 2 for CPU reads */ - out_word(GRREG, 0x0005); /* disable odd-even addressing */ - -#if ROMFONT - { - FARADDR srcoffset; - FARADDR destoffset; - int data; - int ch; - int row; - - srcoffset = rom_char_addr; - destoffset = EGA_BASE; - for (ch = 0; ch < FONT_CHARS; ch++) { - for(row = 0; row < ROM_CHAR_HEIGHT; row++) { - data = GETBYTE_FP(srcoffset++); - PUTBYTE_FP(destoffset++, data); - } - destoffset += (RAM_SCAN_LINES - ROM_CHAR_HEIGHT); - } - } -#endif - - /* Finally set the registers back for text mode. */ - writeregs(graph_off); -} - -/* Set the graphics registers as indicated by the given table */ -static void -writeregs(REGIO *rp) -{ - for (; rp->action != DONE; rp++) { - switch (rp->action) { - case IN: - inp(rp->port1); - break; - case OUT: - outp(rp->port1, rp->data1); - if (rp->port2) - outp(rp->port2, rp->data2); - break; - } - } -} - -/* Output a word to an I/O port. */ -static void -out_word(unsigned int p,unsigned int d) -{ - outp(p, d & 0xff); - outp(p + 1, (d >> 8) & 0xff); -} - -/* Values for the data rotate register to implement drawing modes. */ -static unsigned char mode_table[MODE_MAX + 1] = { - 0x00, 0x18, 0x10, 0x08 -}; - -/* Set the drawing mode. - * This is either SET, OR, AND, or XOR. - */ -static void -setmode(MODE mode) -{ - if (mode > MODE_MAX) - return; - outp(GRREG, DATA_ROTATE); - outp(GRVAL, mode_table[mode]); -} - -#if VGA_ET4000 - -/* VGA 800x600 16-color graphics (BIOS mode 0x29). - */ -REGIO graphics_on[] = { - /* Reset attr F/F */ - IN, ATTRREG, 0, 0, 0, - - /* Disable palette */ - OUT, PALREG, 0, 0, 0, - - /* Reset sequencer regs */ - OUT, SEQREG, 0, SEQVAL, 0, - OUT, SEQREG, 1, SEQVAL, 1, - OUT, SEQREG, 2, SEQVAL, 0x0f, - OUT, SEQREG, 3, SEQVAL, 0, - OUT, SEQREG, 4, SEQVAL, 6, - - /* Misc out reg */ - OUT, GENREG1, 0xe3, 0, 0, - - /* Sequencer enable */ - OUT, SEQREG, 0, SEQVAL, 0x03, - - /* Unprotect crtc regs 0-7 */ - OUT, CRTCREG, 0x11, CRTCVAL, 0, - - /* Crtc */ - OUT, CRTCREG, 0, CRTCVAL, 0x7a, - OUT, CRTCREG, 1, CRTCVAL, 0x63, - OUT, CRTCREG, 2, CRTCVAL, 0x64, - OUT, CRTCREG, 3, CRTCVAL, 0x1d, - OUT, CRTCREG, 4, CRTCVAL, 0x68, - OUT, CRTCREG, 5, CRTCVAL, 0x9a, - OUT, CRTCREG, 6, CRTCVAL, 0x78, - OUT, CRTCREG, 7, CRTCVAL, 0xf0, - OUT, CRTCREG, 8, CRTCVAL, 0x00, - OUT, CRTCREG, 9, CRTCVAL, 0x60, - OUT, CRTCREG, 10, CRTCVAL, 0x00, - OUT, CRTCREG, 11, CRTCVAL, 0x00, - OUT, CRTCREG, 12, CRTCVAL, 0x00, - OUT, CRTCREG, 13, CRTCVAL, 0x00, - OUT, CRTCREG, 14, CRTCVAL, 0x00, - OUT, CRTCREG, 15, CRTCVAL, 0x00, - OUT, CRTCREG, 16, CRTCVAL, 0x5c, - OUT, CRTCREG, 17, CRTCVAL, 0x8e, - OUT, CRTCREG, 18, CRTCVAL, 0x57, - OUT, CRTCREG, 19, CRTCVAL, 0x32, - OUT, CRTCREG, 20, CRTCVAL, 0x00, - OUT, CRTCREG, 21, CRTCVAL, 0x5b, - OUT, CRTCREG, 22, CRTCVAL, 0x75, - OUT, CRTCREG, 23, CRTCVAL, 0xc3, - OUT, CRTCREG, 24, CRTCVAL, 0xff, - - /* Graphics controller */ - OUT, GENREG2, 0x00, 0, 0, - OUT, GENREG3, 0x01, 0, 0, - OUT, GRREG, 0, GRVAL, 0x00, - OUT, GRREG, 1, GRVAL, 0x00, - OUT, GRREG, 2, GRVAL, 0x00, - OUT, GRREG, 3, GRVAL, 0x00, - OUT, GRREG, 4, GRVAL, 0x00, - OUT, GRREG, 5, GRVAL, 0x00, - OUT, GRREG, 6, GRVAL, 0x05, - OUT, GRREG, 7, GRVAL, 0x0f, - OUT, GRREG, 8, GRVAL, 0xff, - - /* Reset attribute flip/flop */ - IN, ATTRREG, 0, 0, 0, - - /* Palette */ - OUT, PALREG, 0, PALREG, 0x00, - OUT, PALREG, 1, PALREG, 0x01, - OUT, PALREG, 2, PALREG, 0x02, - OUT, PALREG, 3, PALREG, 0x03, - OUT, PALREG, 4, PALREG, 0x04, - OUT, PALREG, 5, PALREG, 0x05, - OUT, PALREG, 6, PALREG, 0x06, - OUT, PALREG, 7, PALREG, 0x07, - OUT, PALREG, 8, PALREG, 0x38, - OUT, PALREG, 9, PALREG, 0x39, - OUT, PALREG, 10, PALREG, 0x3a, - OUT, PALREG, 11, PALREG, 0x3b, - OUT, PALREG, 12, PALREG, 0x3c, - OUT, PALREG, 13, PALREG, 0x3d, - OUT, PALREG, 14, PALREG, 0x3e, - OUT, PALREG, 15, PALREG, 0x3f, - OUT, PALREG, 16, PALREG, 0x01, - OUT, PALREG, 17, PALREG, 0x00, - OUT, PALREG, 18, PALREG, 0x0f, - OUT, PALREG, 19, PALREG, 0x00, - - /* Enable palette */ - OUT, PALREG, 0x20, 0, 0, - - /* End of table */ - DONE, 0, 0, 0, 0 -}; - -/* VGA 80x25 text (BIOS mode 3). - */ -static REGIO graph_off[] = { - /* Reset attr F/F */ - IN, ATTRREG, 0, 0, 0, - - /* Disable palette */ - OUT, PALREG, 0, 0, 0, - - /* Reset sequencer regs */ - OUT, SEQREG, 0, SEQVAL, 1, - OUT, SEQREG, 1, SEQVAL, 1, - OUT, SEQREG, 2, SEQVAL, 3, - OUT, SEQREG, 3, SEQVAL, 0, - OUT, SEQREG, 4, SEQVAL, 2, - - /* Misc out reg */ - OUT, GENREG1, 0x63, 0, 0, - - /* Sequencer enable */ - OUT, SEQREG, 0, SEQVAL, 3, - - /* Unprotect crtc regs 0-7 */ - OUT, CRTCREG, 0x11, CRTCVAL, 0, - - /* Crtc */ - OUT, CRTCREG, 0, CRTCVAL, 0x5f, /* horiz total */ - OUT, CRTCREG, 1, CRTCVAL, 0x4f, /* horiz end */ - OUT, CRTCREG, 2, CRTCVAL, 0x50, /* horiz blank */ - OUT, CRTCREG, 3, CRTCVAL, 0x82, /* end blank */ - OUT, CRTCREG, 4, CRTCVAL, 0x55, /* horiz retrace */ - OUT, CRTCREG, 5, CRTCVAL, 0x81, /* end retrace */ - OUT, CRTCREG, 6, CRTCVAL, 0xbf, /* vert total */ - OUT, CRTCREG, 7, CRTCVAL, 0x1f, /* overflows */ - OUT, CRTCREG, 8, CRTCVAL, 0x00, /* row scan */ - OUT, CRTCREG, 9, CRTCVAL, 0x4f, /* max scan line */ - OUT, CRTCREG, 10, CRTCVAL, 0x00, /* cursor start */ - OUT, CRTCREG, 11, CRTCVAL, 0x0f, /* cursor end */ - OUT, CRTCREG, 12, CRTCVAL, 0x0e, /* start high addr */ - OUT, CRTCREG, 13, CRTCVAL, 0xb0, /* low addr */ - OUT, CRTCREG, 14, CRTCVAL, 0x16, /* cursor high */ - OUT, CRTCREG, 15, CRTCVAL, 0x30, /* cursor low */ - OUT, CRTCREG, 16, CRTCVAL, 0x9c, /* vert retrace */ - OUT, CRTCREG, 17, CRTCVAL, 0x8e, /* retrace end */ - OUT, CRTCREG, 18, CRTCVAL, 0x8f, /* vert end */ - OUT, CRTCREG, 19, CRTCVAL, 0x28, /* offset */ - OUT, CRTCREG, 20, CRTCVAL, 0x1f, /* underline */ - OUT, CRTCREG, 21, CRTCVAL, 0x96, /* vert blank */ - OUT, CRTCREG, 22, CRTCVAL, 0xb9, /* end blank */ - OUT, CRTCREG, 23, CRTCVAL, 0xa3, /* crt mode */ - OUT, CRTCREG, 24, CRTCVAL, 0xff, /* line compare */ - - /* Graphics controller */ - OUT, GENREG2, 0x00, 0, 0, - OUT, GENREG3, 0x01, 0, 0, - OUT, GRREG, 0, GRVAL, 0x00, - OUT, GRREG, 1, GRVAL, 0x00, - OUT, GRREG, 2, GRVAL, 0x00, - OUT, GRREG, 3, GRVAL, 0x00, - OUT, GRREG, 4, GRVAL, 0x00, - OUT, GRREG, 5, GRVAL, 0x10, - OUT, GRREG, 6, GRVAL, 0x0e, - OUT, GRREG, 7, GRVAL, 0x00, - OUT, GRREG, 8, GRVAL, 0xff, - - /* Reset attribute flip/flop */ - IN, ATTRREG, 0, 0, 0, - - /* Palette */ - OUT, PALREG, 0, PALREG, 0x00, - OUT, PALREG, 1, PALREG, 0x01, - OUT, PALREG, 2, PALREG, 0x02, - OUT, PALREG, 3, PALREG, 0x03, - OUT, PALREG, 4, PALREG, 0x04, - OUT, PALREG, 5, PALREG, 0x05, - OUT, PALREG, 6, PALREG, 0x06, - OUT, PALREG, 7, PALREG, 0x07, - OUT, PALREG, 8, PALREG, 0x10, - OUT, PALREG, 9, PALREG, 0x11, - OUT, PALREG, 10, PALREG, 0x12, - OUT, PALREG, 11, PALREG, 0x13, - OUT, PALREG, 12, PALREG, 0x14, - OUT, PALREG, 13, PALREG, 0x15, - OUT, PALREG, 14, PALREG, 0x16, - OUT, PALREG, 15, PALREG, 0x17, - OUT, PALREG, 16, PALREG, 0x08, - OUT, PALREG, 17, PALREG, 0x00, - OUT, PALREG, 18, PALREG, 0x0f, - OUT, PALREG, 19, PALREG, 0x00, - - /* Enable palette */ - OUT, PALREG, 0x20, 0, 0, - - /* End of table */ - DONE, 0, 0, 0, 0 -}; - -#endif - -#if VGA_STANDARD - -/* VGA 640x480 16-color graphics (BIOS mode 0x12). - */ -static REGIO graphics_on[] = { - /* Reset attr F/F */ - { IN, ATTRREG, 0, 0, 0 }, - - /* Disable palette */ - { OUT, PALREG, 0, 0, 0 }, - - /* Reset sequencer regs */ - { OUT, SEQREG, 0, SEQVAL, 0 }, - { OUT, SEQREG, 1, SEQVAL, 1 }, - { OUT, SEQREG, 2, SEQVAL, 0x0f }, - { OUT, SEQREG, 3, SEQVAL, 0 }, - { OUT, SEQREG, 4, SEQVAL, 6 }, - - /* Misc out reg */ - { OUT, GENREG1, 0xe3, 0, 0 }, - - /* Sequencer enable */ - { OUT, SEQREG, 0, SEQVAL, 0x03 }, - - /* Unprotect crtc regs 0-7 */ - { OUT, CRTCREG, 0x11, CRTCVAL, 0 }, - - /* Crtc */ - { OUT, CRTCREG, 0, CRTCVAL, 0x5f }, - { OUT, CRTCREG, 1, CRTCVAL, 0x4f }, - { OUT, CRTCREG, 2, CRTCVAL, 0x50 }, - { OUT, CRTCREG, 3, CRTCVAL, 0x82 }, - { OUT, CRTCREG, 4, CRTCVAL, 0x54 }, - { OUT, CRTCREG, 5, CRTCVAL, 0x80 }, - { OUT, CRTCREG, 6, CRTCVAL, 0x0b }, - { OUT, CRTCREG, 7, CRTCVAL, 0x3e }, - { OUT, CRTCREG, 8, CRTCVAL, 0x00 }, - { OUT, CRTCREG, 9, CRTCVAL, 0x40 }, - { OUT, CRTCREG, 10, CRTCVAL, 0x00 }, - { OUT, CRTCREG, 11, CRTCVAL, 0x00 }, - { OUT, CRTCREG, 12, CRTCVAL, 0x00 }, - { OUT, CRTCREG, 13, CRTCVAL, 0x00 }, - { OUT, CRTCREG, 14, CRTCVAL, 0x00 }, - { OUT, CRTCREG, 15, CRTCVAL, 0x59 }, - { OUT, CRTCREG, 16, CRTCVAL, 0xea }, - { OUT, CRTCREG, 17, CRTCVAL, 0x8c }, - { OUT, CRTCREG, 18, CRTCVAL, 0xdf }, - { OUT, CRTCREG, 19, CRTCVAL, 0x28 }, - { OUT, CRTCREG, 20, CRTCVAL, 0x00 }, - { OUT, CRTCREG, 21, CRTCVAL, 0xe7 }, - { OUT, CRTCREG, 22, CRTCVAL, 0x04 }, - { OUT, CRTCREG, 23, CRTCVAL, 0xe3 }, - { OUT, CRTCREG, 24, CRTCVAL, 0xff }, - - /* Graphics controller */ - { OUT, GENREG2, 0x00, 0, 0 }, - { OUT, GENREG3, 0x01, 0, 0 }, - { OUT, GRREG, 0, GRVAL, 0x00 }, - { OUT, GRREG, 1, GRVAL, 0x00 }, - { OUT, GRREG, 2, GRVAL, 0x00 }, - { OUT, GRREG, 3, GRVAL, 0x00 }, - { OUT, GRREG, 4, GRVAL, 0x00 }, - { OUT, GRREG, 5, GRVAL, 0x00 }, - { OUT, GRREG, 6, GRVAL, 0x05 }, - { OUT, GRREG, 7, GRVAL, 0x0f }, - { OUT, GRREG, 8, GRVAL, 0xff }, - - /* Reset attribute flip/flop */ - { IN, ATTRREG, 0, 0, 0 }, - - /* Palette */ - { OUT, PALREG, 0, PALREG, 0x00 }, - { OUT, PALREG, 1, PALREG, 0x01 }, - { OUT, PALREG, 2, PALREG, 0x02 }, - { OUT, PALREG, 3, PALREG, 0x03 }, - { OUT, PALREG, 4, PALREG, 0x04 }, - { OUT, PALREG, 5, PALREG, 0x05 }, - { OUT, PALREG, 6, PALREG, 0x06 }, - { OUT, PALREG, 7, PALREG, 0x07 }, - { OUT, PALREG, 8, PALREG, 0x38 }, - { OUT, PALREG, 9, PALREG, 0x39 }, - { OUT, PALREG, 10, PALREG, 0x3a }, - { OUT, PALREG, 11, PALREG, 0x3b }, - { OUT, PALREG, 12, PALREG, 0x3c }, - { OUT, PALREG, 13, PALREG, 0x3d }, - { OUT, PALREG, 14, PALREG, 0x3e }, - { OUT, PALREG, 15, PALREG, 0x3f }, - { OUT, PALREG, 16, PALREG, 0x01 }, - { OUT, PALREG, 17, PALREG, 0x00 }, - { OUT, PALREG, 18, PALREG, 0x0f }, - { OUT, PALREG, 19, PALREG, 0x00 }, - - /* Enable palette */ - { OUT, PALREG, 0x20, 0, 0 }, - - /* End of table */ - { DONE, 0, 0, 0, 0 } -}; - -/* VGA 80x25 text (BIOS mode 3). - */ -static REGIO graph_off[] = { - /* Reset attr F/F */ - { IN, ATTRREG, 0, 0, 0 }, - - /* Disable palette */ - { OUT, PALREG, 0, 0, 0 }, - - /* Reset sequencer regs */ - { OUT, SEQREG, 0, SEQVAL, 1 }, - { OUT, SEQREG, 1, SEQVAL, 1 }, - { OUT, SEQREG, 2, SEQVAL, 3 }, - { OUT, SEQREG, 3, SEQVAL, 0 }, - { OUT, SEQREG, 4, SEQVAL, 2 }, - - /* Misc out reg */ - { OUT, GENREG1, 0x63, 0, 0 }, - - /* Sequencer enable */ - { OUT, SEQREG, 0, SEQVAL, 3 }, - - /* Unprotect crtc regs 0-7 */ - { OUT, CRTCREG, 0x11, CRTCVAL, 0 }, - - /* Crtc */ - { OUT, CRTCREG, 0, CRTCVAL, 0x5f }, /* horiz total */ - { OUT, CRTCREG, 1, CRTCVAL, 0x4f }, /* horiz end */ - { OUT, CRTCREG, 2, CRTCVAL, 0x50 }, /* horiz blank */ - { OUT, CRTCREG, 3, CRTCVAL, 0x82 }, /* end blank */ - { OUT, CRTCREG, 4, CRTCVAL, 0x55 }, /* horiz retrace */ - { OUT, CRTCREG, 5, CRTCVAL, 0x81 }, /* end retrace */ - { OUT, CRTCREG, 6, CRTCVAL, 0xbf }, /* vert total */ - { OUT, CRTCREG, 7, CRTCVAL, 0x1f }, /* overflows */ - { OUT, CRTCREG, 8, CRTCVAL, 0x00 }, /* row scan */ - { OUT, CRTCREG, 9, CRTCVAL, 0x4f }, /* max scan line */ - { OUT, CRTCREG, 10, CRTCVAL, 0x00 }, /* cursor start */ - { OUT, CRTCREG, 11, CRTCVAL, 0x0f }, /* cursor end */ - { OUT, CRTCREG, 12, CRTCVAL, 0x0e }, /* start high addr */ - { OUT, CRTCREG, 13, CRTCVAL, 0xb0 }, /* low addr */ - { OUT, CRTCREG, 14, CRTCVAL, 0x16 }, /* cursor high */ - { OUT, CRTCREG, 15, CRTCVAL, 0x30 }, /* cursor low */ - { OUT, CRTCREG, 16, CRTCVAL, 0x9c }, /* vert retrace */ - { OUT, CRTCREG, 17, CRTCVAL, 0x8e }, /* retrace end */ - { OUT, CRTCREG, 18, CRTCVAL, 0x8f }, /* vert end */ - { OUT, CRTCREG, 19, CRTCVAL, 0x28 }, /* offset */ - { OUT, CRTCREG, 20, CRTCVAL, 0x1f }, /* underline */ - { OUT, CRTCREG, 21, CRTCVAL, 0x96 }, /* vert blank */ - { OUT, CRTCREG, 22, CRTCVAL, 0xb9 }, /* end blank */ - { OUT, CRTCREG, 23, CRTCVAL, 0xa3 }, /* crt mode */ - { OUT, CRTCREG, 24, CRTCVAL, 0xff }, /* line compare */ - - /* Graphics controller */ - { OUT, GENREG2, 0x00, 0, 0 }, - { OUT, GENREG3, 0x01, 0, 0 }, - { OUT, GRREG, 0, GRVAL, 0x00 }, - { OUT, GRREG, 1, GRVAL, 0x00 }, - { OUT, GRREG, 2, GRVAL, 0x00 }, - { OUT, GRREG, 3, GRVAL, 0x00 }, - { OUT, GRREG, 4, GRVAL, 0x00 }, - { OUT, GRREG, 5, GRVAL, 0x10 }, - { OUT, GRREG, 6, GRVAL, 0x0e }, - { OUT, GRREG, 7, GRVAL, 0x00 }, - { OUT, GRREG, 8, GRVAL, 0xff }, - - /* Reset attribute flip/flop */ - { IN, ATTRREG, 0, 0, 0 }, - - /* Palette */ - { OUT, PALREG, 0, PALREG, 0x00 }, - { OUT, PALREG, 1, PALREG, 0x01 }, - { OUT, PALREG, 2, PALREG, 0x02 }, - { OUT, PALREG, 3, PALREG, 0x03 }, - { OUT, PALREG, 4, PALREG, 0x04 }, - { OUT, PALREG, 5, PALREG, 0x05 }, - { OUT, PALREG, 6, PALREG, 0x06 }, - { OUT, PALREG, 7, PALREG, 0x07 }, - { OUT, PALREG, 8, PALREG, 0x10 }, - { OUT, PALREG, 9, PALREG, 0x11 }, - { OUT, PALREG, 10, PALREG, 0x12 }, - { OUT, PALREG, 11, PALREG, 0x13 }, - { OUT, PALREG, 12, PALREG, 0x14 }, - { OUT, PALREG, 13, PALREG, 0x15 }, - { OUT, PALREG, 14, PALREG, 0x16 }, - { OUT, PALREG, 15, PALREG, 0x17 }, - { OUT, PALREG, 16, PALREG, 0x08 }, - { OUT, PALREG, 17, PALREG, 0x00 }, - { OUT, PALREG, 18, PALREG, 0x0f }, - { OUT, PALREG, 19, PALREG, 0x00 }, - - /* Enable palette */ - { OUT, PALREG, 0x20, 0, 0 }, - - /* End of table */ - { DONE, 0, 0, 0, 0 } -}; - -#endif - -#if EGA_STANDARD - -/* EGA 640x350 16-color graphics (BIOS mode 0x10). - */ -static REGIO graphics_on[] = { - /* Reset attr F/F */ - IN, ATTRREG, 0, 0, 0, - - /* Disable palette */ - OUT, PALREG, 0, 0, 0, - - /* Reset sequencer regs */ - OUT, SEQREG, 0, SEQVAL, 0, - OUT, SEQREG, 1, SEQVAL, 1, - OUT, SEQREG, 2, SEQVAL, 0x0f, - OUT, SEQREG, 3, SEQVAL, 0, - OUT, SEQREG, 4, SEQVAL, 6, - - /* Misc out reg */ - OUT, GENREG1, 0xa7, 0, 0, - - /* Sequencer enable */ - OUT, SEQREG, 0, SEQVAL, 0x03, - - /* Unprotect crtc regs 0-7 */ - OUT, CRTCREG, 0x11, CRTCVAL, 0, - - /* Crtc */ - OUT, CRTCREG, 0, CRTCVAL, 0x5b, - OUT, CRTCREG, 1, CRTCVAL, 0x4f, - OUT, CRTCREG, 2, CRTCVAL, 0x53, - OUT, CRTCREG, 3, CRTCVAL, 0x37, - OUT, CRTCREG, 4, CRTCVAL, 0x52, - OUT, CRTCREG, 5, CRTCVAL, 0x00, - OUT, CRTCREG, 6, CRTCVAL, 0x6c, - OUT, CRTCREG, 7, CRTCVAL, 0x1f, - OUT, CRTCREG, 8, CRTCVAL, 0x00, - OUT, CRTCREG, 9, CRTCVAL, 0x00, - OUT, CRTCREG, 10, CRTCVAL, 0x00, - OUT, CRTCREG, 11, CRTCVAL, 0x00, - OUT, CRTCREG, 12, CRTCVAL, 0x00, - OUT, CRTCREG, 13, CRTCVAL, 0x00, - OUT, CRTCREG, 14, CRTCVAL, 0x00, - OUT, CRTCREG, 15, CRTCVAL, 0x00, - OUT, CRTCREG, 16, CRTCVAL, 0x5e, - OUT, CRTCREG, 17, CRTCVAL, 0x2b, - OUT, CRTCREG, 18, CRTCVAL, 0x5d, - OUT, CRTCREG, 19, CRTCVAL, 0x28, - OUT, CRTCREG, 20, CRTCVAL, 0x0f, - OUT, CRTCREG, 21, CRTCVAL, 0x5f, - OUT, CRTCREG, 22, CRTCVAL, 0x0a, - OUT, CRTCREG, 23, CRTCVAL, 0xe3, - OUT, CRTCREG, 24, CRTCVAL, 0xff, - - /* Graphics controller */ - OUT, GENREG2, 0x00, 0, 0, - OUT, GENREG3, 0x01, 0, 0, - OUT, GRREG, 0, GRVAL, 0x00, - OUT, GRREG, 1, GRVAL, 0x00, - OUT, GRREG, 2, GRVAL, 0x00, - OUT, GRREG, 3, GRVAL, 0x00, - OUT, GRREG, 4, GRVAL, 0x00, - OUT, GRREG, 5, GRVAL, 0x00, - OUT, GRREG, 6, GRVAL, 0x05, - OUT, GRREG, 7, GRVAL, 0x0f, - OUT, GRREG, 8, GRVAL, 0xff, - - /* Reset attribute flip/flop */ - IN, ATTRREG, 0, 0, 0, - - /* Palette */ - OUT, PALREG, 0, PALREG, 0x00, - OUT, PALREG, 1, PALREG, 0x01, - OUT, PALREG, 2, PALREG, 0x02, - OUT, PALREG, 3, PALREG, 0x03, - OUT, PALREG, 4, PALREG, 0x04, - OUT, PALREG, 5, PALREG, 0x05, - OUT, PALREG, 6, PALREG, 0x06, - OUT, PALREG, 7, PALREG, 0x07, - OUT, PALREG, 8, PALREG, 0x38, - OUT, PALREG, 9, PALREG, 0x39, - OUT, PALREG, 10, PALREG, 0x3a, - OUT, PALREG, 11, PALREG, 0x3b, - OUT, PALREG, 12, PALREG, 0x3c, - OUT, PALREG, 13, PALREG, 0x3d, - OUT, PALREG, 14, PALREG, 0x3e, - OUT, PALREG, 15, PALREG, 0x3f, - OUT, PALREG, 16, PALREG, 0x01, - OUT, PALREG, 17, PALREG, 0x00, - OUT, PALREG, 18, PALREG, 0x0f, - OUT, PALREG, 19, PALREG, 0x00, - - /* Enable palette */ - OUT, PALREG, 0x20, 0, 0, - - /* End of table */ - DONE, 0, 0, 0, 0 -}; - -/* EGA 80x25 text (BIOS mode 3). - */ -static REGIO graph_off[] = { - /* Reset attr F/F */ - IN, ATTRREG, 0, 0, 0, - - /* Disable palette */ - OUT, PALREG, 0, 0, 0, - - /* Reset sequencer regs */ - OUT, SEQREG, 0, SEQVAL, 1, - OUT, SEQREG, 1, SEQVAL, 1, - OUT, SEQREG, 2, SEQVAL, 3, - OUT, SEQREG, 3, SEQVAL, 0, - OUT, SEQREG, 4, SEQVAL, 3, - - /* Misc out reg */ - OUT, GENREG1, 0xa7, 0, 0, - - /* Sequencer enable */ - OUT, SEQREG, 0, SEQVAL, 3, - - /* Crtc */ - OUT, CRTCREG, 0, CRTCVAL, 0x5b, /* horiz total */ - OUT, CRTCREG, 1, CRTCVAL, 0x4f, /* horiz end */ - OUT, CRTCREG, 2, CRTCVAL, 0x53, /* horiz blank */ - OUT, CRTCREG, 3, CRTCVAL, 0x37, /* end blank */ - OUT, CRTCREG, 4, CRTCVAL, 0x51, /* horiz retrace */ - OUT, CRTCREG, 5, CRTCVAL, 0x5b, /* end retrace */ - OUT, CRTCREG, 6, CRTCVAL, 0x6c, /* vert total */ - OUT, CRTCREG, 7, CRTCVAL, 0x1f, /* overflows */ - OUT, CRTCREG, 8, CRTCVAL, 0x00, /* row scan */ - OUT, CRTCREG, 9, CRTCVAL, 0x0d, /* max scan line */ - OUT, CRTCREG, 10, CRTCVAL, 0x00, /* cursor start */ - OUT, CRTCREG, 11, CRTCVAL, 0x0f, /* cursor end */ - OUT, CRTCREG, 12, CRTCVAL, 0x00, /* start high addr */ - OUT, CRTCREG, 13, CRTCVAL, 0x00, /* low addr */ - OUT, CRTCREG, 14, CRTCVAL, 0x00, /* cursor high */ - OUT, CRTCREG, 15, CRTCVAL, 0x00, /* cursor low */ - OUT, CRTCREG, 16, CRTCVAL, 0x5e, /* vert retrace */ - OUT, CRTCREG, 17, CRTCVAL, 0x2b, /* retrace end */ - OUT, CRTCREG, 18, CRTCVAL, 0x5d, /* vert end */ - OUT, CRTCREG, 19, CRTCVAL, 0x28, /* offset */ - OUT, CRTCREG, 20, CRTCVAL, 0x0f, /* underline */ - OUT, CRTCREG, 21, CRTCVAL, 0x5e, /* vert blank */ - OUT, CRTCREG, 22, CRTCVAL, 0x0a, /* end blank */ - OUT, CRTCREG, 23, CRTCVAL, 0xa3, /* crt mode */ - OUT, CRTCREG, 24, CRTCVAL, 0xff, /* line compare */ - - /* Graphics controller */ - OUT, GENREG2, 0x00, 0, 0, - OUT, GENREG3, 0x01, 0, 0, - OUT, GRREG, 0, GRVAL, 0x00, - OUT, GRREG, 1, GRVAL, 0x00, - OUT, GRREG, 2, GRVAL, 0x00, - OUT, GRREG, 3, GRVAL, 0x00, - OUT, GRREG, 4, GRVAL, 0x00, - OUT, GRREG, 5, GRVAL, 0x10, - OUT, GRREG, 6, GRVAL, 0x0e, - OUT, GRREG, 7, GRVAL, 0x00, - OUT, GRREG, 8, GRVAL, 0xff, - - /* Reset attribute flip/flop */ - IN, ATTRREG, 0, 0, 0, - - /* Palette */ - OUT, PALREG, 0, PALREG, 0x00, - OUT, PALREG, 1, PALREG, 0x01, - OUT, PALREG, 2, PALREG, 0x02, - OUT, PALREG, 3, PALREG, 0x03, - OUT, PALREG, 4, PALREG, 0x04, - OUT, PALREG, 5, PALREG, 0x05, - OUT, PALREG, 6, PALREG, 0x14, - OUT, PALREG, 7, PALREG, 0x07, - OUT, PALREG, 8, PALREG, 0x38, - OUT, PALREG, 9, PALREG, 0x39, - OUT, PALREG, 10, PALREG, 0x3a, - OUT, PALREG, 11, PALREG, 0x3b, - OUT, PALREG, 12, PALREG, 0x3c, - OUT, PALREG, 13, PALREG, 0x3d, - OUT, PALREG, 14, PALREG, 0x3e, - OUT, PALREG, 15, PALREG, 0x3f, - OUT, PALREG, 16, PALREG, 0x08, - OUT, PALREG, 17, PALREG, 0x00, - OUT, PALREG, 18, PALREG, 0x0f, - OUT, PALREG, 19, PALREG, 0x00, - - /* Enable palette */ - OUT, PALREG, 0x20, 0, 0, - - /* End of table */ - DONE, 0, 0, 0, 0 -}; - -#endif diff --git a/c/src/lib/libbsp/i386/pc386/console/videoAsm.S b/c/src/lib/libbsp/i386/pc386/console/videoAsm.S deleted file mode 100644 index 03f31f879b..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/videoAsm.S +++ /dev/null @@ -1,48 +0,0 @@ -/* - * videoAsm.S - This file contains code for displaying cursor on the console - * - * Copyright (C) 1998 valette@crf.canon.fr - * - * This code is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This code is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - .file "videoAsm.s" - -#include - - .text - .align 4 - .globl wr_cursor /* Move cursor position */ - -/* - * void wr_cursor(newPosition, ioBaseAddr) - */ - -wr_cursor: pushl %ecx - movl 8(%esp), %ecx /* Get new cursor position */ - movb $CC_CURSHIGH, %al /* Cursor high location */ - movl 12(%esp), %edx /* Get IO base address */ - outb (%dx) - incw %dx /* Program Data register */ - movb %ch, %al - outb (%dx) /* Update high location cursor */ - decw %dx /* Program Index Register */ - movb $CC_CURSLOW, %al /* Cursor low location */ - outb (%dx) - incw %dx /* Program Data Register */ - movb %cl, %al - outb (%dx) /* Update low location cursor */ - popl %ecx - ret diff --git a/c/src/lib/libbsp/i386/pc386/console/vt.c b/c/src/lib/libbsp/i386/pc386/console/vt.c deleted file mode 100644 index 022cb5d461..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/vt.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * linux/drivers/char/vt.c - * - * Copyright (C) 1992 obz under the linux copyright - * - * Dynamic diacritical handling - aeb@cwi.nl - Dec 1993 - * Dynamic keymap and string allocation - aeb@cwi.nl - May 1994 - * Restrict VT switching via ioctl() - grif@cs.ucr.edu - Dec 1995 - * Some code moved for less code duplication - Andi Kleen - Mar 1997 - * - * - * by: Rosimildo da Silva -- - * Ported to RTEMS to provide the basic interface to the console - * driver. Removed all stuff not required, such as VT_, Fonts, etc. - */ - -#include /* memcpy */ -#include -#include - -#include -#include -#include -#include -#include - -/* - * Console (vt and kd) routines, as defined by USL SVR4 manual, and by - * experimentation and study of X386 SYSV handling. - * - * One point of difference: SYSV vt's are /dev/vtX, which X >= 0, and - * /dev/console is a separate ttyp. Under Linux, /dev/tty0 is /dev/console, - * and the vc start at /dev/ttyX, X >= 1. We maintain that here, so we will - * always treat our set of vt as numbered 1..MAX_NR_CONSOLES (corresponding to - * ttys 0..MAX_NR_CONSOLES-1). Explicitly naming VT 0 is illegal, but using - * /dev/tty0 (fg_console) as a target is legal, since an implicit aliasing - * to the current console is done by the main ioctl code. - */ - -struct vt_struct *vt_cons[MAX_NR_CONSOLES]; - -/* Keyboard type: Default is KB_101, but can be set by machine - * specific code. - */ -unsigned char keyboard_type = KB_101; - -/* - * Generates sound of some frequency for some number of clock ticks - * - * If freq is 0, will turn off sound, else will turn it on for that time. - * If msec is 0, will return immediately, else will sleep for msec time, then - * turn sound off. - * - * We also return immediately, which is what was implied within the X - * comments - KDMKTONE doesn't put the process to sleep. - */ - -#if defined(__i386__) || defined(__alpha__) || defined(__powerpc__) \ - || (defined(__mips__) && !defined(CONFIG_SGI)) - -static void -kd_nosound(unsigned long ignored) -{ - /* disable counter 2 */ - outb(inb_p(0x61)&0xFC, 0x61); - return; -} - -static void -_kd_mksound(unsigned int hz, unsigned int ticks) -{ - unsigned int count = 0; - rtems_interrupt_lock_context lock_context; - - if (hz > 20 && hz < 32767) - count = 1193180 / hz; - - rtems_interrupt_lock_acquire(&rtems_i386_i8254_access_lock, &lock_context); -/* del_timer(&sound_timer); */ - if (count) { - /* enable counter 2 */ - outb_p(inb_p(0x61)|3, 0x61); - /* set command for counter 2, 2 byte write */ - outb_p(0xB6, TIMER_MODE); - /* select desired HZ */ - outb_p(count & 0xff, TIMER_CNTR2); - outb((count >> 8) & 0xff, TIMER_CNTR2); - -/* - if (ticks) { - sound_timer.expires = jiffies+ticks; - add_timer(&sound_timer); - } -*/ - } else - kd_nosound(0); - - rtems_interrupt_lock_release(&rtems_i386_i8254_access_lock, &lock_context); - return; -} - -#else - -void -_kd_mksound(unsigned int hz, unsigned int ticks) -{ -} - -#endif - -void (*kd_mksound)(unsigned int hz, unsigned int ticks) = _kd_mksound; - -#define i (tmp.kb_index) -#define s (tmp.kb_table) -#define v (tmp.kb_value) -static inline int -do_kdsk_ioctl(int cmd, struct kbentry *user_kbe, int perm, struct kbd_struct *kbd) -{ - struct kbentry tmp; - ushort *key_map, val; - - tmp = *user_kbe; - if (i >= NR_KEYS) /* s cannot be >= MAX_NR_KEYMAPS */ - return -EINVAL; - - switch (cmd) { - case KDGKBENT: - key_map = key_maps[s]; - if (key_map) { - val = U(key_map[i]); - if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES) - val = K_HOLE; - } else - val = (i ? K_HOLE : K_NOSUCHMAP); - user_kbe->kb_value = val; - return 0; - - case KDSKBENT: - return -EINVAL; - } - return 0; -} -#undef i -#undef s -#undef v - -#define HZ 100 - -static inline int -do_kbkeycode_ioctl(int cmd, struct kbkeycode *user_kbkc, int perm) -{ - struct kbkeycode tmp; - int kc = 0; - - tmp = *user_kbkc; - switch (cmd) { - case KDGETKEYCODE: - kc = getkeycode(tmp.scancode); - if (kc >= 0) - user_kbkc->keycode = kc; - break; - case KDSETKEYCODE: - if (!perm) - return -EPERM; - kc = setkeycode(tmp.scancode, tmp.keycode); - break; - } - return kc; -} - -static inline int -do_kdgkb_ioctl(int cmd, struct kbsentry *user_kdgkb, int perm) -{ - return -EINVAL; -} - -/* - * We handle the console-specific ioctl's here. We allow the - * capability to modify any console, not just the fg_console. - */ -int vt_ioctl( unsigned int cmd, unsigned long arg) -{ - int perm; - unsigned int console; - unsigned char ucval; - struct kbd_struct * kbd; - - console = 0; - /* - * To have permissions to do most of the vt ioctls, we either have - * to be the owner of the tty, or super-user. - */ - perm = 1; - kbd = kbd_table + console; - switch (cmd) { - case KIOCSOUND: - if (!perm) - return -EPERM; - if (arg) - arg = 1193180 / arg; - kd_mksound(arg, 0); - return 0; - - case KDMKTONE: - if (!perm) - return -EPERM; - { - unsigned int ticks, count; - - /* - * Generate the tone for the appropriate number of ticks. - * If the time is zero, turn off sound ourselves. - */ - ticks = HZ * ((arg >> 16) & 0xffff) / 1000; - count = ticks ? (arg & 0xffff) : 0; - if (count) - count = 1193180 / count; - kd_mksound(count, ticks); - return 0; - } - - case KDGKBTYPE: - /* - * this is naive. - */ - ucval = keyboard_type; - goto setchar; - - case KDSETMODE: - case KDGETMODE: - return -EINVAL; - - case KDSKBMODE: - if (!perm) - return -EPERM; - switch(arg) { - case K_RAW: - kbd->kbdmode = VC_RAW; - break; - case K_MEDIUMRAW: - kbd->kbdmode = VC_MEDIUMRAW; - break; - case K_XLATE: - kbd->kbdmode = VC_XLATE; - compute_shiftstate(); - break; - case K_UNICODE: - kbd->kbdmode = VC_UNICODE; - compute_shiftstate(); - break; - default: - return -EINVAL; - } - return 0; - - case KDGKBMODE: - ucval = ((kbd->kbdmode == VC_RAW) ? K_RAW : - (kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW : - (kbd->kbdmode == VC_UNICODE) ? K_UNICODE : - K_XLATE); - goto setint; - - /* this could be folded into KDSKBMODE, but for compatibility - reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */ - case KDSKBMETA: - switch(arg) { - case K_METABIT: - clr_vc_kbd_mode(kbd, VC_META); - break; - case K_ESCPREFIX: - set_vc_kbd_mode(kbd, VC_META); - break; - default: - return -EINVAL; - } - return 0; - - case KDGKBMETA: - ucval = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT); - setint: - *(int *)arg = ucval; - return 0; - - case KDGETKEYCODE: - case KDSETKEYCODE: - return do_kbkeycode_ioctl(cmd, (struct kbkeycode *)arg, perm); - - case KDGKBENT: - case KDSKBENT: - return do_kdsk_ioctl(cmd, (struct kbentry *)arg, perm, kbd); - - case KDGKBDIACR: - { - struct kbdiacrs *a = (struct kbdiacrs *)arg; - a->kb_cnt = accent_table_size; - memcpy( a->kbdiacr, accent_table, accent_table_size*sizeof(struct kbdiacr) ); - return 0; - } - - case KDSKBDIACR: - { - struct kbdiacrs *a = (struct kbdiacrs *)arg; - unsigned int ct; - - if (!perm) - return -EPERM; - ct = a->kb_cnt; - if (ct >= MAX_DIACR) - return -EINVAL; - accent_table_size = ct; - memcpy(accent_table, a->kbdiacr, ct*sizeof(struct kbdiacr)); - return 0; - } - - /* the ioctls below read/set the flags usually shown in the leds */ - /* don't use them - they will go away without warning */ - case KDGKBLED: - ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4); - goto setchar; - - case KDSKBLED: - if (!perm) - return -EPERM; - if (arg & ~0x77) - return -EINVAL; - kbd->ledflagstate = (arg & 7); - kbd->default_ledflagstate = ((arg >> 4) & 7); - set_leds(); - return 0; - - /* the ioctls below only set the lights, not the functions */ - /* for those, see KDGKBLED and KDSKBLED above */ - case KDGETLED: - ucval = getledstate(); - setchar: - *(char*)arg = ucval; - return 0; - - case KDSETLED: - if (!perm) - return -EPERM; - setledstate(kbd, arg); - return 0; - - default: - return -EINVAL; - } -} diff --git a/c/src/lib/libbsp/lm32/lm32_evr/Makefile.am b/c/src/lib/libbsp/lm32/lm32_evr/Makefile.am index 20102dac31..d294f3503e 100644 --- a/c/src/lib/libbsp/lm32/lm32_evr/Makefile.am +++ b/c/src/lib/libbsp/lm32/lm32_evr/Makefile.am @@ -30,8 +30,8 @@ librtemsbsp_a_SOURCES += ../shared/startup/bspreset.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/lm32/shared/clock/ckinit.c # console -librtemsbsp_a_SOURCES += ../shared/console/console.c -librtemsbsp_a_SOURCES += ../shared/console/uart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/lm32/shared/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/lm32/shared/console/uart.c # timer librtemsbsp_a_SOURCES += ../shared/timer/timer.c diff --git a/c/src/lib/libbsp/lm32/shared/console/console.c b/c/src/lib/libbsp/lm32/shared/console/console.c deleted file mode 100644 index d49ca346b6..0000000000 --- a/c/src/lib/libbsp/lm32/shared/console/console.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Console driver for Lattice Mico32 (lm32). - */ - -/* - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - * Jukka Pietarinen , 2008, - * Micro-Research Finland Oy - */ - -#define NO_BSP_INIT - -#include -#include -#include -#include - -/* console_initialize - * - * This routine initializes the console IO driver. - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - - printk("console_initialize\n"); - - status = rtems_io_register_name( - "/dev/console", - major, - (rtems_device_minor_number) 0 - ); - - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - return RTEMS_SUCCESSFUL; -} - -/* inbyte - * - * This routine reads a character from the SOURCE. - */ -static int inbyte( void ) -{ - /* - * If polling, wait until a character is available. - */ - return BSP_uart_polled_read(); -} - -/* outbyte - * - * This routine transmits a character out the SOURCE. It may support - * XON/XOFF flow control. - */ -static void outbyte( - char ch -) -{ - /* - * If polling, wait for the transmitter to be ready. - * Check for flow control requests and process. - * Then output the character. - */ - - BSP_uart_polled_write(ch); -} - -/* - * Open entry point - */ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * Close entry point - */ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * read bytes from the serial port. We only have stdin. - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args; - char *buffer; - int maximum; - int count = 0; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - for (count = 0; count < maximum; count++) { - buffer[ count ] = inbyte(); - if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { - buffer[ count++ ] = '\n'; - break; - } - } - - rw_args->bytes_moved = count; - return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; -} - -/* - * write bytes to the serial port. Stdout and stderr are the same. - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - int count; - int maximum; - rtems_libio_rw_args_t *rw_args; - char *buffer; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - for (count = 0; count < maximum; count++) { - if ( buffer[ count ] == '\n') { - outbyte('\r'); - } - outbyte( buffer[ count ] ); - } - - rw_args->bytes_moved = maximum; - return 0; -} - -/* - * IO Control entry point - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -BSP_output_char_function_type BSP_output_char = BSP_uart_polled_write; -BSP_polling_getchar_function_type BSP_poll_char = BSP_uart_polled_read; diff --git a/c/src/lib/libbsp/lm32/shared/console/uart.c b/c/src/lib/libbsp/lm32/shared/console/uart.c deleted file mode 100644 index 9adbd4063d..0000000000 --- a/c/src/lib/libbsp/lm32/shared/console/uart.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Uart driver for Lattice Mico32 (lm32) UART - */ - -/* - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - * Jukka Pietarinen , 2008, - * Micro-Research Finland Oy - */ - -#include "../include/system_conf.h" -#include "uart.h" -#include -#include - -static inline int uartread(unsigned int reg) -{ - return *((int*)(UART_BASE_ADDRESS + reg)); -} - -static inline void uartwrite(unsigned int reg, int value) -{ - *((int*)(UART_BASE_ADDRESS + reg)) = value; -} - -void BSP_uart_init(int baud) -{ - /* Disable UART interrupts */ - uartwrite(LM32_UART_IER, 0); - - /* Line control 8 bit, 1 stop, no parity */ - uartwrite(LM32_UART_LCR, LM32_UART_LCR_8BIT); - - /* Modem control, DTR = 1, RTS = 1 */ - uartwrite(LM32_UART_MCR, LM32_UART_MCR_DTR | LM32_UART_MCR_RTS); - - /* Set baud rate */ - uartwrite(LM32_UART_DIV, CPU_FREQUENCY/baud); -} - -void BSP_uart_polled_write(char ch) -{ - /* Insert CR before LF */ - if (ch == '\n') - BSP_uart_polled_write('\r'); - /* Wait until THR is empty. */ - while (!(uartread(LM32_UART_LSR) & LM32_UART_LSR_THRE)); - uartwrite(LM32_UART_RBR, ch); -} - -int BSP_uart_polled_read( void ) -{ - /* Wait until there is a byte in RBR */ - while (!(uartread(LM32_UART_LSR) & LM32_UART_LSR_DR)); - return (int) uartread(LM32_UART_RBR); -} - -char BSP_uart_is_character_ready(char *ch) -{ - if (uartread(LM32_UART_LSR) & LM32_UART_LSR_DR) - { - *ch = (char) uartread(LM32_UART_RBR); - return true; - } - *ch = '0'; - return false; -} diff --git a/c/src/lib/libbsp/lm32/shared/console/uart.h b/c/src/lib/libbsp/lm32/shared/console/uart.h deleted file mode 100644 index baafde13e2..0000000000 --- a/c/src/lib/libbsp/lm32/shared/console/uart.h +++ /dev/null @@ -1,102 +0,0 @@ -/** - * @file - * @ingroup lm32_shared lm32_uart - * @brief LatticeMico32 UART definitions - */ - -/* - * This file contains definitions for LatticeMico32 UART - * - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - * Jukka Pietarinen , 2008, - * Micro-Research Finland Oy - */ - -/** - * @defgroup lm32_uart LM32 UART - * @ingroup lm32_shared - * @brief LatticeMico32 UART definitions - * @{ - */ - -#ifndef _BSPUART_H -#define _BSPUART_H - -void BSP_uart_init(int baud); - -/* Receive buffer register / transmit holding register */ - -#define LM32_UART_RBR (0x0000) - -/* Interrupt enable register */ - -#define LM32_UART_IER (0x0004) -#define LM32_UART_IER_RBRI (0x0001) -#define LM32_UART_IER_THRI (0x0002) -#define LM32_UART_IER_RLSI (0x0004) -#define LM32_UART_IER_MSI (0x0008) - -/* Interrupt identification register */ - -#define LM32_UART_IIR (0x0008) -#define LM32_UART_IIR_STAT (0x0001) -#define LM32_UART_IIR_ID0 (0x0002) -#define LM32_UART_IIR_ID1 (0x0004) - -/* Line control register */ - -#define LM32_UART_LCR (0x000C) -#define LM32_UART_LCR_WLS0 (0x0001) -#define LM32_UART_LCR_WLS1 (0x0002) -#define LM32_UART_LCR_STB (0x0004) -#define LM32_UART_LCR_PEN (0x0008) -#define LM32_UART_LCR_EPS (0x0010) -#define LM32_UART_LCR_SP (0x0020) -#define LM32_UART_LCR_SB (0x0040) -#define LM32_UART_LCR_5BIT (0) -#define LM32_UART_LCR_6BIT (LM32_UART_LCR_WLS0) -#define LM32_UART_LCR_7BIT (LM32_UART_LCR_WLS1) -#define LM32_UART_LCR_8BIT (LM32_UART_LCR_WLS1 | LM32_UART_LCR_WLS0) - -/* Modem control register */ - -#define LM32_UART_MCR (0x0010) -#define LM32_UART_MCR_DTR (0x0001) -#define LM32_UART_MCR_RTS (0x0002) - -/* Line status register */ - -#define LM32_UART_LSR (0x0014) -#define LM32_UART_LSR_DR (0x0001) -#define LM32_UART_LSR_OE (0x0002) -#define LM32_UART_LSR_PE (0x0004) -#define LM32_UART_LSR_FE (0x0008) -#define LM32_UART_LSR_BI (0x0010) -#define LM32_UART_LSR_THRE (0x0020) -#define LM32_UART_LSR_TEMT (0x0040) - -/* Modem status register */ - -#define LM32_UART_MSR (0x0018) -#define LM32_UART_MSR_DCTS (0x0001) -#define LM32_UART_MSR_DDSR (0x0002) -#define LM32_UART_MSR_TERI (0x0004) -#define LM32_UART_MSR_DDCD (0x0008) -#define LM32_UART_MSR_CTS (0x0010) -#define LM32_UART_MSR_DSR (0x0020) -#define LM32_UART_MSR_RI (0x0040) -#define LM32_UART_MSR_DCD (0x0000) - -/* Baud-rate divisor register */ - -#define LM32_UART_DIV (0x001C) - -#endif /* _BSPUART_H */ - -/** @} */ diff --git a/c/src/lib/libbsp/m32c/m32cbsp/Makefile.am b/c/src/lib/libbsp/m32c/m32cbsp/Makefile.am index 1f1f71422a..feaa61884b 100644 --- a/c/src/lib/libbsp/m32c/m32cbsp/Makefile.am +++ b/c/src/lib/libbsp/m32c/m32cbsp/Makefile.am @@ -24,9 +24,9 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/sbrk.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/getentropy/getentropy-cpucounter.c librtemsbsp_a_SOURCES += startup/crtn.S librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/clock/clock-simidle.c -librtemsbsp_a_SOURCES += ../../shared/console-polled.c -librtemsbsp_a_SOURCES += console/console-io.c -librtemsbsp_a_SOURCES += console/syscalls.S +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-polled.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m32c/m32cbsp/console/console-io.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m32c/m32cbsp/console/syscalls.S librtemsbsp_a_SOURCES += timer/timer.c # Cache diff --git a/c/src/lib/libbsp/m32c/m32cbsp/console/console-io.c b/c/src/lib/libbsp/m32c/m32cbsp/console/console-io.c deleted file mode 100644 index 745493c43a..0000000000 --- a/c/src/lib/libbsp/m32c/m32cbsp/console/console-io.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file contains the hardware specific portions of the TTY driver - * for the serial ports on the m32c simulator in gdb. - */ - -/* - * COPYRIGHT (c) 1989-2008. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include - -/* - * console_initialize_hardware - * - * This routine initializes the console hardware. - * - */ - -void console_initialize_hardware(void) -{ - return; -} - -/* - * console_outbyte_polled - * - * This routine transmits a character using polling. - */ -ssize_t sys_write(int fd, const void *buf, size_t count); -void console_outbyte_polled( - int port, - char ch -) -{ - sys_write( 2, &ch, 1 ); -} - -/* - * console_inbyte_nonblocking - * - * This routine polls for a character. - */ - -int console_inbyte_nonblocking( - int port -) -{ - return -1; -} - -#include - -static void M32CsimBSP_output_char(char c) { console_outbyte_polled( 0, c ); } - -BSP_output_char_function_type BSP_output_char = M32CsimBSP_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/m32c/m32cbsp/console/syscalls.S b/c/src/lib/libbsp/m32c/m32cbsp/console/syscalls.S deleted file mode 100644 index f4cabac940..0000000000 --- a/c/src/lib/libbsp/m32c/m32cbsp/console/syscalls.S +++ /dev/null @@ -1,43 +0,0 @@ -/* - * System call support for simulator in gdb. - * Adapted from newlib 1.16.0. - */ - -#define SYS_exit 1 -#define SYS_open 2 -#define SYS_close 3 -#define SYS_read 4 -#define SYS_write 5 -#define SYS_lseek 6 -#define SYS_unlink 7 -#define SYS_getpid 8 -#define SYS_kill 9 -#define SYS_fstat 10 -#define SYS_sbrk 11 - -#define POUND # -#define SYSCALL(N) mov.b POUND N,0x400 - -#define S(n) _sys_##n: .global _sys_##n | SYSCALL(SYS_##n) | rts - -S(write) -S(exit) -S(sbrk) - - .global _abort -_abort: - /* This is for debuggers. The simulator stops here too. */ - brk - - /* Else, fall back on the simulator's "kill me" option. */ -#if defined(__r8c_cpu__) || defined(__m16c_cpu__) - mov.w #42,r1 -#else - mov.w #42,r0 -#endif - - SYSCALL(SYS_kill) - - /* Else, exit. */ - jmp.a __exit - diff --git a/c/src/lib/libbsp/m68k/av5282/Makefile.am b/c/src/lib/libbsp/m68k/av5282/Makefile.am index c96fe93459..4ad8a6a915 100644 --- a/c/src/lib/libbsp/m68k/av5282/Makefile.am +++ b/c/src/lib/libbsp/m68k/av5282/Makefile.am @@ -29,7 +29,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/setvec.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/av5282/clock/clock.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/av5282/console/console.c # timer librtemsbsp_a_SOURCES += timer/timer.c diff --git a/c/src/lib/libbsp/m68k/av5282/console/console.c b/c/src/lib/libbsp/m68k/av5282/console/console.c deleted file mode 100644 index dd557660f8..0000000000 --- a/c/src/lib/libbsp/m68k/av5282/console/console.c +++ /dev/null @@ -1,711 +0,0 @@ -/* - * Multi UART console serial I/O. - * - * TO DO: Add DMA input/output - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x)) - -#define MCF5282_UART_USR_ERROR ( MCF5282_UART_USR_RB | \ - MCF5282_UART_USR_FE | \ - MCF5282_UART_USR_PE | \ - MCF5282_UART_USR_OE ) - -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); -static ssize_t IntUartInterruptWrite (int minor, const char *buf, size_t len); - -static void _BSP_null_char( char c ) -{ - rtems_interrupt_level level; - - rtems_interrupt_disable(level); - while ( (MCF5282_UART_USR(CONSOLE_PORT) & MCF5282_UART_USR_TXRDY) == 0 ) - continue; - - MCF5282_UART_UTB(CONSOLE_PORT) = c; - while ( (MCF5282_UART_USR(CONSOLE_PORT) & MCF5282_UART_USR_TXRDY) == 0 ) - continue; - - rtems_interrupt_enable(level); -} -BSP_output_char_function_type BSP_output_char = _BSP_null_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - -#define MAX_UART_INFO 3 -#define RX_BUFFER_SIZE 512 - -struct IntUartInfoStruct -{ - int iomode; - volatile int uimr; - int baud; - int databits; - int parity; - int stopbits; - int hwflow; - int rx_in; - int rx_out; - char rx_buffer[RX_BUFFER_SIZE]; - void *ttyp; -}; - -struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; - -/* - * Function : IntUartSet - * - * Description : This updates the hardware UART settings. - */ -static void IntUartSet( - int minor, - int baud, - int databits, - int parity, - int stopbits, - int hwflow -) -{ - int divisor; - uint32_t clock_speed; - uint8_t umr1 = 0; - uint8_t umr2 = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - rtems_interrupt_level level; - - rtems_interrupt_disable(level); - - /* disable interrupts, clear RTS line, and disable the UARTS */ - MCF5282_UART_UIMR(minor) = 0; - MCF5282_UART_UOP0(minor) = 1; - MCF5282_UART_UCR(minor) = - (MCF5282_UART_UCR_TX_DISABLED | MCF5282_UART_UCR_RX_DISABLED); - - /* save the current values */ - info->uimr = 0; - info->baud = baud; - info->databits = databits; - info->parity = parity; - info->stopbits = stopbits; - info->hwflow = hwflow; - - clock_speed = get_CPU_clock_speed(); - /* determine the baud divisor value */ - divisor = (clock_speed / ( 32 * baud )); - if ( divisor < 2 ) - divisor = 2; - - /* check to see if doing hardware flow control */ - if ( hwflow ) { - /* set hardware flow options */ - umr1 |= MCF5282_UART_UMR1_RXRTS; - umr2 |= MCF5282_UART_UMR2_TXCTS; - } - - /* determine the new umr values */ - umr1 |= (parity | databits); - umr2 |= (stopbits); - - /* reset the uart */ - MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_ERROR; - MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_RX; - MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_TX; - - /* reset the uart mode register and update values */ - MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_MR; - MCF5282_UART_UMR(minor) = umr1; - MCF5282_UART_UMR(minor) = umr2; - - /* set the baud rate values */ - MCF5282_UART_UCSR(minor) = - (MCF5282_UART_UCSR_RCS_SYS_CLK | MCF5282_UART_UCSR_TCS_SYS_CLK); - MCF5282_UART_UBG1(minor) = (divisor & 0xff00) >> 8; - MCF5282_UART_UBG2(minor) = (divisor & 0x00ff); - - /* enable the uart */ - MCF5282_UART_UCR(minor) = - (MCF5282_UART_UCR_TX_ENABLED | MCF5282_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if ( info->iomode != TERMIOS_POLLED ) { - /* enable rx interrupts */ - info->uimr |= MCF5282_UART_UIMR_FFULL; - MCF5282_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if ( hwflow ) { - /* assert the RTS line */ - MCF5282_UART_UOP1(minor) = 1; - } - - rtems_interrupt_enable(level); -} - -/* - * Function : IntUartSetAttributes - * - * Description : This provides the hardware-dependent portion of tcsetattr(). - * value and sets it. At the moment this just sets the baud rate. - * - * Note: The highest baudrate is 115200 as this stays within - * an error of +/- 5% at 25MHz processor clock - */ -static int IntUartSetAttributes( - int minor, - const struct termios *t -) -{ - /* set default index values */ - int baud = (int)19200; - int databits = (int)MCF5282_UART_UMR1_BC_8; - int parity = (int)MCF5282_UART_UMR1_PM_NONE; - int stopbits = (int)MCF5282_UART_UMR2_STOP_BITS_1; - int hwflow = (int)0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* check to see if input is valid */ - if ( t != (const struct termios *)0 ) { - /* determine baud rate index */ - baud = rtems_termios_baud_to_number(t->c_ospeed); - - /* determine data bits */ - switch ( t->c_cflag & CSIZE ) { - case CS5: - databits = (int)MCF5282_UART_UMR1_BC_5; - break; - case CS6: - databits = (int)MCF5282_UART_UMR1_BC_6; - break; - case CS7: - databits = (int)MCF5282_UART_UMR1_BC_7; - break; - case CS8: - databits = (int)MCF5282_UART_UMR1_BC_8; - break; - } - - /* determine if parity is enabled */ - if ( t->c_cflag & PARENB ) { - if ( t->c_cflag & PARODD ) { - /* odd parity */ - parity = (int)MCF5282_UART_UMR1_PM_ODD; - } else { - /* even parity */ - parity = (int)MCF5282_UART_UMR1_PM_EVEN; - } - } - - /* determine stop bits */ - if ( t->c_cflag & CSTOPB ) { - /* two stop bits */ - stopbits = (int)MCF5282_UART_UMR2_STOP_BITS_2; - } - - /* check to see if hardware flow control */ - if ( t->c_cflag & CRTSCTS ) { - hwflow = 1; - } - } - - /* check to see if values have changed */ - if ( ( baud != info->baud ) || - ( databits != info->databits ) || - ( parity != info->parity ) || - ( stopbits != info->stopbits ) || - ( hwflow != info->hwflow ) ) { - - /* call function to set values */ - IntUartSet(minor, baud, databits, parity, stopbits, hwflow); - } - - return RTEMS_SUCCESSFUL; -} - -/* - * Function : IntUartInterruptHandler - * - * Description : This is the interrupt handler for the internal uart. It - * determines which channel caused the interrupt before queueing any received - * chars and dequeueing chars waiting for transmission. - */ -static rtems_isr IntUartInterruptHandler(rtems_vector_number v) -{ - unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); - struct IntUartInfoStruct *info = &IntUartInfo[chan]; - - /* check to see if received data */ - if ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_RXRDY ) { - /* read data and put into the receive buffer */ - while ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_RXRDY ) { - - if ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_ERROR ) { - /* clear the error */ - MCF5282_UART_UCR(chan) = MCF5282_UART_UCR_RESET_ERROR; - } - /* put data in rx buffer and check for errors */ - info->rx_buffer[info->rx_in] = MCF5282_UART_URB(chan); - - /* update buffer values */ - info->rx_in++; - - if ( info->rx_in >= RX_BUFFER_SIZE ) { - info->rx_in = 0; - } - } - - /* Make sure the port has been opened */ - if ( info->ttyp ) { - - /* check to see if task driven */ - if ( info->iomode == TERMIOS_TASK_DRIVEN ) { - /* notify rx task that rx buffer has data */ - rtems_termios_rxirq_occured(info->ttyp); - } else { - /* Push up the received data */ - rtems_termios_enqueue_raw_characters( - info->ttyp, info->rx_buffer, info->rx_in); - info->rx_in = 0; - } - } - } - - /* check to see if data needs to be transmitted */ - if ( ( info->uimr & MCF5282_UART_UIMR_TXRDY ) && - ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_TXRDY ) ) - { - - /* disable tx interrupts */ - info->uimr &= ~MCF5282_UART_UIMR_TXRDY; - MCF5282_UART_UIMR(chan) = info->uimr; - - /* tell upper level that character has been sent */ - if ( info->ttyp ) - rtems_termios_dequeue_characters(info->ttyp, 1); - } -} - -/* - * Function : IntUartInitialize - * - * Description : This initialises the internal uart hardware for all - * internal uarts. If the internal uart is to be interrupt driven then the - * interrupt vectors are hooked. - */ -static void IntUartInitialize(void) -{ - unsigned int chan; - struct IntUartInfoStruct *info; - rtems_isr_entry old_handler; - rtems_interrupt_level level; - - for ( chan = 0; chan < MAX_UART_INFO; chan++ ) { - info = &IntUartInfo[chan]; - - info->ttyp = NULL; - info->rx_in = 0; - info->rx_out = 0; - info->baud = -1; - info->databits = -1; - info->parity = -1; - info->stopbits = -1; - info->hwflow = -1; - info->iomode = TERMIOS_POLLED; - - MCF5282_UART_UACR(chan) = 0; - MCF5282_UART_UIMR(chan) = 0; - if ( info->iomode != TERMIOS_POLLED ) { - rtems_interrupt_catch (IntUartInterruptHandler, - UART_INTC0_IRQ_VECTOR(chan), - &old_handler); - } - - /* set uart default values */ - IntUartSetAttributes(chan, NULL); - - /* unmask interrupt */ - rtems_interrupt_disable(level); - switch(chan) { - case 0: - MCF5282_INTC0_ICR13 = MCF5282_INTC_ICR_IL(UART0_IRQ_LEVEL) | - MCF5282_INTC_ICR_IP(UART0_IRQ_PRIORITY); - MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT13 | - MCF5282_INTC_IMRL_MASKALL); - break; - - case 1: - MCF5282_INTC0_ICR14 = MCF5282_INTC_ICR_IL(UART1_IRQ_LEVEL) | - MCF5282_INTC_ICR_IP(UART1_IRQ_PRIORITY); - MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT14 | - MCF5282_INTC_IMRL_MASKALL); - break; - - case 2: - MCF5282_INTC0_ICR15 = MCF5282_INTC_ICR_IL(UART2_IRQ_LEVEL) | - MCF5282_INTC_ICR_IP(UART2_IRQ_PRIORITY); - MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT15 | - MCF5282_INTC_IMRL_MASKALL); - break; - } - rtems_interrupt_enable(level); - - } /* of chan loop */ - - -} /* IntUartInitialise */ - - -/* - * Function : IntUartInterruptWrite - * - * Description : This writes a single character to the appropriate uart - * channel. This is either called during an interrupt or in the user's task - * to initiate a transmit sequence. Calling this routine enables Tx - * interrupts. - */ -static ssize_t IntUartInterruptWrite( - int minor, - const char *buf, - size_t len -) -{ - if (len > 0) { - /* write out character */ - MCF5282_UART_UTB(minor) = *buf; - - /* enable tx interrupt */ - IntUartInfo[minor].uimr |= MCF5282_UART_UIMR_TXRDY; - MCF5282_UART_UIMR(minor) = IntUartInfo[minor].uimr; - } - - return 0; -} - -/* - * Function : IntUartInterruptOpen - * - * Description : This enables interrupts when the tty is opened. - */ -static int IntUartInterruptOpen( - int major, - int minor, - void *arg -) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* enable the uart */ - MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_ENABLED | - MCF5282_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if ( info->iomode != TERMIOS_POLLED ) { - /* enable rx interrupts */ - info->uimr |= MCF5282_UART_UIMR_FFULL; - MCF5282_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if ( info->hwflow ) { - /* assert the RTS line */ - MCF5282_UART_UOP1(minor) = 1; - } - - return 0; -} - -/* - * Function : IntUartInterruptClose - * - * Description : This disables interrupts when the tty is closed. - */ -static int IntUartInterruptClose( - int major, - int minor, - void *arg -) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* disable the interrupts and the uart */ - MCF5282_UART_UIMR(minor) = 0; - MCF5282_UART_UCR(minor) = - (MCF5282_UART_UCR_TX_DISABLED | MCF5282_UART_UCR_RX_DISABLED); - - /* reset values */ - info->ttyp = NULL; - info->uimr = 0; - info->rx_in = 0; - info->rx_out = 0; - - return 0; -} - -/* - * Function : IntUartTaskRead - * - * Description : This reads all available characters from the internal uart - * and places them into the termios buffer. The rx interrupts will be - * re-enabled after all data has been read. - */ -static int IntUartTaskRead(int minor) -{ - char buffer[RX_BUFFER_SIZE]; - int count; - int rx_in; - int index = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* determine number of values to copy out */ - rx_in = info->rx_in; - if ( info->rx_out <= rx_in ) { - count = rx_in - info->rx_out; - } else { - count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; - } - - /* copy data into local buffer from rx buffer */ - while ( ( index < count ) && ( index < RX_BUFFER_SIZE ) ) { - /* copy data byte */ - buffer[index] = info->rx_buffer[info->rx_out]; - index++; - - /* increment rx buffer values */ - info->rx_out++; - if ( info->rx_out >= RX_BUFFER_SIZE ) { - info->rx_out = 0; - } - } - - /* check to see if buffer is not empty */ - if ( count > 0 ) { - /* set characters into termios buffer */ - rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); - } - - return EOF; -} - - - -/* - * Function : IntUartPollRead - * - * Description : This reads a character from the internal uart. It returns - * to the caller without blocking if not character is waiting. - */ -static int IntUartPollRead(int minor) -{ - if ( (MCF5282_UART_USR(minor) & MCF5282_UART_USR_RXRDY) == 0 ) - return-1; - - return MCF5282_UART_URB(minor); -} - - -/* - * Function : IntUartPollWrite - * - * Description : This writes out each character in the buffer to the - * appropriate internal uart channel waiting till each one is sucessfully - * transmitted. - */ -static ssize_t IntUartPollWrite( - int minor, - const char *buf, - size_t len -) -{ - size_t retval = len; - /* loop over buffer */ - - while ( len-- ) { - /* block until we can transmit */ - while ( (MCF5282_UART_USR(minor) & MCF5282_UART_USR_TXRDY) == 0 ) - continue; - /* transmit data byte */ - MCF5282_UART_UTB(minor) = *buf++; - } - return retval; -} - -/* - * Function : console_initialize - * - * Description : This initialises termios, both sets of uart hardware before - * registering /dev/tty devices for each channel and the system /dev/console. - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - - /* Set up TERMIOS */ - rtems_termios_initialize (); - - /* set io modes for the different channels and initialize device */ - IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN; - IntUartInitialize(); - - /* Register the console port */ - status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT); - if ( status != RTEMS_SUCCESSFUL ) { - rtems_fatal_error_occurred (status); - } - - /* Register the other port */ - if ( CONSOLE_PORT != 0 ) { - status = rtems_io_register_name ("/dev/tty00", major, 0); - if ( status != RTEMS_SUCCESSFUL ) { - rtems_fatal_error_occurred (status); - } - } - if ( CONSOLE_PORT != 1 ) { - status = rtems_io_register_name ("/dev/tty01", major, 1); - if ( status != RTEMS_SUCCESSFUL ) { - rtems_fatal_error_occurred (status); - } - } - - return RTEMS_SUCCESSFUL; -} - -/* - * Function : console_open - * - * Description : This actually opens the device depending on the minor - * number set during initialisation. The device specific access routines are - * passed to termios when the devices is opened depending on whether it is - * polled or not. - */ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_status_code status = RTEMS_INVALID_NUMBER; - rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *)arg; - struct IntUartInfoStruct *info; - - static const rtems_termios_callbacks IntUartPollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - IntUartPollRead, /* pollRead */ - IntUartPollWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_POLLED /* mode */ - }; - static const rtems_termios_callbacks IntUartIntrCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - NULL, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_IRQ_DRIVEN /* mode */ - }; - - static const rtems_termios_callbacks IntUartTaskCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - IntUartTaskRead, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_TASK_DRIVEN /* mode */ - }; - - /* open the port depending on the minor device number */ - if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) ) { - info = &IntUartInfo[minor]; - switch ( info->iomode ) { - case TERMIOS_POLLED: - status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); - break; - case TERMIOS_IRQ_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); - info->ttyp = args->iop->data1; - break; - case TERMIOS_TASK_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); - info->ttyp = args->iop->data1; - break; - } - } - - return status; -} - -/* - * Function : console_close - * - * Description : This closes the device via termios - */ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_close(arg); -} - -/* - * Function : console_read - * - * Description : Read from the device via termios - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - return rtems_termios_read(arg); -} - -/* - * Function : console_write - * - * Description : Write to the device via termios - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - return rtems_termios_write(arg); -} - -/* - * Function : console_ioctl - * - * Description : Pass the IOCtl call to termios - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - return rtems_termios_ioctl(arg); -} diff --git a/c/src/lib/libbsp/m68k/csb360/Makefile.am b/c/src/lib/libbsp/m68k/csb360/Makefile.am index cce7610faf..3fd41e5d4c 100644 --- a/c/src/lib/libbsp/m68k/csb360/Makefile.am +++ b/c/src/lib/libbsp/m68k/csb360/Makefile.am @@ -27,8 +27,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/sbrk.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/setvec.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c # console -librtemsbsp_a_SOURCES += console/console-io.c -librtemsbsp_a_SOURCES += ../../shared/console-polled.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/csb360/console/console-io.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-polled.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/cache/nocache.c librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/shared/memProbe.c diff --git a/c/src/lib/libbsp/m68k/csb360/console/console-io.c b/c/src/lib/libbsp/m68k/csb360/console/console-io.c deleted file mode 100644 index 9b0aeac5bb..0000000000 --- a/c/src/lib/libbsp/m68k/csb360/console/console-io.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * This file contains the hardware specific portions of the TTY driver - * for the serial ports on the mcf5272 - */ - -/* - * COPYRIGHT (c) 1989-2000. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include - -volatile int g_cnt = 0; - -/* - * console_initialize_hardware - * - * This routine initializes the console hardware. - * - */ - -void console_initialize_hardware(void) -{ -} - - -/* - * console_outbyte_polled - * - * This routine transmits a character using polling. - */ - -void console_outbyte_polled( - int port, - char ch -) -{ - uart_regs_t *uart; - int i; - if (port == 0) { - uart = g_uart0_regs; - } else { - uart = g_uart1_regs; - } - - /* wait for the fifo to make room */ -/* while ((uart->usr & MCF5272_USR_TXRDY) == 0) { */ - while ((uart->ucsr & MCF5272_USR_TXRDY) == 0) { - continue; - } - - uart->udata = ch; - for (i = 0; i < 1000; i++) g_cnt++; -} - -/* - * console_inbyte_nonblocking - * - * This routine polls for a character. - */ - -int console_inbyte_nonblocking( - int port -) -{ - uart_regs_t *uart; - unsigned char c; - - if (port == 0) { - uart = g_uart0_regs; - } else { - uart = g_uart1_regs; - } - -/* if (uart->usr & MCF5272_USR_RXRDY) { */ - if (uart->ucsr & MCF5272_USR_RXRDY) { - c = (char)uart->udata; - return c; - } else { - return -1; - } -} - -#include - -static void mcf5272_output_char(char c) { console_outbyte_polled( 0, c ); } - -BSP_output_char_function_type BSP_output_char = mcf5272_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - diff --git a/c/src/lib/libbsp/m68k/gen68340/Makefile.am b/c/src/lib/libbsp/m68k/gen68340/Makefile.am index c3df13693d..ab20c9dda3 100644 --- a/c/src/lib/libbsp/m68k/gen68340/Makefile.am +++ b/c/src/lib/libbsp/m68k/gen68340/Makefile.am @@ -30,9 +30,9 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/gen68340/clock/ckinit.c # console -librtemsbsp_a_SOURCES += console/console.c -librtemsbsp_a_SOURCES += console/m340uart.c -librtemsbsp_a_SOURCES += ../../shared/dummy_printk_support.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/gen68340/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/gen68340/console/m340uart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/printk-dummy.c # timer librtemsbsp_a_SOURCES += timer/timer.c diff --git a/c/src/lib/libbsp/m68k/gen68340/console/console.c b/c/src/lib/libbsp/m68k/gen68340/console/console.c deleted file mode 100644 index d6634b1079..0000000000 --- a/c/src/lib/libbsp/m68k/gen68340/console/console.c +++ /dev/null @@ -1,690 +0,0 @@ -/* - * 68340/68349 console serial I/O. - */ - -/* - * Author: - * Geoffroy Montel - * France Telecom - CNET/DSM/TAM/CAT - * 4, rue du Clos Courtel - * 35512 CESSON-SEVIGNE - * FRANCE - * - * e-mail: g_montel@yahoo.com - * - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define CONSOLE_VECTOR 121 -#define CONSOLE_IRQ_LEVEL 3 -#define CONSOLE_INTERRUPT_ARBITRATION 2 - -static void *ttypA; /* to remember which tty has been opened on channel A - used when interrupts are enabled */ - -static void *ttypB; /* to remember which tty has been opened on channel B - used when interrupts are enabled */ - -unsigned char DUIER_mirror = 0 ; /* reflects the state of IER register, which is Write Only */ -unsigned char Error_Status_A = 0; /* error status on Channel A */ -unsigned char Error_Status_B = 0; /* error status on Channel A */ - -/* - * Device-specific routines - */ - -#define USE_INTERRUPTS_A (m340_uart_config[UART_CHANNEL_A].mode==UART_INTERRUPTS) -#define USE_INTERRUPTS_B (m340_uart_config[UART_CHANNEL_B].mode==UART_INTERRUPTS) -#define CHANNEL_ENABLED_A m340_uart_config[UART_CHANNEL_A].enable -#define CHANNEL_ENABLED_B m340_uart_config[UART_CHANNEL_B].enable - -#define set_DUIER(a) DUIER_mirror |= (a); DUIER = DUIER_mirror -#define unset_DUIER(a) DUIER_mirror &= ~(a); DUIER = DUIER_mirror - -#define Enable_Interrupts_Tx_A if (USE_INTERRUPTS_A) set_DUIER(m340_TxRDYA) -#define Disable_Interrupts_Tx_A if (USE_INTERRUPTS_A) unset_DUIER(m340_TxRDYA) - -#define Enable_Interrupts_Tx_B if (USE_INTERRUPTS_B) set_DUIER(m340_TxRDYB) -#define Disable_Interrupts_Tx_B if (USE_INTERRUPTS_B) unset_DUIER(m340_TxRDYB) - -/****************************************************** - Name: InterruptHandler - Input parameters: vector number - Output parameters: - - Description: UART ISR Routine, called by _RTEMS_ISR - *****************************************************/ -rtems_isr -InterruptHandler (rtems_vector_number v) -{ - char ch; - - /***************************************************************************** - ** CHANNEL A ** - *****************************************************************************/ - - /* check Received Break*/ - if (DUSRA & m340_RB) { - Error_Status_A |= m340_RB; - /* reset error status */ - DUCRA = m340_Reset_Error_Status; - } - - /* buffer received ? */ - if (DUSRA & m340_Rx_RDY) { - do { - /* error encountered? */ - if (DUSRA & (m340_OE | m340_PE | m340_FE | m340_RB)) { - Error_Status_A |= DUSRA; - /* reset error status */ - DUCRA = m340_Reset_Error_Status; - /* all the characters in the queue may not be good */ - while (DUSRA & m340_Rx_RDY) - /* push them in a trash */ - ch = DURBA; - } - else { - /* this is necessary, otherwise it blocks when FIFO is full */ - ch = DURBA; - rtems_termios_enqueue_raw_characters(ttypA,&ch,1); - } - } while (DUSRA & m340_Rx_RDY); - Restart_Fifo_Full_A_Timer(); /* only if necessary (pointer to a fake function if - not in FIFO full mode) */ - } - - else /* if no character has been received */ - Restart_Check_A_Timer(); /* same remark */ - - /* ready to accept a character ? */ - if (DUISR & DUIER_mirror & m340_TxRDYA) { - Disable_Interrupts_Tx_A; - /* one character has been transmitted */ - rtems_termios_dequeue_characters(ttypA,1); - } - - /***************************************************************************** - ** CHANNEL B ** - *****************************************************************************/ - - /* check Received Break*/ - if (DUSRB & m340_RB) { - Error_Status_B |= m340_RB; - /* reset error status */ - DUCRB = m340_Reset_Error_Status; - } - - /* buffer received ? */ - if (DUSRB & m340_Rx_RDY) { - do { - if (DUSRB & (m340_OE | m340_PE | m340_FE | m340_RB)) { - Error_Status_B |= DUSRB; - /* reset error status */ - DUCRB = m340_Reset_Error_Status; - /* all the characters in the queue may not be good */ - while (DUSRB & m340_Rx_RDY) - /* push them in a trash */ - ch = DURBB; - } - else { - ch = DURBB; - rtems_termios_enqueue_raw_characters(ttypB,&ch,1); - } - - } while (DUSRB & m340_Rx_RDY); - Restart_Fifo_Full_B_Timer(); - } - else /* if no character has been received */ - Restart_Check_B_Timer(); - - /* ready to accept a character ? */ - if (DUISR & DUIER_mirror & m340_TxRDYB) { - Disable_Interrupts_Tx_B; - /* one character has been transmitted */ - rtems_termios_dequeue_characters(ttypB,1); - } -} - -/****************************************************** - Name: InterruptWrite - Input parameters: minor = channel, pointer to buffer, - and length of buffer to transmit - Output parameters: - - Description: write the first character of buf only - may be called by either console_write - or rtems_termios_enqueue_raw_characters - *****************************************************/ -static ssize_t -InterruptWrite (int minor, const char *buf, size_t len) -{ - if (minor==UART_CHANNEL_A) { - if (len>0) { - DUTBA=*buf; - Enable_Interrupts_Tx_A; - } - } - else if (minor==UART_CHANNEL_B) { - if (len>0) { - DUTBB=*buf; - Enable_Interrupts_Tx_B; - } - } - return 0; -} - -/****************************************************** - Name: dbug_out_char - Input parameters: channel, character to emit - Output parameters: - - Description: wait for the UART to be ready to emit - a character and send it - *****************************************************/ -void dbug_out_char( int minor, int ch ) -{ - if (minor==UART_CHANNEL_A) { - while (!(DUSRA & m340_Tx_RDY)) continue; - DUTBA=ch; - } - else if (minor==UART_CHANNEL_B) { - while (!(DUSRB & m340_Tx_RDY)) continue; - DUTBB=ch; - } -} - -/****************************************************** - Name: dbug_in_char - Input parameters: - - Output parameters: received character - Description: return the character in the UART - *****************************************************/ -int dbug_in_char( int minor ) -{ - if (minor==UART_CHANNEL_A) { - return DURBA; - } - else if (minor==UART_CHANNEL_B) { - return DURBB; - } - return 0; -} - -/****************************************************** - Name: dbug_char_present - Input parameters: channel # - Output parameters: TRUE or FALSE - Description: return whether there's a character - in the receive buffer - *****************************************************/ -int dbug_char_present( int minor ) -{ - if (minor==UART_CHANNEL_A) { - return (DUSRA & m340_Rx_RDY); - } - else if (minor==UART_CHANNEL_B) { - return (DUSRB & m340_Rx_RDY); - } - return 0; -} - -/****************************************************** - Name: dbugInitialise - Input parameters: - - Output parameters: - - Description: Init the UART - *****************************************************/ -static void -dbugInitialise (void) -{ - t_baud_speed_table uart_config; /* configuration of UARTS */ - - /* - * Reset Receiver - */ - DUCRA = m340_Reset_Receiver; - DUCRB = m340_Reset_Receiver; - - /* - * Reset Transmitter - */ - DUCRA = m340_Reset_Transmitter; - DUCRB = m340_Reset_Transmitter; - - /* - * Enable serial module for normal operation, ignore FREEZE, select the crystal clock, - * supervisor/user serial registers unrestricted - * interrupt arbitration at priority CONSOLE_INTERRUPT_ARBITRATION - * WARNING : 8 bits access only on this UART! - */ - DUMCRH = 0x00; - DUMCRL = CONSOLE_INTERRUPT_ARBITRATION; - - /* - * Interrupt level register - */ - DUILR = CONSOLE_IRQ_LEVEL; - - /* sets the IVR */ - DUIVR = CONSOLE_VECTOR; - - /* search for a correct m340 uart configuration */ - uart_config = Find_Right_m340_UART_Config(m340_uart_config[UART_CHANNEL_A].rx_baudrate, - m340_uart_config[UART_CHANNEL_A].tx_baudrate, - CHANNEL_ENABLED_A, - m340_uart_config[UART_CHANNEL_B].rx_baudrate, - m340_uart_config[UART_CHANNEL_B].tx_baudrate, - CHANNEL_ENABLED_B); - - /***************************************************************************** - ** CHANNEL A ** - *****************************************************************************/ - if (CHANNEL_ENABLED_A) { - - if (USE_INTERRUPTS_A) { - rtems_isr_entry old_handler; - - (void) rtems_interrupt_catch (InterruptHandler, - CONSOLE_VECTOR, - &old_handler); - - /* uncomment this if you want to pass control to your own ISR handler - it may be usefull to do so to check for performances with an oscilloscope */ - /* - { - proc_ptr ignored; - _CPU_ISR_install_raw_handler( CONSOLE_VECTOR, _Debug_ISR_Handler_Console, &ignored ); - } - */ - - /* - * Interrupt Enable Register - * Enable Interrupts on Channel A Receiver Ready - */ - set_DUIER(m340_RxRDYA); - } - else { - /* - * Disable Interrupts on channel A - */ - unset_DUIER(m340_RxRDYA&m340_TxRDYA); - } - - /* - * Change set of baud speeds - * disable input control - */ - /* no good uart configuration ? */ - if (uart_config.nb<1) rtems_fatal_error_occurred (-1); - - if (uart_config.baud_speed_table[UART_CHANNEL_A].set==1) - DUACR = m340_BRG_Set1; - else - DUACR = m340_BRG_Set2; - - /* - * make OPCR an auxiliary function serving the communication channels - */ - DUOPCR = m340_OPCR_Aux; - - /* poll the XTAL_RDY bit until it is cleared to ensure that an unstable crystal - input is not applied to the baud rate generator */ - while (DUISR & m340_XTAL_RDY) continue; - - /* - * Serial Channel Baud Speed - */ - DUCSRA = (uart_config.baud_speed_table[UART_CHANNEL_A].rcs << 4) - | (uart_config.baud_speed_table[UART_CHANNEL_A].tcs); - - /* - * Serial Channel Configuration - */ - DUMR1A = m340_uart_config[UART_CHANNEL_A].parity_mode - | m340_uart_config[UART_CHANNEL_A].bits_per_char - | m340_RxRTS; - - if (m340_uart_config[UART_CHANNEL_A].rx_mode==UART_FIFO_FULL) DUMR1A |= m340_R_F | m340_ERR; - - /* - * Serial Channel Configuration 2 - */ - DUMR2A |= m340_normal; - - /* - * Enable Channel A: transmitter and receiver - */ - DUCRA = m340_Transmitter_Enable | m340_Receiver_Enable; - } /* channel A enabled */ - - /***************************************************************************** - ** CHANNEL B ** - *****************************************************************************/ - if (CHANNEL_ENABLED_B) { - - /* we mustn't set the console vector twice! */ - if ((USE_INTERRUPTS_B && !(CHANNEL_ENABLED_A)) - || (USE_INTERRUPTS_B && CHANNEL_ENABLED_A && !USE_INTERRUPTS_A)) { - rtems_isr_entry old_handler; - - (void) rtems_interrupt_catch (InterruptHandler, - CONSOLE_VECTOR, - &old_handler); - - /* uncomment this if you want to pass control to your own ISR handler - it may be usefull to do so to check for performances with an oscilloscope */ - /* - { - proc_ptr ignored; - _CPU_ISR_install_raw_handler( CONSOLE_VECTOR, _Debug_ISR_Handler_Console, &ignored ); - } - */ - - /* - * Interrupt Enable Register - * Enable Interrupts on Channel A Receiver Ready - */ - set_DUIER(m340_RxRDYB); - } - else { - /* - * Disable Interrupts on channel B - */ - unset_DUIER(m340_RxRDYB&m340_TxRDYB); - } - - /* - * Change set of baud speeds - * disable input control - */ - - /* no good uart configuration ? */ - if (uart_config.nb<2) rtems_fatal_error_occurred (-1); - - /* don't set DUACR twice! */ - if (!CHANNEL_ENABLED_A) { - if (uart_config.baud_speed_table[UART_CHANNEL_B].set==1) - DUACR = m340_BRG_Set1; - else - DUACR = m340_BRG_Set2; - } - - /* - * make OPCR an auxiliary function serving the communication channels - */ - if (!CHANNEL_ENABLED_A) DUOPCR = m340_OPCR_Aux; - - /* poll the XTAL_RDY bit until it is cleared to ensure that an unstable crystal - input is not applied to the baud rate generator */ - while (DUISR & m340_XTAL_RDY) continue; - - /* - * Serial Channel Baud Speed - */ - DUCSRB = (uart_config.baud_speed_table[UART_CHANNEL_B].rcs << 4) - | (uart_config.baud_speed_table[UART_CHANNEL_B].tcs); - - /* - * Serial Channel Configuration - */ - DUMR1B = m340_uart_config[UART_CHANNEL_B].parity_mode - | m340_uart_config[UART_CHANNEL_B].bits_per_char - | m340_RxRTS; - - if (m340_uart_config[UART_CHANNEL_B].rx_mode==UART_FIFO_FULL) DUMR1B |= m340_R_F | m340_ERR; - - /* - * Serial Channel Configuration 2 - */ - DUMR2B |= m340_normal; - - /* - * Enable Channel A: transmitter and receiver - */ - DUCRB = m340_Transmitter_Enable | m340_Receiver_Enable; - } /* channel B enabled */ -} - -/****************************************************** - Name: SetAttributes - Input parameters: termios structure, channel - Output parameters: - - Description: return whether there's a character - in the receive buffer - TO DO: add the channel # to check for!! - *****************************************************/ -static int -SetAttributes (int minor, const struct termios *t) -{ - rtems_interrupt_level level; - float ispeed, ospeed; - - /* convert it */ - ispeed = rtems_termios_baud_to_number(t->c_ispeed); - ospeed = rtems_termios_baud_to_number(t->c_ospeed); - - if (ispeed || ospeed) { - /* update config table */ - m340_uart_config[UART_CHANNEL_A].rx_baudrate = ((minor==UART_CHANNEL_A)&&(ispeed!=0)) ? ispeed : m340_uart_config[UART_CHANNEL_A].rx_baudrate; - m340_uart_config[UART_CHANNEL_A].tx_baudrate = ((minor==UART_CHANNEL_A)&&(ospeed!=0)) ? ospeed : m340_uart_config[UART_CHANNEL_A].tx_baudrate; - m340_uart_config[UART_CHANNEL_B].rx_baudrate = ((minor==UART_CHANNEL_B)&&(ispeed!=0)) ? ispeed : m340_uart_config[UART_CHANNEL_B].rx_baudrate; - m340_uart_config[UART_CHANNEL_B].tx_baudrate = ((minor==UART_CHANNEL_B)&&(ospeed!=0)) ? ospeed : m340_uart_config[UART_CHANNEL_B].tx_baudrate; - } - - /* change parity */ - if (t->c_cflag & PARENB) { - if (t->c_cflag & PARODD) m340_uart_config[minor].parity_mode = m340_Odd_Parity; - else m340_uart_config[minor].parity_mode = m340_Even_Parity; - } - - /* change bits per character */ - if (t->c_cflag & CSIZE) { - switch (t->c_cflag & CSIZE) { - default: break; - case CS5: m340_uart_config[minor].bits_per_char = m340_5bpc; break; - case CS6: m340_uart_config[minor].bits_per_char = m340_6bpc; break; - case CS7: m340_uart_config[minor].bits_per_char = m340_7bpc; break; - case CS8: m340_uart_config[minor].bits_per_char = m340_8bpc; break; - } - } - - /* if serial module configuration has been changed */ - if (t->c_cflag & (CSIZE | PARENB)) { - rtems_interrupt_disable(level); - /* reinit the UART */ - dbugInitialise(); - rtems_interrupt_enable (level); - } - - return 0; -} - -/****************************************************** - Name: console_initialize - Input parameters: MAJOR # of console_driver, - minor is always 0, - args are always NULL - Output parameters: - - Description: Reserve resources consumed by this driver - TODO: We should pass m340_uart_config table in arg - *****************************************************/ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - int i; - - /* - * Set up TERMIOS - */ - rtems_termios_initialize (); - - /* - * Do device-specific initialization - */ - Init_UART_Table(); - dbugInitialise (); - Fifo_Full_benchmark_timer_initialize(); - - /* - * Register the devices - */ - for (i=0; iiop->data1; - } - else { - sc |= rtems_termios_open (major, minor, arg, &pollCallbacks); - } - } - - else if (minor==UART_CHANNEL_B) { - if (USE_INTERRUPTS_B) { - rtems_libio_open_close_args_t *args = arg; - - sc |= rtems_termios_open (major, minor, arg, &intrCallbacks); - ttypB = args->iop->data1; - } - else { - sc |= rtems_termios_open (major, minor, arg, &pollCallbacks); - } - } - - else return RTEMS_INVALID_NUMBER; - - return sc; -} - -/****************************************************** - Name: console_close - Input parameters: channel #, termios args - Output parameters: - - Description: close the device - *****************************************************/ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_close (arg); -} - -/****************************************************** - Name: console_read - Input parameters: channel #, termios args - Output parameters: - - Description: read the device - *****************************************************/ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_read (arg); -} - -/****************************************************** - Name: console_write - Input parameters: channel #, termios args - Output parameters: - - Description: write to the device - *****************************************************/ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_write (arg); -} - -/****************************************************** - Name: console_control - Input parameters: channel #, termios args - Output parameters: - - Description: Handle ioctl request - *****************************************************/ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_ioctl_args_t *args = arg; - - if (args->command == TIOCSETA) - SetAttributes (minor, (struct termios *)args->buffer); - - return rtems_termios_ioctl (arg); -} diff --git a/c/src/lib/libbsp/m68k/gen68340/console/m340uart.c b/c/src/lib/libbsp/m68k/gen68340/console/m340uart.c deleted file mode 100644 index 56ad29c256..0000000000 --- a/c/src/lib/libbsp/m68k/gen68340/console/m340uart.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * M68340/349 UART management tools - */ - -/* - * Author: - * Geoffroy Montel - * France Telecom - CNET/DSM/TAM/CAT - * 4, rue du Clos Courtel - * 35512 CESSON-SEVIGNE - * FRANCE - * - * e-mail: g_montel@yahoo.com - * - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include -#include -#include - -/* this table shows compatible speed configurations for the MC68340: - the first row shows baud rates for baud speed set 1 - the second row shows baud rates for baud speed set 2 - look at Motorola's MC68340 Integrated Processor User's Manual - page 7-30 for more infos */ - -float m340_Baud_Rates_Table[16][2] = { - { 50, 75 }, - { 110, 110 }, - { 134.5, 134.5 }, - { 200, 150 }, - { 300, 300 }, - { 600, 600 }, - { 1200, 1200 }, - { 1050, 2000 }, - { 2400, 2400 }, - { 4800, 4800 }, - { 7200, 1800 }, - { 9600, 9600 }, - { 38400, 19200 }, - { 76800, 38400 }, - { SCLK/16, SCLK/16}, - { SCLK, SCLK }, -}; - -/* config on both 340 channels */ -uart_channel_config m340_uart_config[UART_NUMBER_OF_CHANNELS]; - -/* - * Init UART table - */ - -#define NOT_IMPLEMENTED_YET 0 - -/****************************************************** - Name: Init_UART_Table - Input parameters: - - Output parameters: - - Description: Init the m340_uart_config - THIS SHOULD NOT BE HERE! - Its aim was to let the user configure - UARTs for each application. - As we can't pass args to the console - driver initialisation routine at the - moment, this was not done. - ATTENTION: TERMIOS init presupposes that the channel - baud rates is 9600/9600. - -> risks when using IOCTL - *****************************************************/ -void Init_UART_Table(void) -{ - m340_uart_config[UART_CHANNEL_A].enable = TRUE; - strcpy(m340_uart_config[UART_CHANNEL_A].name, UART_CONSOLE_NAME); - m340_uart_config[UART_CHANNEL_A].parity_mode = m340_No_Parity; - m340_uart_config[UART_CHANNEL_A].bits_per_char = m340_8bpc; - m340_uart_config[UART_CHANNEL_A].rx_baudrate = 9600; - m340_uart_config[UART_CHANNEL_A].tx_baudrate = 9600; - m340_uart_config[UART_CHANNEL_A].rx_mode = UART_CRR; - m340_uart_config[UART_CHANNEL_A].mode = UART_POLLING; - - m340_uart_config[UART_CHANNEL_A].termios.enable = TRUE; - m340_uart_config[UART_CHANNEL_A].termios.rx_buffer_size = NOT_IMPLEMENTED_YET; - m340_uart_config[UART_CHANNEL_A].termios.tx_buffer_size = NOT_IMPLEMENTED_YET; - - m340_uart_config[UART_CHANNEL_B].enable = FALSE; - strcpy(m340_uart_config[UART_CHANNEL_B].name, UART_RAW_IO_NAME); - m340_uart_config[UART_CHANNEL_B].parity_mode = m340_No_Parity; - m340_uart_config[UART_CHANNEL_B].bits_per_char = m340_8bpc; - m340_uart_config[UART_CHANNEL_B].rx_baudrate = 38400; - m340_uart_config[UART_CHANNEL_B].tx_baudrate = 38400; - m340_uart_config[UART_CHANNEL_B].rx_mode = UART_CRR; - m340_uart_config[UART_CHANNEL_B].mode = UART_INTERRUPTS; - - m340_uart_config[UART_CHANNEL_B].termios.enable = TRUE; - m340_uart_config[UART_CHANNEL_B].termios.rx_buffer_size = NOT_IMPLEMENTED_YET; - m340_uart_config[UART_CHANNEL_B].termios.tx_buffer_size = NOT_IMPLEMENTED_YET; -} - -/****************************************************** - Name: Find_Right_m340_UART_Channel_Config - Input parameters: Send/Receive baud rates for a - given channel - Output parameters: UART compatible configs for this - channel - Description: returns which uart configurations fit - Receiver Baud Rate and Transmitter Baud - Rate for a given channel - For instance, according to the - m340_Baud_Rates_Table: - - Output Speed = 50, Input Speed = 75 - is not a correct config, because - 50 bauds implies set 1 and 75 bauds - implies set 2 - - Output Speed = 9600, Input Speed = 9600 - two correct configs for this: - RCS=11, TCS=11, Set=1 or 2 - *****************************************************/ -static t_baud_speed_table -Find_Right_m340_UART_Channel_Config( - float ReceiverBaudRate, - float TransmitterBaudRate -) -{ - t_baud_speed_table return_value; - int i,j; - - struct { - int cs; - int set; - } Receiver[2], Transmitter[2]; - - int Receiver_nb_of_config = 0; - int Transmitter_nb_of_config = 0; - - /* Receiver and Transmitter baud rates must be compatible, ie in the - * same set. - */ - - /* search for configurations for ReceiverBaudRate - * there can't be more than two (only two sets). - */ - for (i=0;i<16;i++) { - for (j=0;j<2;j++) { - if (m340_Baud_Rates_Table[i][j]==ReceiverBaudRate) { - Receiver[Receiver_nb_of_config].cs=i; - Receiver[Receiver_nb_of_config].set=j; - Receiver_nb_of_config++; - } - } - } - - /* search for configurations for TransmitterBaudRate - * there can't be more than two (only two sets) - */ - for (i=0;i<16;i++) { - for (j=0;j<2;j++) { - if (m340_Baud_Rates_Table[i][j]==TransmitterBaudRate) { - Transmitter[Transmitter_nb_of_config].cs=i; - Transmitter[Transmitter_nb_of_config].set=j; - Transmitter_nb_of_config++; - } - } - } - - /* now check if there's a compatible config */ - return_value.nb=0; - - for (i=0; i -#include -#include -#include -#include -#include - -/* - * Declare clock speed -- may be overwritten by downloader or debugger - */ -int m360_clock_rate = 25000000; - -/* - * Interrupt-driven input buffer - * Declare console baud rate -- may also be overwritten - */ -int console_baud_rate = 9600; - -/* - */ -#define RXBUFSIZE 16 - -/* - * Interrupt-driven callback - */ -static int m360_smc1_interrupt = 1; -static void *smc1ttyp; - -/* - * I/O buffers and pointers to buffer descriptors - */ -static volatile char rxBuf[RXBUFSIZE]; -static volatile m360BufferDescriptor_t *smcRxBd, *smcTxBd; - -/* - * Device-specific routines - */ - -/* - * Compute baud-rate-generator configuration register value - */ -static int -smc1BRGC (int baud) -{ - int divisor; - int div16 = 0; - - divisor = ((m360_clock_rate / 16) + (baud / 2)) / baud; - if (divisor > 4096) { - div16 = 1; - divisor = (divisor + 8) / 16; - } - return M360_BRG_EN | M360_BRG_EXTC_BRGCLK | ((divisor - 1) << 1) | div16; -} - -/* - * Hardware-dependent portion of tcsetattr(). - */ -static int -smc1SetAttributes (int minor, const struct termios *t) -{ - int baud; - - baud = rtems_termios_baud_to_number(t->c_ospeed); - if (baud > 0) - m360.brgc1 = smc1BRGC (baud); - return 0; -} - -/* - * Interrupt handler - */ -static rtems_isr -smc1InterruptHandler (rtems_vector_number v) -{ - /* - * Buffer received? - */ - if (m360.smc1.smce & 0x1) { - m360.smc1.smce = 0x1; - while ((smcRxBd->status & M360_BD_EMPTY) == 0) { - rtems_termios_enqueue_raw_characters (smc1ttyp, - (char *)smcRxBd->buffer, - smcRxBd->length); - smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT; - } - } - - /* - * Buffer transmitted? - */ - if (m360.smc1.smce & 0x2) { - m360.smc1.smce = 0x2; - if ((smcTxBd->status & M360_BD_READY) == 0) - rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length); - } - m360.cisr = 1UL << 4; /* Clear SMC1 interrupt-in-service bit */ -} - -static int -smc1Initialize (int major, int minor, void *arg) -{ - /* - * Allocate buffer descriptors - */ - smcRxBd = M360AllocateBufferDescriptors (1); - smcTxBd = M360AllocateBufferDescriptors (1); - - /* - * Configure port B pins to enable SMTXD1 and SMRXD1 pins - */ - m360.pbpar |= 0xC0; - m360.pbdir &= ~0xC0; - m360.pbodr &= ~0xC0; - - /* - * Set up BRG1 (9,600 baud) - */ - m360.brgc1 = M360_BRG_RST; - m360.brgc1 = smc1BRGC (console_baud_rate); - - /* - * Put SMC1 in NMSI mode, connect SMC1 to BRG1 - */ - m360.simode |= M360_SI_SMC1_BRG1; - - /* - * Set up SMC1 parameter RAM common to all protocols - */ - m360.smc1p.rbase = (char *)smcRxBd - (char *)&m360; - m360.smc1p.tbase = (char *)smcTxBd - (char *)&m360; - m360.smc1p.rfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE; - m360.smc1p.tfcr = M360_TFCR_MOT | M360_TFCR_DMA_SPACE; - if (m360_smc1_interrupt) - m360.smc1p.mrblr = RXBUFSIZE; - else - m360.smc1p.mrblr = 1; - - /* - * Set up SMC1 parameter RAM UART-specific parameters - */ - m360.smc1p.un.uart.max_idl = 10; - m360.smc1p.un.uart.brklen = 0; - m360.smc1p.un.uart.brkec = 0; - m360.smc1p.un.uart.brkcr = 0; - - /* - * Set up the Receive Buffer Descriptor - */ - smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT; - smcRxBd->length = 0; - smcRxBd->buffer = rxBuf; - - /* - * Setup the Transmit Buffer Descriptor - */ - smcTxBd->status = M360_BD_WRAP; - - /* - * Set up SMC1 general and protocol-specific mode registers - */ - m360.smc1.smce = ~0; /* Clear any pending events */ - m360.smc1.smcm = 0; /* Mask all interrupt/event sources */ - m360.smc1.smcmr = M360_SMCMR_CLEN(9) | M360_SMCMR_SM_UART; - - /* - * Send "Init parameters" command - */ - M360ExecuteRISC (M360_CR_OP_INIT_RX_TX | M360_CR_CHAN_SMC1); - - /* - * Enable receiver and transmitter - */ - m360.smc1.smcmr |= M360_SMCMR_TEN | M360_SMCMR_REN; - - if (m360_smc1_interrupt) { - rtems_isr_entry old_handler; - - (void) rtems_interrupt_catch (smc1InterruptHandler, - (m360.cicr & 0xE0) | 0x04, - &old_handler); - m360.smc1.smcm = 3; /* Enable SMC1 TX and RX interrupts */ - m360.cimr |= 1UL << 4; /* Enable SMC1 interrupts */ - } - - return 0; -} - -static int -smc1PollRead (int minor) -{ - unsigned char c; - - if (smcRxBd->status & M360_BD_EMPTY) - return -1; - c = rxBuf[0]; - smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP; - return c; -} - -/* - * Device-dependent write routine - * Interrupt-driven devices: - * Begin transmission of as many characters as possible (minimum is 1). - * Polling devices: - * Transmit all characters. - */ -static ssize_t -smc1InterruptWrite (int minor, const char *buf, size_t len) -{ - if (len > 0) { - smcTxBd->buffer = (char *)buf; - smcTxBd->length = len; - smcTxBd->status = M360_BD_READY | M360_BD_WRAP | M360_BD_INTERRUPT; - } - - return 0; -} - -static ssize_t -smc1PollWrite (int minor, const char *buf, size_t len) -{ - size_t retval = len; - while (len--) { - static char txBuf; - while (smcTxBd->status & M360_BD_READY) - continue; - txBuf = *buf++; - smcTxBd->buffer = &txBuf; - smcTxBd->length = 1; - smcTxBd->status = M360_BD_READY | M360_BD_WRAP; - } - return retval; -} - -/* - *************** - * BOILERPLATE * - *************** - */ - -/* - * Reserve resources consumed by this driver - * - * NOTE: This is in another file to reduce dependencies on the minimum size. - */ - -/* - * Initialize and register the device - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - - /* - * Set up TERMIOS - */ - rtems_termios_initialize (); - - /* - * Register the device - */ - status = rtems_io_register_name ("/dev/console", major, 0); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - return RTEMS_SUCCESSFUL; -} - -/* - * Open the device - */ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_status_code sc; - static const rtems_termios_callbacks intrCallbacks = { - smc1Initialize, /* firstOpen */ - NULL, /* lastClose */ - NULL, /* pollRead */ - smc1InterruptWrite, /* write */ - smc1SetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - 1 /* outputUsesInterrupts */ - }; - static const rtems_termios_callbacks pollCallbacks = { - smc1Initialize, /* firstOpen */ - NULL, /* lastClose */ - smc1PollRead, /* pollRead */ - smc1PollWrite, /* write */ - smc1SetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - 0 /* outputUsesInterrupts */ - }; - - /* - * Do generic termios initialization - */ - if (m360_smc1_interrupt) { - rtems_libio_open_close_args_t *args = arg; - - sc = rtems_termios_open (major, minor, arg, &intrCallbacks); - smc1ttyp = args->iop->data1; - } - else { - sc = rtems_termios_open (major, minor, arg, &pollCallbacks); - } - return sc; -} - -/* - * Close the device - */ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_close (arg); -} - -/* - * Read from the device - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_read (arg); -} - -/* - * Write to the device - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_write (arg); -} - -/* - * Handle ioctl request. - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_ioctl (arg); -} diff --git a/c/src/lib/libbsp/m68k/genmcf548x/Makefile.am b/c/src/lib/libbsp/m68k/genmcf548x/Makefile.am index a20f56ad89..3ba91a7f92 100644 --- a/c/src/lib/libbsp/m68k/genmcf548x/Makefile.am +++ b/c/src/lib/libbsp/m68k/genmcf548x/Makefile.am @@ -33,7 +33,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/getentropy/getentropy # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/genmcf548x/clock/clock.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/genmcf548x/console/console.c # timer librtemsbsp_a_SOURCES += timer/timer.c diff --git a/c/src/lib/libbsp/m68k/genmcf548x/console/console.c b/c/src/lib/libbsp/m68k/genmcf548x/console/console.c deleted file mode 100644 index 32e5601a17..0000000000 --- a/c/src/lib/libbsp/m68k/genmcf548x/console/console.c +++ /dev/null @@ -1,843 +0,0 @@ -/*===============================================================*\ -| Project: RTEMS generic mcf548x BSP | -+-----------------------------------------------------------------+ -| File: console.c | -+-----------------------------------------------------------------+ -| The file contains the console driver code of generic MCF548x | -| BSP. | -+-----------------------------------------------------------------+ -| Copyright (c) 2007 | -| Embedded Brains GmbH | -| Obere Lagerstr. 30 | -| D-82178 Puchheim | -| Germany | -| rtems@embedded-brains.de | -+-----------------------------------------------------------------+ -| | -| Parts of the code has been derived from the "dBUG source code" | -| package Freescale is providing for M548X EVBs. The usage of | -| the modified or unmodified code and it's integration into the | -| generic mcf548x BSP has been done according to the Freescale | -| license terms. | -| | -| The Freescale license terms can be reviewed in the file | -| | -| Freescale_license.txt | -| | -+-----------------------------------------------------------------+ -| | -| The generic mcf548x BSP has been developed on the basic | -| structures and modules of the av5282 BSP. | -| | -+-----------------------------------------------------------------+ -| | -| The license and distribution terms for this file may be | -| found in the file LICENSE in this distribution or at | -| | -| http://www.rtems.org/license/LICENSE. | -| | -+-----------------------------------------------------------------+ -| | -| date history ID | -| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | -| 12.11.07 1.0 ras | -| | -\*===============================================================*/ - - /* - * Multi UART console serial I/O. - * - * TO DO: Add DMA input/output - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define UART_INTC0_IRQ_VECTOR(x) (64+35-(x)) - -#define MCF548X_PSC_SR_ERROR ( MCF548X_PSC_SR_RB_NEOF | \ - MCF548X_PSC_SR_FE_PHYERR | \ - MCF548X_PSC_SR_PE_CRCERR | \ - MCF548X_PSC_SR_OE ) - -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); -static int IntUartPollRead (int minor); -static int IntUartSetAttributes(int minor, const struct termios *t); - -static void -psc_output_char( char c ) -{ - rtems_interrupt_level level; - - rtems_interrupt_disable(level); - while (!((MCF548X_PSC_SR(CONSOLE_PORT) & MCF548X_PSC_SR_TXRDY))) - continue; - *((uint8_t *) &MCF548X_PSC_TB(CONSOLE_PORT)) = c; - while (!((MCF548X_PSC_SR(CONSOLE_PORT) & MCF548X_PSC_SR_TXRDY))) - continue; - rtems_interrupt_enable(level); -} - -static void -psc_output_char_init(char c) -{ - IntUartSetAttributes(CONSOLE_PORT, NULL); - BSP_output_char = psc_output_char; - psc_output_char(c); -} - -BSP_output_char_function_type BSP_output_char = psc_output_char_init; - -BSP_polling_getchar_function_type BSP_poll_char = NULL; - -#define MAX_UART_INFO 4 -#define RX_BUFFER_SIZE 248 - -struct IntUartInfoStruct -{ - int iomode; - volatile int imr; - int baud; - int databits; - int parity; - int stopbits; - int hwflow; - int rx_in; - int rx_out; - char rx_buffer[RX_BUFFER_SIZE]; - void *ttyp; -}; - -struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; - -static int GetBaud( int baudHandle ) -{ - int baud = BSP_CONSOLE_BAUD; - switch(baudHandle) - { - case B0: - baud = (int)0; - break; - case B1200: - baud = (int)1200; - break; - case B2400: - baud = (int)2400; - break; - case B4800: - baud = (int)4800; - break; - case B9600: - baud = (int)9600; - break; - case B19200: - baud = (int)19200; - break; - case B38400: - baud = (int)38400; - break; - case B57600: - baud = (int)57600; - break; - case B115200: - baud = (int)115200; - break; - } - return baud; -} - -/*************************************************************************** - Function : IntUartSet - - Description : This updates the hardware UART settings. - ***************************************************************************/ -static void -IntUartSet(int minor, int baud, int databits, int parity, int stopbits, int hwflow) -{ - uint8_t psc_mode_1 = 0, psc_mode_2 = 0; - uint16_t divider; - int level; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - rtems_interrupt_disable(level); - - /* disable interrupts, clear RTS line, and disable the UARTS */ - /* Mask all psc interrupts */ - MCF548X_PSC_IMR(minor) = 0x0000; - - /* Clear RTS to send */ - MCF548X_PSC_OPSET(minor) &= ~(MCF548X_PSC_OPSET_RTS); - - /* Disable receiver and transmitter */ - MCF548X_PSC_CR(minor) &= ~(MCF548X_PSC_CR_RX_ENABLED | MCF548X_PSC_CR_TX_ENABLED); - - /* provide gpio settings */ - switch (minor) - { - case 0: - MCF548X_GPIO_PAR_PSC0 = (0 | MCF548X_GPIO_PAR_PSC0_PAR_TXD0 | MCF548X_GPIO_PAR_PSC0_PAR_RXD0); - - if(hwflow) - { - MCF548X_GPIO_PAR_PSC0 |= (0 | MCF548X_GPIO_PAR_PSC0_PAR_CTS0_CTS | MCF548X_GPIO_PAR_PSC0_PAR_RTS0_RTS); - } - break; - case 1: - MCF548X_GPIO_PAR_PSC1 = (0 | MCF548X_GPIO_PAR_PSC1_PAR_TXD1 | MCF548X_GPIO_PAR_PSC1_PAR_RXD1); - - if(hwflow) - { - MCF548X_GPIO_PAR_PSC1 |= (0 | MCF548X_GPIO_PAR_PSC1_PAR_CTS1_CTS | MCF548X_GPIO_PAR_PSC1_PAR_RTS1_RTS); - } - break; - case 2: - MCF548X_GPIO_PAR_PSC2 = (0 | MCF548X_GPIO_PAR_PSC2_PAR_TXD2 | MCF548X_GPIO_PAR_PSC2_PAR_RXD2); - - if(hwflow) - { - MCF548X_GPIO_PAR_PSC2 |= (0 | MCF548X_GPIO_PAR_PSC2_PAR_CTS2_CTS | MCF548X_GPIO_PAR_PSC2_PAR_RTS2_RTS); - } - break; - case 3: - MCF548X_GPIO_PAR_PSC3 = (0 | MCF548X_GPIO_PAR_PSC3_PAR_TXD3 | MCF548X_GPIO_PAR_PSC3_PAR_RXD3); - - if(hwflow) - { - MCF548X_GPIO_PAR_PSC3 |= (0 | MCF548X_GPIO_PAR_PSC3_PAR_CTS3_CTS | MCF548X_GPIO_PAR_PSC3_PAR_RTS3_RTS); - } - break; - default: - break; - } - - /* save the current values */ - info->imr = 0; - info->baud = baud; - info->databits = databits; - info->parity = parity; - info->stopbits = stopbits; - info->hwflow = hwflow; - - /* Put PSC in UART mode */ - MCF548X_PSC_SICR(minor) = MCF548X_PSC_SICR_SIM_UART; - - /* set the baud rate values */ - MCF548X_PSC_CSR(minor) = (0 | MCF548X_PSC_CSR_RCSEL_SYS_CLK | MCF548X_PSC_CSR_TCSEL_SYS_CLK); - - /* Calculate baud settings */ - divider = (uint16_t)((get_CPU_clock_speed())/(baud * 32)); - MCF548X_PSC_CTUR(minor) = (uint8_t) ((divider >> 8) & 0xFF); - MCF548X_PSC_CTLR(minor) = (uint8_t) (divider & 0xFF); - - /* Reset transmitter, receiver, mode register, and error conditions */ - MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_RX; - MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_TX; - MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_ERROR; - MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_BKCHGINT; - MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_MR; - - /* check to see if doing hardware flow control */ - if ( hwflow ) - { - /* set hardware flow options */ - psc_mode_1 = MCF548X_PSC_MR_RXRTS; - psc_mode_2 = MCF548X_PSC_MR_TXCTS; - } - - /* set mode registers */ - psc_mode_1 |= (uint8_t)(parity | databits); - psc_mode_2 |= (uint8_t)(stopbits); - - /* set mode registers */ - MCF548X_PSC_MR(minor) = psc_mode_1; - MCF548X_PSC_MR(minor) = psc_mode_2; - - /* Setup FIFO Alarms */ - MCF548X_PSC_RFAR(minor) = MCF548X_PSC_RFAR_ALARM(248); - MCF548X_PSC_TFAR(minor) = MCF548X_PSC_TFAR_ALARM(248); - - /* check to see if interrupts need to be enabled */ - if ( info->iomode != TERMIOS_POLLED ) - { - /* enable rx interrupts */ - info->imr |= MCF548X_PSC_IMR_RXRDY_FU; - MCF548X_PSC_IMR(minor) = info->imr; - } - - /* check to see if doing hardware flow control */ - if ( hwflow ) - { - /* assert the RTS line */ - MCF548X_PSC_OPSET(minor) = MCF548X_PSC_OPSET_RTS; - } - - rtems_interrupt_enable(level); - - /* Enable receiver and transmitter */ - MCF548X_PSC_CR(minor) =(0 | MCF548X_PSC_CR_RX_ENABLED | MCF548X_PSC_CR_TX_ENABLED); - - -} - -/*************************************************************************** - Function : IntUartSetAttributes - - Description : This provides the hardware-dependent portion of tcsetattr(). - value and sets it. At the moment this just sets the baud rate. - - Note: The highest baudrate is 115200 as this stays within - an error of +/- 5% at 25MHz processor clock - ***************************************************************************/ -static int -IntUartSetAttributes(int minor, const struct termios *t) -{ -/* set default index values */ -#ifdef HAS_DBUG - int baud = DBUG_SETTINGS.console_baudrate; -#else - int baud = (int)BSP_CONSOLE_BAUD; -#endif - int databits = (int)MCF548X_PSC_MR_BC_8; - int parity = (int)MCF548X_PSC_MR_PM_NONE; - int stopbits = (int)MCF548X_PSC_MR_SB_STOP_BITS_1; - int hwflow = (int)1; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* check to see if input is valid */ - if ( t != (const struct termios *)0 ) - { - /* determine baud rate index */ - baud = GetBaud( t->c_ospeed ); - - /* determine data bits */ - switch ( t->c_cflag & CSIZE ) - { - case CS5: - databits = (int)MCF548X_PSC_MR_BC_5; - break; - case CS6: - databits = (int)MCF548X_PSC_MR_BC_6; - break; - case CS7: - databits = (int)MCF548X_PSC_MR_BC_7; - break; - case CS8: - databits = (int)MCF548X_PSC_MR_BC_8; - break; - } - - /* determine if parity is enabled */ - if ( t->c_cflag & PARENB ) - { - if ( t->c_cflag & PARODD ) - { - /* odd parity */ - parity = (int)MCF548X_PSC_MR_PM_ODD; - } - else - { - /* even parity */ - parity = (int)MCF548X_PSC_MR_PM_EVEN; - } - } - - /* determine stop bits */ - if ( t->c_cflag & CSTOPB ) - { - /* two stop bits */ - stopbits = (int)MCF548X_PSC_MR_SB_STOP_BITS_2; - } - - /* check to see if hardware flow control */ - if ( t->c_cflag & CRTSCTS ) - { - hwflow = 1; - } - } - - /* check to see if values have changed */ - if ( ( baud != info->baud ) || - ( databits != info->databits ) || - ( parity != info->parity ) || - ( stopbits != info->stopbits ) || - ( hwflow != info->hwflow ) ) - { - - /* call function to set values */ - IntUartSet(minor, baud, databits, parity, stopbits, hwflow); - } - -return RTEMS_SUCCESSFUL; - -} - -/*************************************************************************** - Function : IntUartInterruptHandler - - Description : This is the interrupt handler for the internal uart. It - determines which channel caused the interrupt before queueing any received - chars and dequeueing chars waiting for transmission. - ***************************************************************************/ -static rtems_isr -IntUartInterruptHandler(rtems_vector_number v) -{ - unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); - struct IntUartInfoStruct *info = &IntUartInfo[chan]; - - /* check to see if received data */ - if ( MCF548X_PSC_ISR(chan) & MCF548X_PSC_ISR_RXRDY_FU ) - { - /* read data and put into the receive buffer */ - while ( MCF548X_PSC_SR(chan) & MCF548X_PSC_SR_RXRDY ) - { - - /* put data in rx buffer */ - info->rx_buffer[info->rx_in] = *((volatile uint8_t *)&MCF548X_PSC_RB(chan)); - - /* check for errors */ - if ( MCF548X_PSC_SR(chan) & MCF548X_PSC_SR_ERROR ) - { - /* clear the error */ - MCF548X_PSC_CR(chan) = MCF548X_PSC_CR_RESET_ERROR; - } - - /* update buffer values */ - info->rx_in++; - - if ( info->rx_in >= RX_BUFFER_SIZE ) - { - info->rx_in = 0; - } - } - /* Make sure the port has been opened */ - if ( info->ttyp ) - { - - /* check to see if task driven */ - if ( info->iomode == TERMIOS_TASK_DRIVEN ) - { - /* notify rx task that rx buffer has data */ - rtems_termios_rxirq_occured(info->ttyp); - } - else - { - /* Push up the received data */ - rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, info->rx_in); - info->rx_in = 0; - } - } - } - - /* check to see if data needs to be transmitted */ - if ( ( info->imr & MCF548X_PSC_IMR_TXRDY ) && - ( MCF548X_PSC_ISR(chan) & MCF548X_PSC_ISR_TXRDY ) ) - { - - /* disable tx interrupts */ - info->imr &= ~MCF548X_PSC_IMR_TXRDY; - MCF548X_PSC_IMR(chan) = info->imr; - - /* tell upper level that character has been sent */ - if ( info->ttyp ) - rtems_termios_dequeue_characters(info->ttyp, 1); - } - -} - -/*************************************************************************** - Function : IntUartInitialize - - Description : This initialises the internal uart hardware for all - internal uarts. If the internal uart is to be interrupt driven then the - interrupt vectors are hooked. - ***************************************************************************/ -static void -IntUartInitialize(void) -{ - unsigned int chan; - struct IntUartInfoStruct *info; - rtems_isr_entry old_handler; - - for ( chan = 0; chan < MAX_UART_INFO; chan++ ) - { - info = &IntUartInfo[chan]; - - info->ttyp = NULL; - info->rx_in = 0; - info->rx_out = 0; - info->baud = -1; - info->databits = -1; - info->parity = -1; - info->stopbits = -1; - info->hwflow = -1; - - MCF548X_PSC_ACR(chan) = 0; - MCF548X_PSC_IMR(chan) = 0; - if ( info->iomode != TERMIOS_POLLED ) - { - rtems_interrupt_catch (IntUartInterruptHandler, - UART_INTC0_IRQ_VECTOR(chan), - &old_handler); - } - - /* set uart default values */ - IntUartSetAttributes(chan, NULL); - - /* unmask interrupt */ - bsp_interrupt_vector_enable(MCF548X_IRQ_PSC(chan)); - } /* of chan loop */ - - BSP_output_char = psc_output_char; -} /* IntUartInitialise */ - -/*************************************************************************** - Function : IntUartInterruptWrite - - Description : This writes a single character to the appropriate uart - channel. This is either called during an interrupt or in the user's task - to initiate a transmit sequence. Calling this routine enables Tx - interrupts. - ***************************************************************************/ -static ssize_t -IntUartInterruptWrite (int minor, const char *buf, size_t len) -{ - if (len > 0) { - /* write out character */ - *(volatile uint8_t *)(&MCF548X_PSC_TB(minor)) = *buf; - - /* enable tx interrupt */ - IntUartInfo[minor].imr |= MCF548X_PSC_IMR_TXRDY; - MCF548X_PSC_IMR(minor) = IntUartInfo[minor].imr; - } - - return 0; -} - -/*************************************************************************** - Function : IntUartInterruptOpen - - Description : This enables interrupts when the tty is opened. - ***************************************************************************/ -static int -IntUartInterruptOpen(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* enable the uart */ - MCF548X_PSC_CR(minor) = (MCF548X_PSC_CR_TX_ENABLED | MCF548X_PSC_CR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if ( info->iomode != TERMIOS_POLLED ) - { - /* enable rx interrupts */ - info->imr |= MCF548X_PSC_IMR_RXRDY_FU; - MCF548X_PSC_IMR(minor) = info->imr; - } - - /* check to see if doing hardware flow control */ - if ( info->hwflow ) - { - /* assert the RTS line */ - MCF548X_PSC_OPSET(minor) = MCF548X_PSC_OPSET_RTS; - } - - return 0; -} - - -/*************************************************************************** - Function : IntUartInterruptClose - - Description : This disables interrupts when the tty is closed. - ***************************************************************************/ -static int -IntUartInterruptClose(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* disable the interrupts and the uart */ - MCF548X_PSC_IMR(minor) = 0; - MCF548X_PSC_CR(minor) = (MCF548X_PSC_CR_TX_ENABLED | MCF548X_PSC_CR_RX_ENABLED); - - /* reset values */ - info->ttyp = NULL; - info->imr = 0; - info->rx_in = 0; - info->rx_out = 0; - - return 0; -} - -/*************************************************************************** - Function : IntUartTaskRead - - Description : This reads all available characters from the internal uart - and places them into the termios buffer. The rx interrupts will be - re-enabled after all data has been read. - ***************************************************************************/ -static int -IntUartTaskRead(int minor) -{ - char buffer[RX_BUFFER_SIZE]; - int count; - int rx_in; - int index = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* determine number of values to copy out */ - rx_in = info->rx_in; - if ( info->rx_out <= rx_in ) - { - count = rx_in - info->rx_out; - } - else - { - count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; - } - - /* copy data into local buffer from rx buffer */ - while ( ( index < count ) && ( index < RX_BUFFER_SIZE ) ) - { - /* copy data byte */ - buffer[index] = info->rx_buffer[info->rx_out]; - index++; - - /* increment rx buffer values */ - info->rx_out++; - if ( info->rx_out >= RX_BUFFER_SIZE ) - { - info->rx_out = 0; - } - } - - /* check to see if buffer is not empty */ - if ( count > 0 ) - { - /* set characters into termios buffer */ - rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); - } - - return EOF; -} - - -/*************************************************************************** - Function : IntUartPollRead - - Description : This reads a character from the internal uart. It returns - to the caller without blocking if not character is waiting. - ***************************************************************************/ -static int -IntUartPollRead (int minor) -{ -if (!((MCF548X_PSC_SR(minor) & MCF548X_PSC_SR_RXRDY))) - return(-1); - - return *((uint8_t *)&MCF548X_PSC_RB(minor)); -} - - -/*************************************************************************** - Function : IntUartPollWrite - - Description : This writes out each character in the buffer to the - appropriate internal uart channel waiting till each one is sucessfully - transmitted. - ***************************************************************************/ -static ssize_t -IntUartPollWrite (int minor, const char *buf, size_t len) -{ - size_t retval = len; -/* loop over buffer */ - while ( len-- ) - { - /* block until we can transmit */ - while (!((MCF548X_PSC_SR(minor) & MCF548X_PSC_SR_TXRDY))) - continue; - /* transmit data byte */ - *((uint8_t *)&MCF548X_PSC_TB(minor)) = *buf++; - } - return retval; -} - -/*************************************************************************** - Function : console_initialize - - Description : This initialises termios, both sets of uart hardware before - registering /dev/tty devices for each channel and the system /dev/console. - ***************************************************************************/ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg ) -{ - rtems_status_code status; - - - /* Set up TERMIOS */ - rtems_termios_initialize (); - - /* set io modes for the different channels and initialize device */ - IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN; //TERMIOS_POLLED; - IntUartInitialize(); - - /* Register the console port */ - status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - - /* Register the other port */ - if ( CONSOLE_PORT != 0 ) - { - status = rtems_io_register_name ("/dev/tty00", major, 0); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - } - if ( CONSOLE_PORT != 1 ) - { - status = rtems_io_register_name ("/dev/tty01", major, 1); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - } - - return(RTEMS_SUCCESSFUL); -} - -/*************************************************************************** - Function : console_open - - Description : This actually opens the device depending on the minor - number set during initialisation. The device specific access routines are - passed to termios when the devices is opened depending on whether it is - polled or not. - ***************************************************************************/ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - rtems_status_code status = RTEMS_INVALID_NUMBER; - rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *)arg; - struct IntUartInfoStruct *info; - - static const rtems_termios_callbacks IntUartPollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - IntUartPollRead, /* pollRead */ - IntUartPollWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_POLLED /* mode */ - }; - static const rtems_termios_callbacks IntUartIntrCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - NULL, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_IRQ_DRIVEN /* mode */ - }; - - static const rtems_termios_callbacks IntUartTaskCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - IntUartTaskRead, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_TASK_DRIVEN /* mode */ - }; - - /* open the port depending on the minor device number */ - if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) ) - { - info = &IntUartInfo[minor]; - switch ( info->iomode ) - { - case TERMIOS_POLLED: - status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); - break; - case TERMIOS_IRQ_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); - info->ttyp = args->iop->data1; - break; - case TERMIOS_TASK_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); - info->ttyp = args->iop->data1; - break; - } - } - - return( status ); -} - -/*************************************************************************** - Function : console_close - - Description : This closes the device via termios - ***************************************************************************/ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return(rtems_termios_close (arg)); -} - -/*************************************************************************** - Function : console_read - - Description : Read from the device via termios - ***************************************************************************/ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return(rtems_termios_read (arg)); -} - -/*************************************************************************** - Function : console_write - - Description : Write to the device via termios - ***************************************************************************/ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return(rtems_termios_write (arg)); -} - -/*************************************************************************** - Function : console_ioctl - - Description : Pass the IOCtl call to termios - ***************************************************************************/ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return( rtems_termios_ioctl (arg) ); -} diff --git a/c/src/lib/libbsp/m68k/mcf5206elite/Makefile.am b/c/src/lib/libbsp/m68k/mcf5206elite/Makefile.am index 12ddd0340f..465a4f8b53 100644 --- a/c/src/lib/libbsp/m68k/mcf5206elite/Makefile.am +++ b/c/src/lib/libbsp/m68k/mcf5206elite/Makefile.am @@ -32,8 +32,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/sbrk.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/setvec.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c # console -librtemsbsp_a_SOURCES += console/console.c -librtemsbsp_a_SOURCES += ../../shared/dummy_printk_support.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf5206elite/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/printk-dummy.c # i2c librtemsbsp_a_SOURCES += i2c/i2c.c librtemsbsp_a_SOURCES += i2c/i2cdrv.c diff --git a/c/src/lib/libbsp/m68k/mcf5206elite/console/console.c b/c/src/lib/libbsp/m68k/mcf5206elite/console/console.c deleted file mode 100644 index bbf343d0f3..0000000000 --- a/c/src/lib/libbsp/m68k/mcf5206elite/console/console.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Console driver for Motorola MCF5206E UART modules - */ - -/* - * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia - * Author: Victor V. Vengerov - * - * COPYRIGHT (c) 1989-1998. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include "mcf5206/mcf5206e.h" -#include "mcf5206/mcfuart.h" - -/* Descriptor structures for two on-chip UART channels */ -static mcfuart uart[2]; - -/* Console operations mode: - * 0 - raw (non-termios) polled input/output - * 1 - termios-based polled input/output - * 2 - termios-based interrupt-driven input/output - */ -int console_mode = 2; -#define CONSOLE_MODE_RAW (0) -#define CONSOLE_MODE_POLL (1) -#define CONSOLE_MODE_INT (2) - -/* Wrapper functions for MCF UART generic driver */ - -/* console_poll_read -- - * wrapper for poll read function - * - * PARAMETERS: - * minor - minor device number - * - * RETURNS: - * character code readed from UART, or -1 if there is no characters - * available - */ -static int -console_poll_read(int minor) -{ - return mcfuart_poll_read(&uart[minor]); -} - -/* console_interrupt_write -- - * wrapper for interrupt write function - * - * PARAMETERS: - * minor - minor device number - * buf - output buffer - * len - output buffer length - * - * RETURNS: - * result code - */ -static ssize_t -console_interrupt_write(int minor, const char *buf, size_t len) -{ - return mcfuart_interrupt_write(&uart[minor], buf, len); -} - -/* console_poll_write -- - * wrapper for polling mode write function - * - * PARAMETERS: - * minor - minor device number - * buf - output buffer - * len - output buffer length - * - * RETURNS: - * result code - */ -static ssize_t -console_poll_write(int minor, const char *buf, size_t len) -{ - return mcfuart_poll_write(&uart[minor], buf, len); -} - -/* console_set_attributes -- - * wrapper for hardware-dependent termios attributes setting - * - * PARAMETERS: - * minor - minor device number - * t - pointer to the termios structure - * - * RETURNS: - * result code - */ -static int -console_set_attributes(int minor, const struct termios *t) -{ - return mcfuart_set_attributes(&uart[minor], t); -} - -/* console_stop_remote_tx -- - * wrapper for stopping data flow from remote party. - * - * PARAMETERS: - * minor - minor device number - * - * RETURNS: - * result code - */ -static int -console_stop_remote_tx(int minor) -{ - if (minor < sizeof(uart)/sizeof(uart[0])) - return mcfuart_stop_remote_tx(&uart[minor]); - else - return RTEMS_INVALID_NUMBER; -} - -/* console_start_remote_tx -- - * wrapper for resuming data flow from remote party. - * - * PARAMETERS: - * minor - minor device number - * - */ -static int -console_start_remote_tx(int minor) -{ - if (minor < sizeof(uart)/sizeof(uart[0])) - return mcfuart_start_remote_tx(&uart[minor]); - else - return RTEMS_INVALID_NUMBER; -} - -/* console_first_open -- - * wrapper for UART controller initialization functions - * - * PARAMETERS: - * major - major device number - * minor - minor device number - * arg - libio device open argument - * - * RETURNS: - * error code - */ -static int -console_first_open(int major, int minor, void *arg) -{ - rtems_libio_open_close_args_t *args = arg; - rtems_status_code sc; - uint8_t intvec; - - switch (minor) { - case 0: intvec = BSP_INTVEC_UART1; break; - case 1: intvec = BSP_INTVEC_UART2; break; - default: - return RTEMS_INVALID_NUMBER; - } - - if (console_mode != CONSOLE_MODE_INT) { - intvec = 0; - } - - sc = mcfuart_init( - &uart[minor], /* uart */ - args->iop->data1, /* tty */ - intvec, /* interrupt vector number */ - minor+1); - - if (sc == RTEMS_SUCCESSFUL) - sc = mcfuart_reset(&uart[minor]); - - return sc; -} - -/* console_last_close -- - * wrapper for UART controller close function - * - * PARAMETERS: - * major - major device number - * minor - minor device number - * arg - libio device close argument - * - * RETURNS: - * error code - */ -static int -console_last_close(int major, int minor, void *arg) -{ - return mcfuart_disable(&uart[minor]); -} - -/* console_initialize -- - * This routine initializes the console IO drivers and register devices - * in RTEMS I/O system. - * - * PARAMETERS: - * major - major console device number - * minor - minor console device number (not used) - * arg - device initialize argument - * - * RETURNS: - * RTEMS error code (RTEMS_SUCCESSFUL if device initialized successfuly) - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - rtems_status_code status; - - /* - * Set up TERMIOS - */ - if (console_mode != CONSOLE_MODE_RAW) - rtems_termios_initialize (); - - /* - * Register the devices - */ - status = rtems_io_register_name ("/dev/console", major, 0); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - status = rtems_io_register_name ("/dev/aux", major, 1); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - if (console_mode == CONSOLE_MODE_RAW) { - rtems_status_code sc; - sc = mcfuart_init(&uart[0], /* uart */ - NULL, /* tty */ - 0, /* interrupt vector number */ - 1); /* UART channel number */ - - if (sc == RTEMS_SUCCESSFUL) - sc = mcfuart_reset(&uart[0]); - - sc = mcfuart_init(&uart[1], /* uart */ - NULL, /* tty */ - 0, /* interrupt vector number */ - 2); /* UART channel number */ - - if (sc == RTEMS_SUCCESSFUL) - sc = mcfuart_reset(&uart[1]); - return sc; - } - - return RTEMS_SUCCESSFUL; -} - -/* console_open -- - * Open console device driver. Pass appropriate termios callback - * functions to termios library. - * - * PARAMETERS: - * major - major device number for console devices - * minor - minor device number for console - * arg - device opening argument - * - * RETURNS: - * RTEMS error code - */ -rtems_device_driver -console_open(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - static const rtems_termios_callbacks intr_callbacks = { - console_first_open, /* firstOpen */ - console_last_close, /* lastClose */ - NULL, /* pollRead */ - console_interrupt_write, /* write */ - console_set_attributes, /* setAttributes */ - console_stop_remote_tx, /* stopRemoteTx */ - console_start_remote_tx, /* startRemoteTx */ - 1 /* outputUsesInterrupts */ - }; - static const rtems_termios_callbacks poll_callbacks = { - console_first_open, /* firstOpen */ - console_last_close, /* lastClose */ - console_poll_read, /* pollRead */ - console_poll_write, /* write */ - console_set_attributes, /* setAttributes */ - console_stop_remote_tx, /* stopRemoteTx */ - console_start_remote_tx, /* startRemoteTx */ - 0 /* outputUsesInterrupts */ - }; - - switch (console_mode) { - case CONSOLE_MODE_RAW: - return RTEMS_SUCCESSFUL; - - case CONSOLE_MODE_INT: - return rtems_termios_open(major, minor, arg, &intr_callbacks); - - case CONSOLE_MODE_POLL: - return rtems_termios_open(major, minor, arg, &poll_callbacks); - - default: - rtems_fatal_error_occurred(0xC07A1310); - } - return RTEMS_INTERNAL_ERROR; -} - -/* console_close -- - * Close console device. - * - * PARAMETERS: - * major - major device number for console devices - * minor - minor device number for console - * arg - device close argument - * - * RETURNS: - * RTEMS error code - */ -rtems_device_driver -console_close(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - if (console_mode != CONSOLE_MODE_RAW) - return rtems_termios_close (arg); - else - return RTEMS_SUCCESSFUL; -} - -/* console_read -- - * Read from the console device - * - * PARAMETERS: - * major - major device number for console devices - * minor - minor device number for console - * arg - device read argument - * - * RETURNS: - * RTEMS error code - */ -rtems_device_driver -console_read(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - if (console_mode != CONSOLE_MODE_RAW) { - return rtems_termios_read (arg); - } else { - rtems_libio_rw_args_t *argp = arg; - char *buf = argp->buffer; - int count = argp->count; - int n = 0; - int c; - - while (n < count) { - do { - c = mcfuart_poll_read(&uart[minor]); - } while (c == -1); - if (c == '\r') - c = '\n'; - *(buf++) = c; - n++; - if (c == '\n') - break; - } - argp->bytes_moved = n; - return RTEMS_SUCCESSFUL; - } -} - -/* console_write -- - * Write to the console device - * - * PARAMETERS: - * major - major device number for console devices - * minor - minor device number for console - * arg - device write argument - * - * RETURNS: - * RTEMS error code - */ -rtems_device_driver -console_write(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - if (console_mode != CONSOLE_MODE_RAW) { - return rtems_termios_write (arg); - } else { - rtems_libio_rw_args_t *argp = arg; - char cr = '\r'; - char *buf = argp->buffer; - int count = argp->count; - int i; - - for (i = 0; i < count; i++) { - if (*buf == '\n') - mcfuart_poll_write(&uart[minor], &cr, 1); - mcfuart_poll_write(&uart[minor], buf, 1); - buf++; - } - argp->bytes_moved = count; - return RTEMS_SUCCESSFUL; - } -} - -/* console_control -- - * Handle console device I/O control (IOCTL) - * - * PARAMETERS: - * major - major device number for console devices - * minor - minor device number for console - * arg - device ioctl argument - * - * RETURNS: - * RTEMS error code - */ -rtems_device_driver -console_control(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - if (console_mode != CONSOLE_MODE_RAW) { - return rtems_termios_ioctl (arg); - } else { - return RTEMS_SUCCESSFUL; - } -} diff --git a/c/src/lib/libbsp/m68k/mcf52235/Makefile.am b/c/src/lib/libbsp/m68k/mcf52235/Makefile.am index 98b8993521..c9138f2d66 100644 --- a/c/src/lib/libbsp/m68k/mcf52235/Makefile.am +++ b/c/src/lib/libbsp/m68k/mcf52235/Makefile.am @@ -31,9 +31,9 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/setvec.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/mcf52235/clock/clock.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf52235/console/console.c # debugio -librtemsbsp_a_SOURCES += console/debugio.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf52235/console/debugio.c # timer librtemsbsp_a_SOURCES += timer/timer.c diff --git a/c/src/lib/libbsp/m68k/mcf52235/console/console.c b/c/src/lib/libbsp/m68k/mcf52235/console/console.c deleted file mode 100644 index c2b6e36bfa..0000000000 --- a/c/src/lib/libbsp/m68k/mcf52235/console/console.c +++ /dev/null @@ -1,656 +0,0 @@ - /* - * Multi UART console serial I/O. - * - * TO DO: Add DMA input/output - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x)) - -#define MCF_UART_USR_ERROR ( MCF_UART_USR_RB | \ - MCF_UART_USR_FE | \ - MCF_UART_USR_PE | \ - MCF_UART_USR_OE ) - -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); -static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len); - -#define MAX_UART_INFO 3 -#define RX_BUFFER_SIZE 512 - -struct IntUartInfoStruct -{ - int iomode; - volatile int uimr; - int baud; - int databits; - int parity; - int stopbits; - int hwflow; - int rx_in; - int rx_out; - char rx_buffer[RX_BUFFER_SIZE]; - void *ttyp; -}; - -struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; - -/*************************************************************************** - Function : IntUartSet - - Description : This updates the hardware UART settings. - ***************************************************************************/ -static void -IntUartSet(int minor, int baud, int databits, int parity, int stopbits, - int hwflow) -{ - int divisor; - uint32_t clock_speed; - uint8_t umr1 = 0; - uint8_t umr2 = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - int level; - - rtems_interrupt_disable(level); - - /* disable interrupts, clear RTS line, and disable the UARTS */ - MCF_UART_UIMR(minor) = 0; - MCF_UART_UOP0(minor) = 1; - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED); - - /* save the current values */ - info->uimr = 0; - info->baud = baud; - info->databits = databits; - info->parity = parity; - info->stopbits = stopbits; - info->hwflow = hwflow; - - clock_speed = bsp_get_CPU_clock_speed(); - /* determine the baud divisor value */ - divisor = ((clock_speed) / (32 * baud)); - if (divisor < 2) - divisor = 2; - - /* check to see if doing hardware flow control */ - if (hwflow) { - /* set hardware flow options */ - umr1 |= MCF_UART_UMR_RXRTS; - umr2 |= MCF_UART_UMR_TXCTS; - } - - /* determine the new umr values */ - umr1 |= (parity | databits); - umr2 |= (stopbits); - - /* reset the uart */ - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_ERROR; - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_RX; - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_TX; - - /* reset the uart mode register and update values */ - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_MR; - MCF_UART_UMR(minor) = umr1; - MCF_UART_UMR(minor) = umr2; - - /* set the baud rate values */ - MCF_UART_UCSR(minor) = - (MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK); - MCF_UART_UBG1(minor) = (divisor & 0xff00) >> 8; - MCF_UART_UBG2(minor) = (divisor & 0x00ff); - - /* enable the uart */ - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if (info->iomode != TERMIOS_POLLED) { - /* enable rx interrupts */ - info->uimr |= MCF_UART_UIMR_RXRDY_FU; - MCF_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if (hwflow) { - /* assert the RTS line */ - MCF_UART_UOP1(minor) = 1; - } - - rtems_interrupt_enable(level); - -} - -/*************************************************************************** - Function : IntUartSetAttributes - - Description : This provides the hardware-dependent portion of tcsetattr(). - value and sets it. At the moment this just sets the baud rate. - - Note: The highest baudrate is 115200 as this stays within - an error of +/- 5% at 25MHz processor clock - ***************************************************************************/ -static int IntUartSetAttributes(int minor, const struct termios *t) -{ - /* set default index values */ - int baud = (int) 19200; - int databits = (int) MCF_UART_UMR_BC_8; - int parity = (int) MCF_UART_UMR_PM_NONE; - int stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_1; - int hwflow = (int) 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* check to see if input is valid */ - if (t != (const struct termios *) 0) { - /* determine baud rate index */ - baud = rtems_termios_baud_to_number(t->c_ospeed); - - /* determine data bits */ - switch (t->c_cflag & CSIZE) { - case CS5: - databits = (int) MCF_UART_UMR_BC_5; - break; - case CS6: - databits = (int) MCF_UART_UMR_BC_6; - break; - case CS7: - databits = (int) MCF_UART_UMR_BC_7; - break; - case CS8: - databits = (int) MCF_UART_UMR_BC_8; - break; - } - - /* determine if parity is enabled */ - if (t->c_cflag & PARENB) { - if (t->c_cflag & PARODD) { - /* odd parity */ - parity = (int) MCF_UART_UMR_PM_ODD; - } else { - /* even parity */ - parity = (int) MCF_UART_UMR_PM_EVEN; - } - } - - /* determine stop bits */ - if (t->c_cflag & CSTOPB) { - /* two stop bits */ - stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_2; - } - - /* check to see if hardware flow control */ - if (t->c_cflag & CRTSCTS) { - hwflow = 1; - } - } - - /* check to see if values have changed */ - if ((baud != info->baud) || - (databits != info->databits) || - (parity != info->parity) || - (stopbits != info->stopbits) || (hwflow != info->hwflow)) { - - /* call function to set values */ - IntUartSet(minor, baud, databits, parity, stopbits, hwflow); - } - - return (RTEMS_SUCCESSFUL); - -} - -/*************************************************************************** - Function : IntUartInterruptHandler - - Description : This is the interrupt handler for the internal uart. It - determines which channel caused the interrupt before queueing any received - chars and dequeueing chars waiting for transmission. - ***************************************************************************/ -static rtems_isr IntUartInterruptHandler(rtems_vector_number v) -{ - unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); - struct IntUartInfoStruct *info = &IntUartInfo[chan]; - - /* check to see if received data */ - if (MCF_UART_UISR(chan) & MCF_UART_UISR_RXRDY_FU) { - /* read data and put into the receive buffer */ - while (MCF_UART_USR(chan) & MCF_UART_USR_RXRDY) { - - if (MCF_UART_USR(chan) & MCF_UART_USR_ERROR) { - /* clear the error */ - MCF_UART_UCR(chan) = MCF_UART_UCR_RESET_ERROR; - } - /* put data in rx buffer and check for errors */ - info->rx_buffer[info->rx_in] = MCF_UART_URB(chan); - - /* update buffer values */ - info->rx_in++; - - if (info->rx_in >= RX_BUFFER_SIZE) { - info->rx_in = 0; - } - } - /* Make sure the port has been opened */ - if (info->ttyp) { - - /* check to see if task driven */ - if (info->iomode == TERMIOS_TASK_DRIVEN) { - /* notify rx task that rx buffer has data */ - rtems_termios_rxirq_occured(info->ttyp); - } else { - /* Push up the received data */ - rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, - info->rx_in); - info->rx_in = 0; - } - } - } - - /* check to see if data needs to be transmitted */ - if ((info->uimr & MCF_UART_UIMR_TXRDY) && - (MCF_UART_UISR(chan) & MCF_UART_UISR_TXRDY)) { - - /* disable tx interrupts */ - info->uimr &= ~MCF_UART_UIMR_TXRDY; - MCF_UART_UIMR(chan) = info->uimr; - - /* tell upper level that character has been sent */ - if (info->ttyp) - rtems_termios_dequeue_characters(info->ttyp, 1); - } -} - -/*************************************************************************** - Function : IntUartInitialize - - Description : This initialises the internal uart hardware for all - internal uarts. If the internal uart is to be interrupt driven then the - interrupt vectors are hooked. - ***************************************************************************/ -static void IntUartInitialize(void) -{ - unsigned int chan; - struct IntUartInfoStruct *info; - rtems_isr_entry old_handler; - int level; - - for (chan = 0; chan < MAX_UART_INFO; chan++) { - info = &IntUartInfo[chan]; - - info->ttyp = NULL; - info->rx_in = 0; - info->rx_out = 0; - info->baud = -1; - info->databits = -1; - info->parity = -1; - info->stopbits = -1; - info->hwflow = -1; - info->iomode = TERMIOS_POLLED; /*polled console io */ - - MCF_UART_UACR(chan) = 0; - MCF_UART_UIMR(chan) = 0; - if (info->iomode != TERMIOS_POLLED) { - rtems_interrupt_catch(IntUartInterruptHandler, - UART_INTC0_IRQ_VECTOR(chan), &old_handler); - } - - /* set uart default values */ - IntUartSetAttributes(chan, NULL); - - /* unmask interrupt */ - rtems_interrupt_disable(level); - switch (chan) { - case 0: - MCF_INTC0_ICR13 = MCF_INTC_ICR_IL(UART0_IRQ_LEVEL) | - MCF_INTC_ICR_IP(UART0_IRQ_PRIORITY); - MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK13 | MCF_INTC_IMRL_MASKALL); - break; - - case 1: - MCF_INTC0_ICR14 = MCF_INTC_ICR_IL(UART1_IRQ_LEVEL) | - MCF_INTC_ICR_IP(UART1_IRQ_PRIORITY); - MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK14 | MCF_INTC_IMRL_MASKALL); - break; - - case 2: - MCF_INTC0_ICR15 = MCF_INTC_ICR_IL(UART2_IRQ_LEVEL) | - MCF_INTC_ICR_IP(UART2_IRQ_PRIORITY); - MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK15 | MCF_INTC_IMRL_MASKALL); - break; - } - rtems_interrupt_enable(level); - - } /* of chan loop */ - -} /* IntUartInitialise */ - -/*************************************************************************** - Function : IntUartInterruptWrite - - Description : This writes a single character to the appropriate uart - channel. This is either called during an interrupt or in the user's task - to initiate a transmit sequence. Calling this routine enables Tx - interrupts. - ***************************************************************************/ -static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len) -{ - if (len > 0) { - /* write out character */ - MCF_UART_UTB(minor) = *buf; - - /* enable tx interrupt */ - IntUartInfo[minor].uimr |= MCF_UART_UIMR_TXRDY; - MCF_UART_UIMR(minor) = IntUartInfo[minor].uimr; - } - - return (0); -} - -/*************************************************************************** - Function : IntUartInterruptOpen - - Description : This enables interrupts when the tty is opened. - ***************************************************************************/ -static int IntUartInterruptOpen(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* enable the uart */ - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if (info->iomode != TERMIOS_POLLED) { - /* enable rx interrupts */ - info->uimr |= MCF_UART_UIMR_RXRDY_FU; - MCF_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if (info->hwflow) { - /* assert the RTS line */ - MCF_UART_UOP1(minor) = 1; - } - - return (0); -} - -/*************************************************************************** - Function : IntUartInterruptClose - - Description : This disables interrupts when the tty is closed. - ***************************************************************************/ -static int IntUartInterruptClose(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* disable the interrupts and the uart */ - MCF_UART_UIMR(minor) = 0; - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED); - - /* reset values */ - info->ttyp = NULL; - info->uimr = 0; - info->rx_in = 0; - info->rx_out = 0; - - return (0); -} - -/*************************************************************************** - Function : IntUartTaskRead - - Description : This reads all available characters from the internal uart - and places them into the termios buffer. The rx interrupts will be - re-enabled after all data has been read. - ***************************************************************************/ -static int IntUartTaskRead(int minor) -{ - char buffer[RX_BUFFER_SIZE]; - int count; - int rx_in; - int index = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* determine number of values to copy out */ - rx_in = info->rx_in; - if (info->rx_out <= rx_in) { - count = rx_in - info->rx_out; - } else { - count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; - } - - /* copy data into local buffer from rx buffer */ - while ((index < count) && (index < RX_BUFFER_SIZE)) { - /* copy data byte */ - buffer[index] = info->rx_buffer[info->rx_out]; - index++; - - /* increment rx buffer values */ - info->rx_out++; - if (info->rx_out >= RX_BUFFER_SIZE) { - info->rx_out = 0; - } - } - - /* check to see if buffer is not empty */ - if (count > 0) { - /* set characters into termios buffer */ - rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); - } - - return (EOF); -} - -/*************************************************************************** - Function : IntUartPollRead - - Description : This reads a character from the internal uart. It returns - to the caller without blocking if not character is waiting. - ***************************************************************************/ -static int IntUartPollRead(int minor) -{ - if ((MCF_UART_USR(minor) & MCF_UART_USR_RXRDY) == 0) - return (-1); - - return (MCF_UART_URB(minor)); -} - -/*************************************************************************** - Function : IntUartPollWrite - - Description : This writes out each character in the buffer to the - appropriate internal uart channel waiting till each one is sucessfully - transmitted. - ***************************************************************************/ -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len) -{ - size_t retval = len; - /* loop over buffer */ - while (len--) { - /* block until we can transmit */ - while ((MCF_UART_USR(minor) & MCF_UART_USR_TXRDY) == 0) - continue; - /* transmit data byte */ - MCF_UART_UTB(minor) = *buf++; - } - return retval; -} - -/*************************************************************************** - Function : console_initialize - - Description : This initialises termios, both sets of uart hardware before - registering /dev/tty devices for each channel and the system /dev/console. - ***************************************************************************/ -rtems_device_driver console_initialize(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - rtems_status_code status; - - /* Set up TERMIOS */ - rtems_termios_initialize(); - - /* set io modes for the different channels and initialize device */ - IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN; - IntUartInitialize(); - - /* Register the console port */ - status = rtems_io_register_name("/dev/console", major, CONSOLE_PORT); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - - /* Register the other port */ - if (CONSOLE_PORT != 0) { - status = rtems_io_register_name("/dev/tty00", major, 0); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - } - if (CONSOLE_PORT != 1) { - status = rtems_io_register_name("/dev/tty01", major, 1); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - } - - return (RTEMS_SUCCESSFUL); -} - -/*************************************************************************** - Function : console_open - - Description : This actually opens the device depending on the minor - number set during initialisation. The device specific access routines are - passed to termios when the devices is opened depending on whether it is - polled or not. - ***************************************************************************/ -rtems_device_driver console_open(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - rtems_status_code status = RTEMS_INVALID_NUMBER; - rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *) arg; - struct IntUartInfoStruct *info; - - static const rtems_termios_callbacks IntUartPollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - IntUartPollRead, /* pollRead */ - IntUartPollWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_POLLED /* mode */ - }; - static const rtems_termios_callbacks IntUartIntrCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - NULL, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_IRQ_DRIVEN /* mode */ - }; - - static const rtems_termios_callbacks IntUartTaskCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - IntUartTaskRead, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_TASK_DRIVEN /* mode */ - }; - - /* open the port depending on the minor device number */ - if ((minor >= 0) && (minor < MAX_UART_INFO)) { - info = &IntUartInfo[minor]; - switch (info->iomode) { - case TERMIOS_POLLED: - status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); - break; - case TERMIOS_IRQ_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); - info->ttyp = args->iop->data1; - break; - case TERMIOS_TASK_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); - info->ttyp = args->iop->data1; - break; - } - } - - if (status == RTEMS_SUCCESSFUL) { - /* - * Reset the default baudrate. - */ - struct termios term; - - if (tcgetattr(STDIN_FILENO, &term) >= 0) { - term.c_cflag &= ~(CSIZE); - term.c_cflag |= CS8; - term.c_ispeed = B19200; - term.c_ospeed = B19200; - tcsetattr(STDIN_FILENO, TCSANOW, &term); - } - } - - return (status); -} - -/*************************************************************************** - Function : console_close - - Description : This closes the device via termios - ***************************************************************************/ -rtems_device_driver console_close(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - return (rtems_termios_close(arg)); -} - -/****************** -********************************************************* - Function : console_read - - Description : Read from the device via termios - ***************************************************************************/ -rtems_device_driver console_read(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - return (rtems_termios_read(arg)); -} - -/*************************************************************************** - Function : console_write - - Description : Write to the device via termios - ***************************************************************************/ -rtems_device_driver console_write(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - return (rtems_termios_write(arg)); -} - -/*************************************************************************** - Function : console_ioctl - - Description : Pass the IOCtl call to termios - ***************************************************************************/ -rtems_device_driver console_control(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - return (rtems_termios_ioctl(arg)); -} diff --git a/c/src/lib/libbsp/m68k/mcf52235/console/debugio.c b/c/src/lib/libbsp/m68k/mcf52235/console/debugio.c deleted file mode 100644 index 1fbf4b09d7..0000000000 --- a/c/src/lib/libbsp/m68k/mcf52235/console/debugio.c +++ /dev/null @@ -1,32 +0,0 @@ - /* - * Multi UART console serial I/O. - * - * TO DO: Add DMA input/output - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -static void _BSP_null_char(char c) -{ - int level; - - rtems_interrupt_disable(level); - while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0) - continue; - MCF_UART_UTB(CONSOLE_PORT) = c; - while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0) - continue; - rtems_interrupt_enable(level); -} - -BSP_output_char_function_type BSP_output_char = _BSP_null_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - diff --git a/c/src/lib/libbsp/m68k/mcf5225x/Makefile.am b/c/src/lib/libbsp/m68k/mcf5225x/Makefile.am index 99b996c1f4..f93dd98d5f 100644 --- a/c/src/lib/libbsp/m68k/mcf5225x/Makefile.am +++ b/c/src/lib/libbsp/m68k/mcf5225x/Makefile.am @@ -24,8 +24,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/getentropy/getentropy librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/sbrk.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/setvec.c librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/mcf5225x/clock/clock.c -librtemsbsp_a_SOURCES += console/console.c -librtemsbsp_a_SOURCES += console/debugio.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf5225x/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf5225x/console/debugio.c librtemsbsp_a_SOURCES += timer/timer.c librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/shared/cache/cache-mcf5225x.c diff --git a/c/src/lib/libbsp/m68k/mcf5225x/console/console.c b/c/src/lib/libbsp/m68k/mcf5225x/console/console.c deleted file mode 100644 index 9e36e3945a..0000000000 --- a/c/src/lib/libbsp/m68k/mcf5225x/console/console.c +++ /dev/null @@ -1,689 +0,0 @@ -/* - * Multi UART console serial I/O. - * - * TO DO: Add DMA input/output - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x)) - -#define MCF_UART_USR_ERROR ( MCF_UART_USR_RB | \ - MCF_UART_USR_FE | \ - MCF_UART_USR_PE | \ - MCF_UART_USR_OE ) - -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); -static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len); - -#define MAX_UART_INFO 3 -#define RX_BUFFER_SIZE 512 - -struct IntUartInfoStruct -{ - int iomode; - volatile int uimr; - int baud; - int databits; - int parity; - int stopbits; - int hwflow; - int rx_in; - int rx_out; - char rx_buffer[RX_BUFFER_SIZE]; - void *ttyp; -}; - -struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; - -/*************************************************************************** - Function : IntUartSet - - Description : This updates the hardware UART settings. - ***************************************************************************/ -static void -IntUartSet(int minor, int baud, int databits, int parity, int stopbits, - int hwflow) -{ - int divisor; - uint32_t clock_speed; - uint8_t umr1 = 0; - uint8_t umr2 = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - rtems_interrupt_level level=UART0_IRQ_LEVEL; - - rtems_interrupt_disable(level); - - /* disable interrupts, clear RTS line, and disable the UARTS */ - MCF_UART_UIMR(minor) = 0; - MCF_UART_UOP0(minor) = 1; - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED); - - /* save the current values */ - info->uimr = 0; - info->baud = baud; - info->databits = databits; - info->parity = parity; - info->stopbits = stopbits; - info->hwflow = hwflow; - - clock_speed = bsp_get_CPU_clock_speed(); - /* determine the baud divisor value */ - divisor = ((clock_speed) / (32 * baud)); - if (divisor < 2) - divisor = 2; - - /* check to see if doing hardware flow control */ - if (hwflow) { - /* set hardware flow options */ - umr1 |= MCF_UART_UMR_RXRTS; - umr2 |= MCF_UART_UMR_TXCTS; - } - - /* determine the new umr values */ - umr1 |= (parity | databits); - -#if 1 /* TZN: maybe needed for santec bus modul handling */ - if (minor==STATIONS_PORT) - umr2 |= (stopbits) | 0x20; /* 0x20 ... set TXRTS just4testing */ - else - umr2 |= (stopbits); -#else - umr2 |= (stopbits); -#endif - - /* reset the uart */ - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_ERROR; - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_RX; - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_TX; - - /* reset the uart mode register and update values */ - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_MR; - MCF_UART_UMR(minor) = umr1; - MCF_UART_UMR(minor) = umr2; - - /* set the baud rate values */ - MCF_UART_UCSR(minor) = - (MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK); - MCF_UART_UBG1(minor) = (divisor & 0xff00) >> 8; - MCF_UART_UBG2(minor) = (divisor & 0x00ff); - - /* enable the uart */ - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if (info->iomode != TERMIOS_POLLED) { - /* enable rx interrupts */ - info->uimr |= MCF_UART_UIMR_RXRDY_FU; - MCF_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if (hwflow) { - /* assert the RTS line */ - MCF_UART_UOP1(minor) = 1; - } - - if (minor==STATIONS_PORT) //maybe needed for santec handling - MCF_UART_UOP0(minor) = 1; - - rtems_interrupt_enable(level); - -} - -/*************************************************************************** - Function : IntUartSetAttributes - - Description : This provides the hardware-dependent portion of tcsetattr(). - value and sets it. At the moment this just sets the baud rate. - - Note: The highest baudrate is 115200 as this stays within - an error of +/- 5% at 25MHz processor clock - ***************************************************************************/ -static int IntUartSetAttributes(int minor, const struct termios *t) -{ - /* set default index values */ - int baud = (int) 19200; - int databits = (int) MCF_UART_UMR_BC_8; - int parity = (int) MCF_UART_UMR_PM_NONE; - int stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_1; - int hwflow = (int) 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* check to see if input is valid */ - if (t != (const struct termios *) 0) { - /* determine baud rate index */ - baud = rtems_termios_baud_to_number(t->c_ospeed); - - /* determine data bits */ - switch (t->c_cflag & CSIZE) { - case CS5: - databits = (int) MCF_UART_UMR_BC_5; - break; - case CS6: - databits = (int) MCF_UART_UMR_BC_6; - break; - case CS7: - databits = (int) MCF_UART_UMR_BC_7; - break; - case CS8: - databits = (int) MCF_UART_UMR_BC_8; - break; - } - - /* determine if parity is enabled */ - if (t->c_cflag & PARENB) { - if (t->c_cflag & PARODD) { - /* odd parity */ - parity = (int) MCF_UART_UMR_PM_ODD; - } else { - /* even parity */ - parity = (int) MCF_UART_UMR_PM_EVEN; - } - } - - /* determine stop bits */ - if (t->c_cflag & CSTOPB) { - /* two stop bits */ - stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_2; - } - - /* check to see if hardware flow control */ - if (t->c_cflag & CRTSCTS) { - hwflow = 1; - } - } - - /* check to see if values have changed */ - if ((baud != info->baud) || - (databits != info->databits) || - (parity != info->parity) || - (stopbits != info->stopbits) || (hwflow != info->hwflow)) { - - /* call function to set values */ - IntUartSet(minor, baud, databits, parity, stopbits, hwflow); - } - - return (RTEMS_SUCCESSFUL); - -} - -/*************************************************************************** - Function : IntUartInterruptHandler - - Description : This is the interrupt handler for the internal uart. It - determines which channel caused the interrupt before queueing any received - chars and dequeueing chars waiting for transmission. - ***************************************************************************/ -static rtems_isr IntUartInterruptHandler(rtems_vector_number v) -{ - unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); - struct IntUartInfoStruct *info = &IntUartInfo[chan]; - - - /* check to see if received data */ - if (MCF_UART_UISR(chan) & MCF_UART_UISR_RXRDY_FU) { - -#if 0 /* TZN ... just4testing */ - if (MCF_GPIO_PORTTC&MCF_GPIO_PORTTC_PORTTC0) - MCF_GPIO_PORTTC &= ~MCF_GPIO_PORTTC_PORTTC0; - else - MCF_GPIO_PORTTC |= MCF_GPIO_PORTTC_PORTTC0; -#endif - - /* read data and put into the receive buffer */ - while (MCF_UART_USR(chan) & MCF_UART_USR_RXRDY) { - - if (MCF_UART_USR(chan) & MCF_UART_USR_ERROR) { - /* clear the error */ - MCF_UART_UCR(chan) = MCF_UART_UCR_RESET_ERROR; - } - /* put data in rx buffer and check for errors */ - info->rx_buffer[info->rx_in] = MCF_UART_URB(chan); - - /* update buffer values */ - info->rx_in++; - - if (info->rx_in >= RX_BUFFER_SIZE) { - info->rx_in = 0; - } - } - /* Make sure the port has been opened */ - if (info->ttyp) { - - /* check to see if task driven */ - if (info->iomode == TERMIOS_TASK_DRIVEN) { - /* notify rx task that rx buffer has data */ - rtems_termios_rxirq_occured(info->ttyp); - } else { - /* Push up the received data */ - rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, - info->rx_in); - info->rx_in = 0; - } - } - } - - /* check to see if data needs to be transmitted */ - if ((info->uimr & MCF_UART_UIMR_TXRDY) && - (MCF_UART_UISR(chan) & MCF_UART_UISR_TXRDY)) { - - /* disable tx interrupts */ - info->uimr &= ~MCF_UART_UIMR_TXRDY; - MCF_UART_UIMR(chan) = info->uimr; - - /* tell upper level that character has been sent */ - if (info->ttyp) - rtems_termios_dequeue_characters(info->ttyp, 1); - } -} - -/*************************************************************************** - Function : IntUartInitialize - - Description : This initialises the internal uart hardware for all - internal uarts. If the internal uart is to be interrupt driven then the - interrupt vectors are hooked. - ***************************************************************************/ -static void IntUartInitialize(void) -{ - unsigned int chan; - struct IntUartInfoStruct *info; - rtems_isr_entry old_handler; - rtems_interrupt_level level=UART0_IRQ_LEVEL; - - for (chan = 0; chan < MAX_UART_INFO; chan++) { - info = &IntUartInfo[chan]; - - info->ttyp = NULL; - info->rx_in = 0; - info->rx_out = 0; - info->baud = -1; - info->databits = -1; - info->parity = -1; - info->stopbits = -1; - info->hwflow = -1; - info->iomode = TERMIOS_IRQ_DRIVEN; /*TZN, irq driven console io */ - //info->iomode = TERMIOS_POLLED; /*TZN, just4testint, use polling mode for all UARTS */ - - MCF_UART_UACR(chan) = 0; - MCF_UART_UIMR(chan) = 0; - if (info->iomode != TERMIOS_POLLED) { - rtems_interrupt_catch(IntUartInterruptHandler, - UART_INTC0_IRQ_VECTOR(chan), &old_handler); - } - - /* set uart default values */ - IntUartSetAttributes(chan, NULL); - - /* unmask interrupt */ - rtems_interrupt_disable(level); - switch (chan) { - case 0: - MCF_INTC0_ICR13 = MCF_INTC_ICR_IL(UART0_IRQ_LEVEL) | - MCF_INTC_ICR_IP(UART0_IRQ_PRIORITY); - MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK13 | MCF_INTC_IMRL_MASKALL); - break; - - case 1: - MCF_INTC0_ICR14 = MCF_INTC_ICR_IL(UART1_IRQ_LEVEL) | - MCF_INTC_ICR_IP(UART1_IRQ_PRIORITY); - MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK14 | MCF_INTC_IMRL_MASKALL); - break; - - case 2: - MCF_INTC0_ICR15 = MCF_INTC_ICR_IL(UART2_IRQ_LEVEL) | - MCF_INTC_ICR_IP(UART2_IRQ_PRIORITY); - MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK15 | MCF_INTC_IMRL_MASKALL); - break; - } - rtems_interrupt_enable(level); - - } /* of chan loop */ - -} /* IntUartInitialise */ - -/*************************************************************************** - Function : IntUartInterruptWrite - - Description : This writes a single character to the appropriate uart - channel. This is either called during an interrupt or in the user's task - to initiate a transmit sequence. Calling this routine enables Tx - interrupts. - ***************************************************************************/ -static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len) -{ - if (len > 0) { - /* write out character */ - MCF_UART_UTB(minor) = *buf; - - /* enable tx interrupt */ - IntUartInfo[minor].uimr |= MCF_UART_UIMR_TXRDY; - MCF_UART_UIMR(minor) = IntUartInfo[minor].uimr; - } - - return (0); -} - -/*************************************************************************** - Function : IntUartInterruptOpen - - Description : This enables interrupts when the tty is opened. - ***************************************************************************/ -static int IntUartInterruptOpen(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* enable the uart */ - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if (info->iomode != TERMIOS_POLLED) { - /* enable rx interrupts */ - info->uimr |= MCF_UART_UIMR_RXRDY_FU; - MCF_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if (info->hwflow) { - /* assert the RTS line */ - MCF_UART_UOP1(minor) = 1; - } - - return (0); -} - -/*************************************************************************** - Function : IntUartInterruptClose - - Description : This disables interrupts when the tty is closed. - ***************************************************************************/ -static int IntUartInterruptClose(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* disable the interrupts and the uart */ - MCF_UART_UIMR(minor) = 0; - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED); - - /* reset values */ - info->ttyp = NULL; - info->uimr = 0; - info->rx_in = 0; - info->rx_out = 0; - - return (0); -} - -/*************************************************************************** - Function : IntUartTaskRead - - Description : This reads all available characters from the internal uart - and places them into the termios buffer. The rx interrupts will be - re-enabled after all data has been read. - ***************************************************************************/ -static int IntUartTaskRead(int minor) -{ - char buffer[RX_BUFFER_SIZE]; - int count; - int rx_in; - int index = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* determine number of values to copy out */ - rx_in = info->rx_in; - if (info->rx_out <= rx_in) { - count = rx_in - info->rx_out; - } else { - count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; - } - - /* copy data into local buffer from rx buffer */ - while ((index < count) && (index < RX_BUFFER_SIZE)) { - /* copy data byte */ - buffer[index] = info->rx_buffer[info->rx_out]; - index++; - - /* increment rx buffer values */ - info->rx_out++; - if (info->rx_out >= RX_BUFFER_SIZE) { - info->rx_out = 0; - } - } - - /* check to see if buffer is not empty */ - if (count > 0) { - /* set characters into termios buffer */ - rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); - } - - return (EOF); -} - -/*************************************************************************** - Function : IntUartPollRead - - Description : This reads a character from the internal uart. It returns - to the caller without blocking if not character is waiting. - ***************************************************************************/ -static -int IntUartPollRead(int minor) -{ - if ((MCF_UART_USR(minor) & MCF_UART_USR_RXRDY) == 0) - return (-1); - - return (MCF_UART_URB(minor)); -} - -/*************************************************************************** - Function : IntUartPollWrite - - Description : This writes out each character in the buffer to the - appropriate internal uart channel waiting till each one is sucessfully - transmitted. - ***************************************************************************/ -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len) -{ - /* loop over buffer */ - while (len--) { - /* block until we can transmit */ - while ((MCF_UART_USR(minor) & MCF_UART_USR_TXRDY) == 0) - continue; - /* transmit data byte */ - MCF_UART_UTB(minor) = *buf++; - } - return (0); -} - -/*************************************************************************** - Function : console_initialize - - Description : This initialises termios, both sets of uart hardware before - registering /dev/tty devices for each channel and the system /dev/console. - ***************************************************************************/ -rtems_device_driver console_initialize(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - rtems_status_code status; - - /* Set up TERMIOS */ - rtems_termios_initialize(); - - /* set io modes for the different channels and initialize device */ - IntUartInitialize(); - - /* Register the console port */ - status = rtems_io_register_name("/dev/console", major, CONSOLE_PORT); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - - /* Register the RS485 port to communicate with SANTEC stations */ - if ((STATIONS_PORT!=CONSOLE_PORT) && (STATIONS_PORT!=BLUETOOTH_PORT)) { - status = rtems_io_register_name("/dev/tty00", major,STATIONS_PORT); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - } - else { - status=RTEMS_TOO_MANY; - rtems_fatal_error_occurred(status); - } - - /* Register the Bluetooth port */ - if ((BLUETOOTH_PORT!=CONSOLE_PORT) && (BLUETOOTH_PORT!=STATIONS_PORT)) { - status = rtems_io_register_name("/dev/tty01", major, BLUETOOTH_PORT); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - } - else { - status=RTEMS_TOO_MANY; - rtems_fatal_error_occurred(status); - } - - return (RTEMS_SUCCESSFUL); -} - -/*************************************************************************** - Function : console_open - - Description : This actually opens the device depending on the minor - number set during initialisation. The device specific access routines are - passed to termios when the devices is opened depending on whether it is - polled or not. - ***************************************************************************/ -rtems_device_driver console_open(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - rtems_status_code status = RTEMS_INVALID_NUMBER; - rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *) arg; - struct IntUartInfoStruct *info; - - static const rtems_termios_callbacks IntUartPollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - IntUartPollRead, /* pollRead */ - IntUartPollWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_POLLED /* mode */ - }; - static const rtems_termios_callbacks IntUartIntrCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - NULL, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_IRQ_DRIVEN /* mode */ - }; - - static const rtems_termios_callbacks IntUartTaskCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - IntUartTaskRead, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_TASK_DRIVEN /* mode */ - }; - - /* open the port depending on the minor device number */ - if ((minor >= 0) && (minor < MAX_UART_INFO)) { - info = &IntUartInfo[minor]; - switch (info->iomode) { - case TERMIOS_POLLED: - status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); - break; - case TERMIOS_IRQ_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); - info->ttyp = args->iop->data1; - break; - case TERMIOS_TASK_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); - info->ttyp = args->iop->data1; - break; - } - } - - if (status == RTEMS_SUCCESSFUL) { - /* - * Reset the default baudrate. - */ - struct termios term; - - if (tcgetattr(STDIN_FILENO, &term) >= 0) { - term.c_cflag &= ~(CSIZE); - term.c_cflag |= CS8; - term.c_ispeed = B115200; - term.c_ospeed = B115200; - tcsetattr(STDIN_FILENO, TCSANOW, &term); - } - } - - return (status); -} - -/*************************************************************************** - Function : console_close - - Description : This closes the device via termios - ***************************************************************************/ -rtems_device_driver console_close(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - return (rtems_termios_close(arg)); -} - -/****************** -********************************************************* - Function : console_read - - Description : Read from the device via termios - ***************************************************************************/ -rtems_device_driver console_read(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - return (rtems_termios_read(arg)); -} - -/*************************************************************************** - Function : console_write - - Description : Write to the device via termios - ***************************************************************************/ -rtems_device_driver console_write(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - return (rtems_termios_write(arg)); -} - -/*************************************************************************** - Function : console_ioctl - - Description : Pass the IOCtl call to termios - ***************************************************************************/ -rtems_device_driver console_control(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - return (rtems_termios_ioctl(arg)); -} diff --git a/c/src/lib/libbsp/m68k/mcf5225x/console/debugio.c b/c/src/lib/libbsp/m68k/mcf5225x/console/debugio.c deleted file mode 100644 index b91048a310..0000000000 --- a/c/src/lib/libbsp/m68k/mcf5225x/console/debugio.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Multi UART console serial I/O. - * - * TO DO: Add DMA input/output - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -static void _BSP_null_char(char c) -{ - rtems_interrupt_level level=UART0_IRQ_LEVEL; - - rtems_interrupt_disable(level); - while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0) - continue; - MCF_UART_UTB(CONSOLE_PORT) = c; - while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0) - continue; - rtems_interrupt_enable(level); -} - -BSP_output_char_function_type BSP_output_char = _BSP_null_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/m68k/mcf5235/Makefile.am b/c/src/lib/libbsp/m68k/mcf5235/Makefile.am index c4caf60792..abc3b777d2 100644 --- a/c/src/lib/libbsp/m68k/mcf5235/Makefile.am +++ b/c/src/lib/libbsp/m68k/mcf5235/Makefile.am @@ -33,7 +33,7 @@ librtemsbsp_a_SOURCES += startup/copyvectors.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/mcf5235/clock/clock.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf5235/console/console.c # timer librtemsbsp_a_SOURCES += timer/timer.c diff --git a/c/src/lib/libbsp/m68k/mcf5235/console/console.c b/c/src/lib/libbsp/m68k/mcf5235/console/console.c deleted file mode 100644 index 38317130cb..0000000000 --- a/c/src/lib/libbsp/m68k/mcf5235/console/console.c +++ /dev/null @@ -1,745 +0,0 @@ - /* - * Multi UART console serial I/O. - * - * TO DO: Add DMA input/output - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x)) - -#define MCF5235_UART_USR_ERROR ( MCF5235_UART_USR_RB | \ - MCF5235_UART_USR_FE | \ - MCF5235_UART_USR_PE | \ - MCF5235_UART_USR_OE ) - -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); -static ssize_t IntUartInterruptWrite (int minor, const char *buf, size_t len); - -static void -_BSP_null_char( char c ) -{ - int level; - - rtems_interrupt_disable(level); - while ( (MCF5235_UART_USR(CONSOLE_PORT) & MCF5235_UART_USR_TXRDY) == 0 ) - continue; - MCF5235_UART_UTB(CONSOLE_PORT) = c; - while ( (MCF5235_UART_USR(CONSOLE_PORT) & MCF5235_UART_USR_TXRDY) == 0 ) - continue; - rtems_interrupt_enable(level); -} -BSP_output_char_function_type BSP_output_char = _BSP_null_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - -#define MAX_UART_INFO 3 -#define RX_BUFFER_SIZE 512 - -struct IntUartInfoStruct -{ - int iomode; - volatile int uimr; - int baud; - int databits; - int parity; - int stopbits; - int hwflow; - int rx_in; - int rx_out; - char rx_buffer[RX_BUFFER_SIZE]; - void *ttyp; -}; - -struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; - -/*************************************************************************** - Function : IntUartSet - - Description : This updates the hardware UART settings. - ***************************************************************************/ -static void -IntUartSet(int minor, int baud, int databits, int parity, int stopbits, int hwflow) -{ - int divisor; - uint32_t clock_speed; - uint8_t umr1 = 0; - uint8_t umr2 = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - int level; - - rtems_interrupt_disable(level); - - - /* disable interrupts, clear RTS line, and disable the UARTS */ - MCF5235_UART_UIMR(minor) = 0; - MCF5235_UART_UOP0(minor) = 1; - MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_DISABLED | MCF5235_UART_UCR_RX_DISABLED); - - /* save the current values */ - info->uimr = 0; - info->baud = baud; - info->databits = databits; - info->parity = parity; - info->stopbits = stopbits; - info->hwflow = hwflow; - - clock_speed = get_CPU_clock_speed(); - /* determine the baud divisor value */ - divisor = ((clock_speed/2) / ( 32 * baud )); - if ( divisor < 2 ) { - divisor = 2; - } - - /* check to see if doing hardware flow control */ - if ( hwflow ) - { - /* set hardware flow options */ - umr1 |= MCF5235_UART_UMR_RXRTS; - umr2 |= MCF5235_UART_UMR_TXCTS; - } - - /* determine the new umr values */ - umr1 |= (parity | databits); - umr2 |= (stopbits); - - /* reset the uart */ - MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_ERROR; - MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_RX; - MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_TX; - - /* reset the uart mode register and update values */ - MCF5235_UART_UCR(minor) = MCF5235_UART_UCR_RESET_MR; - MCF5235_UART_UMR(minor) = umr1; - MCF5235_UART_UMR(minor) = umr2; - - /* set the baud rate values */ - MCF5235_UART_UCSR(minor) = (MCF5235_UART_UCSR_RCS_SYS_CLK | MCF5235_UART_UCSR_TCS_SYS_CLK); - MCF5235_UART_UBG1(minor) = (divisor & 0xff00) >> 8; - MCF5235_UART_UBG2(minor) = (divisor & 0x00ff); - - /* enable the uart */ - MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_ENABLED | MCF5235_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if ( info->iomode != TERMIOS_POLLED ) - { - /* enable rx interrupts */ - info->uimr |= MCF5235_UART_UIMR_FFULL; - MCF5235_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if ( hwflow ) - { - /* assert the RTS line */ - MCF5235_UART_UOP1(minor) = 1; - } - - rtems_interrupt_enable(level); - -} - - -/*************************************************************************** - Function : IntUartSetAttributes - - Description : This provides the hardware-dependent portion of tcsetattr(). - value and sets it. At the moment this just sets the baud rate. - - Note: The highest baudrate is 115200 as this stays within - an error of +/- 5% at 25MHz processor clock - ***************************************************************************/ -static int -IntUartSetAttributes(int minor, const struct termios *t) -{ - /* set default index values */ - int baud = (int)19200; - int databits = (int)MCF5235_UART_UMR_BC_8; - int parity = (int)MCF5235_UART_UMR_PM_NONE; - int stopbits = (int)MCF5235_UART_UMR_STOP_BITS_1; - int hwflow = (int)0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* check to see if input is valid */ - if ( t != (const struct termios *)0 ) - { - /* determine baud rate index */ - baud = rtems_termios_baud_to_number(t->c_ospeed); - - /* determine data bits */ - switch ( t->c_cflag & CSIZE ) - { - case CS5: - databits = (int)MCF5235_UART_UMR_BC_5; - break; - case CS6: - databits = (int)MCF5235_UART_UMR_BC_6; - break; - case CS7: - databits = (int)MCF5235_UART_UMR_BC_7; - break; - case CS8: - databits = (int)MCF5235_UART_UMR_BC_8; - break; - } - - /* determine if parity is enabled */ - if ( t->c_cflag & PARENB ) - { - if ( t->c_cflag & PARODD ) - { - /* odd parity */ - parity = (int)MCF5235_UART_UMR_PM_ODD; - } - else - { - /* even parity */ - parity = (int)MCF5235_UART_UMR_PM_EVEN; - } - } - - /* determine stop bits */ - if ( t->c_cflag & CSTOPB ) - { - /* two stop bits */ - stopbits = (int)MCF5235_UART_UMR_STOP_BITS_2; - } - - /* check to see if hardware flow control */ - if ( t->c_cflag & CRTSCTS ) - { - hwflow = 1; - } - } - - /* check to see if values have changed */ - if ( ( baud != info->baud ) || - ( databits != info->databits ) || - ( parity != info->parity ) || - ( stopbits != info->stopbits ) || - ( hwflow != info->hwflow ) ) - { - - /* call function to set values */ - IntUartSet(minor, baud, databits, parity, stopbits, hwflow); - } - - return( RTEMS_SUCCESSFUL ); - -} - -/*************************************************************************** - Function : IntUartInterruptHandler - - Description : This is the interrupt handler for the internal uart. It - determines which channel caused the interrupt before queueing any received - chars and dequeueing chars waiting for transmission. - ***************************************************************************/ -static rtems_isr -IntUartInterruptHandler(rtems_vector_number v) -{ - unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); - struct IntUartInfoStruct *info = &IntUartInfo[chan]; - - /* check to see if received data */ - if ( MCF5235_UART_UISR(chan) & MCF5235_UART_UISR_RXRDY ) - { - /* read data and put into the receive buffer */ - while ( MCF5235_UART_USR(chan) & MCF5235_UART_USR_RXRDY ) - { - - if ( MCF5235_UART_USR(chan) & MCF5235_UART_USR_ERROR ) - { - /* clear the error */ - MCF5235_UART_UCR(chan) = MCF5235_UART_UCR_RESET_ERROR; - } - /* put data in rx buffer and check for errors */ - info->rx_buffer[info->rx_in] = MCF5235_UART_URB(chan); - - /* update buffer values */ - info->rx_in++; - - if ( info->rx_in >= RX_BUFFER_SIZE ) - { - info->rx_in = 0; - } - } - /* Make sure the port has been opened */ - if ( info->ttyp ) - { - - /* check to see if task driven */ - if ( info->iomode == TERMIOS_TASK_DRIVEN ) - { - /* notify rx task that rx buffer has data */ - rtems_termios_rxirq_occured(info->ttyp); - } - else - { - /* Push up the received data */ - rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, info->rx_in); - info->rx_in = 0; - } - } - } - - /* check to see if data needs to be transmitted */ - if ( ( info->uimr & MCF5235_UART_UIMR_TXRDY ) && - ( MCF5235_UART_UISR(chan) & MCF5235_UART_UISR_TXRDY ) ) - { - - /* disable tx interrupts */ - info->uimr &= ~MCF5235_UART_UIMR_TXRDY; - MCF5235_UART_UIMR(chan) = info->uimr; - - /* tell upper level that character has been sent */ - if ( info->ttyp ) - rtems_termios_dequeue_characters(info->ttyp, 1); - } -} - - - -/*************************************************************************** - Function : IntUartInitialize - - Description : This initialises the internal uart hardware for all - internal uarts. If the internal uart is to be interrupt driven then the - interrupt vectors are hooked. - ***************************************************************************/ -static void -IntUartInitialize(void) -{ - unsigned int chan; - struct IntUartInfoStruct *info; - rtems_isr_entry old_handler; - int level; - - for ( chan = 0; chan < MAX_UART_INFO; chan++ ) - { - info = &IntUartInfo[chan]; - - info->ttyp = NULL; - info->rx_in = 0; - info->rx_out = 0; - info->baud = -1; - info->databits = -1; - info->parity = -1; - info->stopbits = -1; - info->hwflow = -1; - info->iomode = TERMIOS_POLLED; /*polled console io */ - - MCF5235_UART_UACR(chan) = 0; - MCF5235_UART_UIMR(chan) = 0; - if ( info->iomode != TERMIOS_POLLED ) - { - rtems_interrupt_catch (IntUartInterruptHandler, - UART_INTC0_IRQ_VECTOR(chan), - &old_handler); - } - - /* set uart default values */ - IntUartSetAttributes(chan, NULL); - - /* unmask interrupt */ - rtems_interrupt_disable(level); - switch(chan) { - case 0: - MCF5235_INTC0_ICR13 = MCF5235_INTC_ICR_IL(UART0_IRQ_LEVEL) | - MCF5235_INTC_ICR_IP(UART0_IRQ_PRIORITY); - MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT13 | - MCF5235_INTC0_IMRL_MASKALL); - break; - - case 1: - MCF5235_INTC0_ICR14 = MCF5235_INTC_ICR_IL(UART1_IRQ_LEVEL) | - MCF5235_INTC_ICR_IP(UART1_IRQ_PRIORITY); - MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT14 | - MCF5235_INTC0_IMRL_MASKALL); - break; - - case 2: - MCF5235_INTC0_ICR15 = MCF5235_INTC_ICR_IL(UART2_IRQ_LEVEL) | - MCF5235_INTC_ICR_IP(UART2_IRQ_PRIORITY); - MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT15 | - MCF5235_INTC0_IMRL_MASKALL); - break; - } - rtems_interrupt_enable(level); - - } /* of chan loop */ - - -} /* IntUartInitialise */ - - -/*************************************************************************** - Function : IntUartInterruptWrite - - Description : This writes a single character to the appropriate uart - channel. This is either called during an interrupt or in the user's task - to initiate a transmit sequence. Calling this routine enables Tx - interrupts. - ***************************************************************************/ -static ssize_t -IntUartInterruptWrite (int minor, const char *buf, size_t len) -{ - if (len > 0) { - /* write out character */ - MCF5235_UART_UTB(minor) = *buf; - - /* enable tx interrupt */ - IntUartInfo[minor].uimr |= MCF5235_UART_UIMR_TXRDY; - MCF5235_UART_UIMR(minor) = IntUartInfo[minor].uimr; - } - - return( 0 ); -} - -/*************************************************************************** - Function : IntUartInterruptOpen - - Description : This enables interrupts when the tty is opened. - ***************************************************************************/ -static int -IntUartInterruptOpen(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* enable the uart */ - MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_ENABLED | MCF5235_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if ( info->iomode != TERMIOS_POLLED ) - { - /* enable rx interrupts */ - info->uimr |= MCF5235_UART_UIMR_FFULL; - MCF5235_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if ( info->hwflow ) - { - /* assert the RTS line */ - MCF5235_UART_UOP1(minor) = 1; - } - - return( 0 ); -} - - - -/*************************************************************************** - Function : IntUartInterruptClose - - Description : This disables interrupts when the tty is closed. - ***************************************************************************/ -static int -IntUartInterruptClose(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* disable the interrupts and the uart */ - MCF5235_UART_UIMR(minor) = 0; - MCF5235_UART_UCR(minor) = (MCF5235_UART_UCR_TX_DISABLED | MCF5235_UART_UCR_RX_DISABLED); - - /* reset values */ - info->ttyp = NULL; - info->uimr = 0; - info->rx_in = 0; - info->rx_out = 0; - - return( 0 ); -} - -/*************************************************************************** - Function : IntUartTaskRead - - Description : This reads all available characters from the internal uart - and places them into the termios buffer. The rx interrupts will be - re-enabled after all data has been read. - ***************************************************************************/ -static int -IntUartTaskRead(int minor) -{ - char buffer[RX_BUFFER_SIZE]; - int count; - int rx_in; - int index = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* determine number of values to copy out */ - rx_in = info->rx_in; - if ( info->rx_out <= rx_in ) - { - count = rx_in - info->rx_out; - } - else - { - count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; - } - - /* copy data into local buffer from rx buffer */ - while ( ( index < count ) && ( index < RX_BUFFER_SIZE ) ) - { - /* copy data byte */ - buffer[index] = info->rx_buffer[info->rx_out]; - index++; - - /* increment rx buffer values */ - info->rx_out++; - if ( info->rx_out >= RX_BUFFER_SIZE ) - { - info->rx_out = 0; - } - } - - /* check to see if buffer is not empty */ - if ( count > 0 ) - { - /* set characters into termios buffer */ - rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); - } - - return( EOF ); -} - - - -/*************************************************************************** - Function : IntUartPollRead - - Description : This reads a character from the internal uart. It returns - to the caller without blocking if not character is waiting. - ***************************************************************************/ -static int -IntUartPollRead (int minor) -{ - if ( (MCF5235_UART_USR(minor) & MCF5235_UART_USR_RXRDY) == 0 ) - return(-1); - - return(MCF5235_UART_URB(minor)); -} - - -/*************************************************************************** - Function : IntUartPollWrite - - Description : This writes out each character in the buffer to the - appropriate internal uart channel waiting till each one is sucessfully - transmitted. - ***************************************************************************/ -static ssize_t -IntUartPollWrite (int minor, const char *buf, size_t len) -{ - size_t retval = len; - /* loop over buffer */ - while ( len-- ) - { - /* block until we can transmit */ - while ( (MCF5235_UART_USR(minor) & MCF5235_UART_USR_TXRDY) == 0 ) - continue; - /* transmit data byte */ - MCF5235_UART_UTB(minor) = *buf++; - } - return retval; -} - -/*************************************************************************** - Function : console_initialize - - Description : This initialises termios, both sets of uart hardware before - registering /dev/tty devices for each channel and the system /dev/console. - ***************************************************************************/ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg ) -{ - rtems_status_code status; - - - /* Set up TERMIOS */ - rtems_termios_initialize (); - - /* set io modes for the different channels and initialize device */ - IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN; - IntUartInitialize(); - - /* Register the console port */ - status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - - /* Register the other port */ - if ( CONSOLE_PORT != 0 ) - { - status = rtems_io_register_name ("/dev/tty00", major, 0); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - } - if ( CONSOLE_PORT != 1 ) - { - status = rtems_io_register_name ("/dev/tty01", major, 1); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - } - - return(RTEMS_SUCCESSFUL); -} - -/*************************************************************************** - Function : console_open - - Description : This actually opens the device depending on the minor - number set during initialisation. The device specific access routines are - passed to termios when the devices is opened depending on whether it is - polled or not. - ***************************************************************************/ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - rtems_status_code status = RTEMS_INVALID_NUMBER; - rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *)arg; - struct IntUartInfoStruct *info; - - static const rtems_termios_callbacks IntUartPollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - IntUartPollRead, /* pollRead */ - IntUartPollWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_POLLED /* mode */ - }; - static const rtems_termios_callbacks IntUartIntrCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - NULL, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_IRQ_DRIVEN /* mode */ - }; - - static const rtems_termios_callbacks IntUartTaskCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - IntUartTaskRead, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_TASK_DRIVEN /* mode */ - }; - - /* open the port depending on the minor device number */ - if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) ) - { - info = &IntUartInfo[minor]; - switch ( info->iomode ) - { - case TERMIOS_POLLED: - status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); - break; - case TERMIOS_IRQ_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); - info->ttyp = args->iop->data1; - break; - case TERMIOS_TASK_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); - info->ttyp = args->iop->data1; - break; - } - } - - if (status == RTEMS_SUCCESSFUL) - { - /* - * Reset the default baudrate. - */ - struct termios term; - if (tcgetattr (STDIN_FILENO, &term) >= 0) - { - term.c_cflag &= ~(CSIZE); - term.c_cflag |= CS8; - term.c_ispeed = B19200; - term.c_ospeed = B19200; - tcsetattr (STDIN_FILENO, TCSANOW, &term); - } - } - - return( status ); -} - -/*************************************************************************** - Function : console_close - - Description : This closes the device via termios - ***************************************************************************/ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return(rtems_termios_close (arg)); -} - -/****************** -********************************************************* - Function : console_read - - Description : Read from the device via termios - ***************************************************************************/ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return(rtems_termios_read (arg)); -} - -/*************************************************************************** - Function : console_write - - Description : Write to the device via termios - ***************************************************************************/ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return(rtems_termios_write (arg)); -} - -/*************************************************************************** - Function : console_ioctl - - Description : Pass the IOCtl call to termios - ***************************************************************************/ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return( rtems_termios_ioctl (arg) ); -} diff --git a/c/src/lib/libbsp/m68k/mcf5329/Makefile.am b/c/src/lib/libbsp/m68k/mcf5329/Makefile.am index 5a82f8849f..1be86750a6 100644 --- a/c/src/lib/libbsp/m68k/mcf5329/Makefile.am +++ b/c/src/lib/libbsp/m68k/mcf5329/Makefile.am @@ -31,7 +31,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/setvec.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/mcf5329/clock/clock.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf5329/console/console.c # timer librtemsbsp_a_SOURCES += timer/timer.c diff --git a/c/src/lib/libbsp/m68k/mcf5329/console/console.c b/c/src/lib/libbsp/m68k/mcf5329/console/console.c deleted file mode 100644 index 797e5b0606..0000000000 --- a/c/src/lib/libbsp/m68k/mcf5329/console/console.c +++ /dev/null @@ -1,668 +0,0 @@ - /* - * Multi UART console serial I/O. - * - * TO DO: Add DMA input/output - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#define UART_INTC0_IRQ_VECTOR(x) (64+26+(x)) - -#define MCF_UART_USR_ERROR ( MCF_UART_USR_RB | \ - MCF_UART_USR_FE | \ - MCF_UART_USR_PE | \ - MCF_UART_USR_OE ) - -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); -static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len); - -static void _BSP_null_char(char c) -{ - int level; - - rtems_interrupt_disable(level); - while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0) - continue; - MCF_UART_UTB(CONSOLE_PORT) = c; - while ((MCF_UART_USR(CONSOLE_PORT) & MCF_UART_USR_TXRDY) == 0) - continue; - rtems_interrupt_enable(level); -} - -BSP_output_char_function_type BSP_output_char = _BSP_null_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - -#define MAX_UART_INFO 3 -#define RX_BUFFER_SIZE 512 - -struct IntUartInfoStruct -{ - int iomode; - volatile int uimr; - int baud; - int databits; - int parity; - int stopbits; - int hwflow; - int rx_in; - int rx_out; - char rx_buffer[RX_BUFFER_SIZE]; - void *ttyp; -}; - -struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; - -/*************************************************************************** - Function : IntUartSet - - Description : This updates the hardware UART settings. - ***************************************************************************/ -static void -IntUartSet(int minor, int baud, int databits, int parity, int stopbits, - int hwflow) -{ - int divisor; - uint32_t clock_speed; - uint8_t umr1 = 0; - uint8_t umr2 = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - int level; - - rtems_interrupt_disable(level); - - /* disable interrupts, clear RTS line, and disable the UARTS */ - MCF_UART_UIMR(minor) = 0; - MCF_UART_UOP0(minor) = 1; - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED); - - /* save the current values */ - info->uimr = 0; - info->baud = baud; - info->databits = databits; - info->parity = parity; - info->stopbits = stopbits; - info->hwflow = hwflow; - - clock_speed = bsp_get_BUS_clock_speed(); - /* determine the baud divisor value */ - divisor = ((clock_speed) / (32 * baud)); - if (divisor < 2) - divisor = 2; - - /* check to see if doing hardware flow control */ - if (hwflow) { - /* set hardware flow options */ - umr1 |= MCF_UART_UMR_RXRTS; - umr2 |= MCF_UART_UMR_TXCTS; - } - - /* determine the new umr values */ - umr1 |= (parity | databits); - umr2 |= (stopbits); - - /* reset the uart */ - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_ERROR; - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_RX; - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_TX; - - /* reset the uart mode register and update values */ - MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_MR; - MCF_UART_UMR(minor) = umr1; - MCF_UART_UMR(minor) = umr2; - - /* set the baud rate values */ - MCF_UART_UCSR(minor) = - (MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK); - MCF_UART_UBG1(minor) = (divisor & 0xff00) >> 8; - MCF_UART_UBG2(minor) = (divisor & 0x00ff); - - /* enable the uart */ - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if (info->iomode != TERMIOS_POLLED) { - /* enable rx interrupts */ - info->uimr |= MCF_UART_UIMR_RXRDY_FU; - MCF_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if (hwflow) { - /* assert the RTS line */ - MCF_UART_UOP1(minor) = 1; - } - - rtems_interrupt_enable(level); - -} - -/*************************************************************************** - Function : IntUartSetAttributes - - Description : This provides the hardware-dependent portion of tcsetattr(). - value and sets it. At the moment this just sets the baud rate. - - Note: The highest baudrate is 115200 as this stays within - an error of +/- 5% at 25MHz processor clock - ***************************************************************************/ -static int IntUartSetAttributes(int minor, const struct termios *t) -{ - /* set default index values */ - int baud = (int) 19200; - int databits = (int) MCF_UART_UMR_BC_8; - int parity = (int) MCF_UART_UMR_PM_NONE; - int stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_1; - int hwflow = (int) 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* check to see if input is valid */ - if (t != (const struct termios *) 0) { - /* determine baud rate index */ - baud = rtems_termios_baud_to_number(t->c_ospeed); - - /* determine data bits */ - switch (t->c_cflag & CSIZE) { - case CS5: - databits = (int) MCF_UART_UMR_BC_5; - break; - case CS6: - databits = (int) MCF_UART_UMR_BC_6; - break; - case CS7: - databits = (int) MCF_UART_UMR_BC_7; - break; - case CS8: - databits = (int) MCF_UART_UMR_BC_8; - break; - } - - /* determine if parity is enabled */ - if (t->c_cflag & PARENB) { - if (t->c_cflag & PARODD) { - /* odd parity */ - parity = (int) MCF_UART_UMR_PM_ODD; - } else { - /* even parity */ - parity = (int) MCF_UART_UMR_PM_EVEN; - } - } - - /* determine stop bits */ - if (t->c_cflag & CSTOPB) { - /* two stop bits */ - stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_2; - } - - /* check to see if hardware flow control */ - if (t->c_cflag & CRTSCTS) { - hwflow = 1; - } - } - - /* check to see if values have changed */ - if ((baud != info->baud) || - (databits != info->databits) || - (parity != info->parity) || - (stopbits != info->stopbits) || (hwflow != info->hwflow)) { - - /* call function to set values */ - IntUartSet(minor, baud, databits, parity, stopbits, hwflow); - } - - return (RTEMS_SUCCESSFUL); - -} - -/*************************************************************************** - Function : IntUartInterruptHandler - - Description : This is the interrupt handler for the internal uart. It - determines which channel caused the interrupt before queueing any received - chars and dequeueing chars waiting for transmission. - ***************************************************************************/ -static rtems_isr IntUartInterruptHandler(rtems_vector_number v) -{ - unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); - struct IntUartInfoStruct *info = &IntUartInfo[chan]; - - /* check to see if received data */ - if (MCF_UART_UISR(chan) & MCF_UART_UISR_RXRDY_FU) { - /* read data and put into the receive buffer */ - while (MCF_UART_USR(chan) & MCF_UART_USR_RXRDY) { - - if (MCF_UART_USR(chan) & MCF_UART_USR_ERROR) { - /* clear the error */ - MCF_UART_UCR(chan) = MCF_UART_UCR_RESET_ERROR; - } - /* put data in rx buffer and check for errors */ - info->rx_buffer[info->rx_in] = MCF_UART_URB(chan); - - /* update buffer values */ - info->rx_in++; - - if (info->rx_in >= RX_BUFFER_SIZE) { - info->rx_in = 0; - } - } - /* Make sure the port has been opened */ - if (info->ttyp) { - - /* check to see if task driven */ - if (info->iomode == TERMIOS_TASK_DRIVEN) { - /* notify rx task that rx buffer has data */ - rtems_termios_rxirq_occured(info->ttyp); - } else { - /* Push up the received data */ - rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, - info->rx_in); - info->rx_in = 0; - } - } - } - - /* check to see if data needs to be transmitted */ - if ((info->uimr & MCF_UART_UIMR_TXRDY) && - (MCF_UART_UISR(chan) & MCF_UART_UISR_TXRDY)) { - - /* disable tx interrupts */ - info->uimr &= ~MCF_UART_UIMR_TXRDY; - MCF_UART_UIMR(chan) = info->uimr; - - /* tell upper level that character has been sent */ - if (info->ttyp) - rtems_termios_dequeue_characters(info->ttyp, 1); - } -} - -/*************************************************************************** - Function : IntUartInitialize - - Description : This initialises the internal uart hardware for all - internal uarts. If the internal uart is to be interrupt driven then the - interrupt vectors are hooked. - ***************************************************************************/ -static void IntUartInitialize(void) -{ - unsigned int chan; - struct IntUartInfoStruct *info; - rtems_isr_entry old_handler; - int level; - - for (chan = 0; chan < MAX_UART_INFO; chan++) { - info = &IntUartInfo[chan]; - - info->ttyp = NULL; - info->rx_in = 0; - info->rx_out = 0; - info->baud = -1; - info->databits = -1; - info->parity = -1; - info->stopbits = -1; - info->hwflow = -1; - info->iomode = TERMIOS_POLLED; /*polled console io */ - - MCF_UART_UACR(chan) = 0; - MCF_UART_UIMR(chan) = 0; - if (info->iomode != TERMIOS_POLLED) { - rtems_interrupt_catch(IntUartInterruptHandler, - UART_INTC0_IRQ_VECTOR(chan), &old_handler); - } - - /* set uart default values */ - IntUartSetAttributes(chan, NULL); - - /* unmask interrupt */ - rtems_interrupt_disable(level); - switch (chan) { - case 0: - MCF_INTC0_ICR26 = MCF_INTC_ICR_IL(UART0_IRQ_LEVEL); - MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_INT_MASK26); - break; - - case 1: - MCF_INTC0_ICR27 = MCF_INTC_ICR_IL(UART1_IRQ_LEVEL); - MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_INT_MASK27); - break; - - case 2: - MCF_INTC0_ICR28 = MCF_INTC_ICR_IL(UART2_IRQ_LEVEL); - MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_INT_MASK28); - break; - } - rtems_interrupt_enable(level); - - } /* of chan loop */ - -} /* IntUartInitialise */ - -/*************************************************************************** - Function : IntUartInterruptWrite - - Description : This writes a single character to the appropriate uart - channel. This is either called during an interrupt or in the user's task - to initiate a transmit sequence. Calling this routine enables Tx - interrupts. - ***************************************************************************/ -static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len) -{ - if (len > 0) { - /* write out character */ - MCF_UART_UTB(minor) = *buf; - - /* enable tx interrupt */ - IntUartInfo[minor].uimr |= MCF_UART_UIMR_TXRDY; - MCF_UART_UIMR(minor) = IntUartInfo[minor].uimr; - } - - return (0); -} - -/*************************************************************************** - Function : IntUartInterruptOpen - - Description : This enables interrupts when the tty is opened. - ***************************************************************************/ -static int IntUartInterruptOpen(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* enable the uart */ - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if (info->iomode != TERMIOS_POLLED) { - /* enable rx interrupts */ - info->uimr |= MCF_UART_UIMR_RXRDY_FU; - MCF_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if (info->hwflow) { - /* assert the RTS line */ - MCF_UART_UOP1(minor) = 1; - } - - return (0); -} - -/*************************************************************************** - Function : IntUartInterruptClose - - Description : This disables interrupts when the tty is closed. - ***************************************************************************/ -static int IntUartInterruptClose(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* disable the interrupts and the uart */ - MCF_UART_UIMR(minor) = 0; - MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED); - - /* reset values */ - info->ttyp = NULL; - info->uimr = 0; - info->rx_in = 0; - info->rx_out = 0; - - return (0); -} - -/*************************************************************************** - Function : IntUartTaskRead - - Description : This reads all available characters from the internal uart - and places them into the termios buffer. The rx interrupts will be - re-enabled after all data has been read. - ***************************************************************************/ -static int IntUartTaskRead(int minor) -{ - char buffer[RX_BUFFER_SIZE]; - int count; - int rx_in; - int index = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* determine number of values to copy out */ - rx_in = info->rx_in; - if (info->rx_out <= rx_in) { - count = rx_in - info->rx_out; - } else { - count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; - } - - /* copy data into local buffer from rx buffer */ - while ((index < count) && (index < RX_BUFFER_SIZE)) { - /* copy data byte */ - buffer[index] = info->rx_buffer[info->rx_out]; - index++; - - /* increment rx buffer values */ - info->rx_out++; - if (info->rx_out >= RX_BUFFER_SIZE) { - info->rx_out = 0; - } - } - - /* check to see if buffer is not empty */ - if (count > 0) { - /* set characters into termios buffer */ - rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); - } - - return (EOF); -} - -/*************************************************************************** - Function : IntUartPollRead - - Description : This reads a character from the internal uart. It returns - to the caller without blocking if not character is waiting. - ***************************************************************************/ -static int IntUartPollRead(int minor) -{ - if ((MCF_UART_USR(minor) & MCF_UART_USR_RXRDY) == 0) - return (-1); - - return (MCF_UART_URB(minor)); -} - -/*************************************************************************** - Function : IntUartPollWrite - - Description : This writes out each character in the buffer to the - appropriate internal uart channel waiting till each one is sucessfully - transmitted. - ***************************************************************************/ -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len) -{ - size_t retval = len; - /* loop over buffer */ - while (len--) { - /* block until we can transmit */ - while ((MCF_UART_USR(minor) & MCF_UART_USR_TXRDY) == 0) - continue; - /* transmit data byte */ - MCF_UART_UTB(minor) = *buf++; - } - return retval; -} - -/*************************************************************************** - Function : console_initialize - - Description : This initialises termios, both sets of uart hardware before - registering /dev/tty devices for each channel and the system /dev/console. - ***************************************************************************/ -rtems_device_driver console_initialize(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - rtems_status_code status; - - /* Set up TERMIOS */ - rtems_termios_initialize(); - - /* set io modes for the different channels and initialize device */ - IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN; - IntUartInitialize(); - - /* Register the console port */ - status = rtems_io_register_name("/dev/console", major, CONSOLE_PORT); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - - /* Register the other port */ - if (CONSOLE_PORT != 0) { - status = rtems_io_register_name("/dev/tty00", major, 0); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - } - if (CONSOLE_PORT != 1) { - status = rtems_io_register_name("/dev/tty01", major, 1); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - } - - return (RTEMS_SUCCESSFUL); -} - -/*************************************************************************** - Function : console_open - - Description : This actually opens the device depending on the minor - number set during initialisation. The device specific access routines are - passed to termios when the devices is opened depending on whether it is - polled or not. - ***************************************************************************/ -rtems_device_driver console_open(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - rtems_status_code status = RTEMS_INVALID_NUMBER; - rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *) arg; - struct IntUartInfoStruct *info; - - static const rtems_termios_callbacks IntUartPollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - IntUartPollRead, /* pollRead */ - IntUartPollWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_POLLED /* mode */ - }; - static const rtems_termios_callbacks IntUartIntrCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - NULL, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_IRQ_DRIVEN /* mode */ - }; - - static const rtems_termios_callbacks IntUartTaskCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - IntUartTaskRead, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_TASK_DRIVEN /* mode */ - }; - - /* open the port depending on the minor device number */ - if ((minor >= 0) && (minor < MAX_UART_INFO)) { - info = &IntUartInfo[minor]; - switch (info->iomode) { - case TERMIOS_POLLED: - status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); - break; - case TERMIOS_IRQ_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); - info->ttyp = args->iop->data1; - break; - case TERMIOS_TASK_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); - info->ttyp = args->iop->data1; - break; - } - } - - if (status == RTEMS_SUCCESSFUL) { - /* - * Reset the default baudrate. - */ - struct termios term; - - if (tcgetattr(STDIN_FILENO, &term) >= 0) { - term.c_cflag &= ~(CSIZE); - term.c_cflag |= CS8; - term.c_ispeed = B19200; - term.c_ospeed = B19200; - tcsetattr(STDIN_FILENO, TCSANOW, &term); - } - } - - return (status); -} - -/*************************************************************************** - Function : console_close - - Description : This closes the device via termios - ***************************************************************************/ -rtems_device_driver console_close(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - return (rtems_termios_close(arg)); -} - -/*************************************************************************** - Function : console_read - - Description : Read from the device via termios - ***************************************************************************/ -rtems_device_driver console_read(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - return (rtems_termios_read(arg)); -} - -/*************************************************************************** - Function : console_write - - Description : Write to the device via termios - ***************************************************************************/ -rtems_device_driver console_write(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) -{ - return (rtems_termios_write(arg)); -} - -/*************************************************************************** - Function : console_ioctl - - Description : Pass the IOCtl call to termios - ***************************************************************************/ -rtems_device_driver console_control(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - return (rtems_termios_ioctl(arg)); -} diff --git a/c/src/lib/libbsp/m68k/mrm332/Makefile.am b/c/src/lib/libbsp/m68k/mrm332/Makefile.am index 462628eba3..4677565797 100644 --- a/c/src/lib/libbsp/m68k/mrm332/Makefile.am +++ b/c/src/lib/libbsp/m68k/mrm332/Makefile.am @@ -29,8 +29,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/mrm332/clock/ckinit.c # console -librtemsbsp_a_SOURCES += console/console.c -librtemsbsp_a_SOURCES += console/sci.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mrm332/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mrm332/console/sci.c # spurious librtemsbsp_a_SOURCES += spurious/spinit.c # timer diff --git a/c/src/lib/libbsp/m68k/mrm332/console/console.c b/c/src/lib/libbsp/m68k/mrm332/console/console.c deleted file mode 100644 index 7b5ae7d51c..0000000000 --- a/c/src/lib/libbsp/m68k/mrm332/console/console.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * COPYRIGHT (c) 1989-1997. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include -#include -#include "sci.h" - -/* - * console_open - * - * open a port as a termios console. - */ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_status_code status; - - /* the console is opened three times at startup */ - /* for standard input, output, and error */ - - /* Get correct callback structure for the device */ - - /* argument of FALSE gives us interrupt driven serial io */ - /* argument of TRUE gives us polling based serial io */ - - /* SCI internal uart */ - - status = rtems_termios_open( major, minor, arg, SciGetTermiosHandlers( FALSE ) ); - - return status; -} - -/* - * console_close - * - * This routine closes a port that has been opened as console. - */ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_close (arg); -} - -/* - * console_read - * - * This routine uses the termios driver to read a character. - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_read (arg); -} - -/* - * console_write - * - * this routine uses the termios driver to write a character. - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_write (arg); -} - -/* - * console_control - * - * this routine uses the termios driver to process io - */ - -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_ioctl (arg); -} - -/* - * console_initialize - * - * Routine called to initialize the console device driver. - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor_arg, - void *arg -) -{ - rtems_status_code status; - - /* - * initialize the termio interface. - */ - rtems_termios_initialize(); - - /* - * register the SCI device name for termios - * do this over in the sci driver init routine? - */ - - status = rtems_io_register_name( "/dev/sci", major, 0 ); - - if (status != RTEMS_SUCCESSFUL) - { - rtems_fatal_error_occurred(status); - } - - /* - * Link the uart device to the console device - */ - -#if 1 - status = rtems_io_register_name( "/dev/console", major, 0 ); - - if (status != RTEMS_SUCCESSFUL) - { - rtems_fatal_error_occurred(status); - } -#else - if ( link( "/dev/sci", "/dev/console") < 0 ) - { - rtems_fatal_error_occurred( RTEMS_IO_ERROR ); - } -#endif - - /* - * Console Initialize Succesful - */ - - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/lib/libbsp/m68k/mrm332/console/sci.c b/c/src/lib/libbsp/m68k/mrm332/console/sci.c deleted file mode 100644 index c6b4933f13..0000000000 --- a/c/src/lib/libbsp/m68k/mrm332/console/sci.c +++ /dev/null @@ -1,1586 +0,0 @@ -/***************************************************************************** -* File: sci.c -* -* Desc: This file contains the console IO routines for the SCI port. -* There are two interfaces in this module. One is for the rtems -* termios/console code and the other is a device driver interface. -* This module works together with the termio module which is -* sometimes referred to as the "line disciplines" which implements -* terminal i/o processing like tabs, backspaces, and newlines. -* The rtems printf uses interrupt io and the rtems printk routine -* uses polled io which is better for debugging. -* -* Index: Documentation -* Section A - Include Files -* Section B - Manifest Constants -* Section C - External Data -* Section D - External Functions -* Section E - Local Functions -* Section F - Local Variables -* Section G - A circular data buffer for rcv chars -* Section H - RTEMS termios callbacks for the interrupt api -* Section I - RTEMS termios callbacks for the polled api - -* Section 0 - Miscellaneous routines -* Section 1 - Routines to manipulate the circular buffer -* Section 2 - Interrupt based entry points for the termios module -* Section 3 - Polling based entry points for the termios module -* Section 4 - Device driver public api entry points -* Section 5 - Hardware level routines -* Section 6 - Testing and debugging code -* -* Refer: Motorola QSM Reference Manual - Chapter 5 - SCI sub-module -* -* Note: See bsp.h,confdefs.h,system.h for installing drivers into RTEMS. -* -*****************************************************************************/ - -/***************************************************************************** - Overview of serial port console terminal input/output -*****************************************************************************/ - -/* - +-----------+ +---------+ - | app | | app | - +-----------+ +---------+ - | | - | (printf,scanf,etc.) | - v | - +-----------+ | - | libc | | - +-----------+ | - | | - | | - | (open,close,read,write,ioctl) | - ======|==========================================|======================== - | /dev/console | /dev/sci - | (stdin,stdout,stderr) | - ======|==========================================|======================== - | | - | | - v v - +-----------+ +-----------+ +---------+ - | console | <---> | termios | <---> | sci | - | driver | | module | | driver | - +-----------+ +-----------+ +---------+ - | - | - v - +---------+ - | | - | uart | - | | - +---------+ -*/ - - -/***************************************************************************** - Section A - Include Files -*****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include "sci.h" -#include -#include -/*#include "../misc/include/cpu332.h" */ - -/***************************************************************************** - Section B - Manifest Constants -*****************************************************************************/ - -#define SCI_MINOR 0 /* minor device number */ - -/* IMPORTANT - if the device driver api is opened, it means the sci is being - * used for direct hardware access, so other users (like termios) get ignored - */ -#define DRIVER_CLOSED 0 /* the device driver api is closed */ -#define DRIVER_OPENED 1 /* the device driver api is opened */ - -/* system clock definitions, i dont have documentation on this... */ - -#if 0 /* Not needed, this is provided in mrm332.h */ -#define XTAL 32768.0 /* crystal frequency in Hz */ -#define NUMB_W 0 /* system clock parameters */ -#define NUMB_X 1 -#define NUMB_Y 0x38 /* for 14.942 Mhz */ -#define NUMB_Y 0x3F /* for 16.777 Mhz */ - -#define SYS_CLOCK (XTAL * 4.0 * (NUMB_Y+1) * (1 << (2 * NUMB_W + NUMB_X))) - -#endif - - -/***************************************************************************** - Section C - External Data -*****************************************************************************/ - - - -/***************************************************************************** - Section D - External Functions -*****************************************************************************/ - - - -/***************************************************************************** - Section E - Local Functions -*****************************************************************************/ - -void SCI_output_char(char c); - -/*rtems_isr SciIsr( rtems_vector_number vector ); interrupt handler */ - -const rtems_termios_callbacks * SciGetTermiosHandlers( int32_t polled ); - -rtems_device_driver SciInitialize( /* device driver api */ - rtems_device_major_number, rtems_device_minor_number, void *); -rtems_device_driver SciOpen( /* device driver api */ - rtems_device_major_number, rtems_device_minor_number, void *); -rtems_device_driver SciClose( /* device driver api */ - rtems_device_major_number, rtems_device_minor_number, void *); -rtems_device_driver SciRead( /* device driver api */ - rtems_device_major_number, rtems_device_minor_number, void *); -rtems_device_driver SciWrite( /* device driver api */ - rtems_device_major_number, rtems_device_minor_number, void *); -rtems_device_driver SciControl( /* device driver api */ - rtems_device_major_number, rtems_device_minor_number, void *); -rtems_device_driver SciRead ( - rtems_device_major_number, rtems_device_minor_number, void *); - -rtems_isr SciIsr( rtems_vector_number vector ); - -int SciInterruptOpen(int, int, void *); /* termios api */ -int SciInterruptClose(int, int, void *); /* termios api */ -ssize_t SciInterruptWrite(int, const char *, size_t); /* termios api */ - -int SciSetAttributes(int, const struct termios*); /* termios api */ -int SciPolledOpen(int, int, void *); /* termios api */ -int SciPolledClose(int, int, void *); /* termios api */ -int SciPolledRead(int); /* termios api */ -ssize_t SciPolledWrite(int, const char *, size_t); /* termios api */ - -static void SciSetBaud(uint32_t rate); /* hardware routine */ -static void SciSetDataBits(uint16_t bits); /* hardware routine */ -static void SciSetParity(uint16_t parity); /* hardware routine */ - -static void inline SciDisableAllInterrupts( void ); /* hardware routine */ -static void inline SciDisableTransmitInterrupts( void );/* hardware routine */ -static void inline SciDisableReceiveInterrupts( void ); /* hardware routine */ - -static void inline SciEnableTransmitInterrupts( void ); /* hardware routine */ -static void inline SciEnableReceiveInterrupts( void ); /* hardware routine */ - -static void inline SciDisableReceiver( void ); /* hardware routine */ -static void inline SciDisableTransmitter( void ); /* hardware routine */ - -static void inline SciEnableReceiver( void ); /* hardware routine */ -static void inline SciEnableTransmitter( void ); /* hardware routine */ - -void SciWriteCharWait ( uint8_t ); /* hardware routine */ -void SciWriteCharNoWait( uint8_t ); /* hardware routine */ - -uint8_t inline SciCharAvailable( void ); /* hardware routine */ - -static uint8_t inline SciReadCharWait( void ); /* hardware routine */ -static uint8_t inline SciReadCharNoWait( void ); /* hardware routine */ - -void SciSendBreak( void ); /* test routine */ - -static int8_t SciRcvBufGetChar(void); /* circular rcv buf */ -static void SciRcvBufPutChar( uint8_t); /* circular rcv buf */ -#if 0 -static void SciRcvBufFlush( void ); /* unused routine */ -#endif - -void SciUnitTest(void); /* test routine */ -void SciPrintStats(void); /* test routine */ - - -/***************************************************************************** - Section F - Local Variables -*****************************************************************************/ - -static struct rtems_termios_tty *SciTermioTty; - -static uint8_t SciInited = 0; /* has the driver been inited */ - -static uint8_t SciOpened; /* has the driver been opened */ - -static uint8_t SciMajor; /* major device number */ - -static uint16_t SciBaud; /* current value in baud register */ - -static uint32_t SciBytesIn = 0; /* bytes received */ -static uint32_t SciBytesOut = 0; /* bytes transmitted */ - -static uint32_t SciErrorsParity = 0; /* error counter */ -static uint32_t SciErrorsNoise = 0; /* error counter */ -static uint32_t SciErrorsFraming = 0; /* error counter */ -static uint32_t SciErrorsOverrun = 0; /* error counter */ - -#if defined(CONSOLE_SCI) - -/* this is what rtems printk uses to do polling based output */ - -BSP_output_char_function_type BSP_output_char = SCI_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - -#endif - -/***************************************************************************** - Section G - A circular buffer for rcv chars when the driver interface is used. -*****************************************************************************/ - -/* it is trivial to wrap your buffer pointers when size is a power of two */ - -#define SCI_RCV_BUF_SIZE 256 /* must be a power of 2 !!! */ - -/* if someone opens the sci device using the device driver interface, - * then the receive data interrupt handler will put characters in this buffer - * instead of sending them up to the termios module for the console - */ -static uint8_t SciRcvBuffer[SCI_RCV_BUF_SIZE]; - -static uint8_t SciRcvBufPutIndex = 0; /* array index to put in next char */ - -static uint8_t SciRcvBufGetIndex = 0; /* array index to take out next char */ - -static uint16_t SciRcvBufCount = 0; /* how many bytes are in the buffer */ - - - -/***************************************************************************** - Section H - RTEMS termios callbacks for the interrupt version of the driver -*****************************************************************************/ - -static const rtems_termios_callbacks SciInterruptCallbacks = -{ - SciInterruptOpen, /* first open */ - SciInterruptClose, /* last close */ - NULL, /* polled read (not required) */ - SciInterruptWrite, /* write */ - SciSetAttributes, /* set attributes */ - NULL, /* stop remote xmit */ - NULL, /* start remote xmit */ - TRUE /* output uses interrupts */ -}; - -/***************************************************************************** - Section I - RTEMS termios callbacks for the polled version of the driver -*****************************************************************************/ - -static const rtems_termios_callbacks SciPolledCallbacks = -{ - SciPolledOpen, /* first open */ - SciPolledClose, /* last close */ - SciPolledRead, /* polled read */ - SciPolledWrite, /* write */ - SciSetAttributes, /* set attributes */ - NULL, /* stop remote xmit */ - NULL, /* start remote xmit */ - FALSE /* output uses interrupts */ -}; - - -/* - * SECTION 0 - * MISCELLANEOUS ROUTINES - */ - -/**************************************************************************** - * Func: SCI_output_char - * Desc: used by rtems printk function to send a char to the uart - * Inputs: the character to transmit - * Outputs: none - * Errors: none - * Scope: public - ****************************************************************************/ - -void SCI_output_char(char c) -{ -/* ( minor device number, pointer to the character, length ) */ - - SciPolledWrite( SCI_MINOR, &c, 1); - - return; -} - - -/**************************************************************************** -* Func: SciGetTermiosHandlers -* Desc: returns a pointer to the table of serial io functions -* this is called from console_open with polled set to false -* Inputs: flag indicating whether we want polled or interrupt driven io -* Outputs: pointer to function table -* Errors: none -* Scope: public -****************************************************************************/ - -const rtems_termios_callbacks * SciGetTermiosHandlers( int32_t polled ) -{ - if ( polled ) - { - return &SciPolledCallbacks; /* polling based */ - } - else - { - return &SciInterruptCallbacks; /* interrupt driven */ - } -} - - -/**************************************************************************** -* Func: SciIsr -* Desc: interrupt handler for serial communications interface -* Inputs: vector number - unused -* Outputs: none -* Errors: none -* Scope: public API -****************************************************************************/ - -rtems_isr SciIsr( rtems_vector_number vector ) -{ - uint8_t ch; - - if ( (*SCSR) & SCI_ERROR_PARITY ) SciErrorsParity ++; - if ( (*SCSR) & SCI_ERROR_FRAMING ) SciErrorsFraming ++; - if ( (*SCSR) & SCI_ERROR_NOISE ) SciErrorsNoise ++; - if ( (*SCSR) & SCI_ERROR_OVERRUN ) SciErrorsOverrun ++; - - /* see if it was a transmit interrupt */ - /* data reg empty, xmt complete */ - if ( ( *SCCR1 & SCI_ENABLE_INT_TX ) && ( (*SCSR) & SCI_XMTR_AVAILABLE ) ) - { - SciDisableTransmitInterrupts(); - - /* tell termios module that the charcter was sent */ - /* he will call us later to transmit more if there are any */ - - if (rtems_termios_dequeue_characters( SciTermioTty, 1 )) - { - /* there are more bytes to transmit so enable TX interrupt */ - - SciEnableTransmitInterrupts(); - } - } - - /* see if it was a receive interrupt */ - /* on the sci uart we just get one character per interrupt */ - - while ( SciCharAvailable() ) /* char in data register? */ - { - ch = SciReadCharNoWait(); /* get the char from the uart */ - - /* IMPORTANT!!! */ - /* either send it to the termios module or keep it locally */ - - if ( SciOpened == DRIVER_OPENED ) /* the driver is open */ - { - SciRcvBufPutChar(ch); /* keep it locally */ - } - else /* put in termios buffer */ - { - char c = (char) ch; - rtems_termios_enqueue_raw_characters( SciTermioTty, &c, 1 ); - } - - *SCSR &= SCI_CLEAR_RX_INT; /* clear the interrupt */ - } -} - - -/* - * SECTION 1 - * ROUTINES TO MANIPULATE THE CIRCULAR BUFFER - */ - -/**************************************************************************** -* Func: SciRcvBufGetChar -* Desc: read a character from the circular buffer -* make sure there is data before you call this! -* Inputs: none -* Outputs: the character or -1 -* Errors: none -* Scope: private -****************************************************************************/ - -static int8_t SciRcvBufGetChar(void) -{ - rtems_interrupt_level level; - uint8_t ch; - - if ( SciRcvBufCount == 0 ) - { - rtems_fatal_error_occurred(0xDEAD); /* check the count first! */ - } - - rtems_interrupt_disable( level ); /* disable interrupts */ - - ch = SciRcvBuffer[SciRcvBufGetIndex]; /* get next byte */ - - SciRcvBufGetIndex++; /* bump the index */ - - SciRcvBufGetIndex &= SCI_RCV_BUF_SIZE - 1; /* and wrap it */ - - SciRcvBufCount--; /* decrement counter */ - - rtems_interrupt_enable( level ); /* restore interrupts */ - - return ch; /* return the char */ -} - - -/**************************************************************************** -* Func: SciRcvBufPutChar -* Desc: put a character into the rcv data circular buffer -* Inputs: the character -* Outputs: none -* Errors: none -* Scope: private -****************************************************************************/ - -static void SciRcvBufPutChar( uint8_t ch ) -{ - rtems_interrupt_level level; - - if ( SciRcvBufCount == SCI_RCV_BUF_SIZE ) /* is there room? */ - { - return; /* no, throw it away */ - } - - rtems_interrupt_disable( level ); /* disable interrupts */ - - SciRcvBuffer[SciRcvBufPutIndex] = ch; /* put it in the buf */ - - SciRcvBufPutIndex++; /* bump the index */ - - SciRcvBufPutIndex &= SCI_RCV_BUF_SIZE - 1; /* and wrap it */ - - SciRcvBufCount++; /* increment counter */ - - rtems_interrupt_enable( level ); /* restore interrupts */ - - return; /* return */ -} - - -/**************************************************************************** -* Func: SciRcvBufFlush -* Desc: completely reset and clear the rcv buffer -* Inputs: none -* Outputs: none -* Errors: none -* Scope: private -****************************************************************************/ - -#if 0 /* prevents compiler warning */ -static void SciRcvBufFlush( void ) -{ - rtems_interrupt_level level; - - rtems_interrupt_disable( level ); /* disable interrupts */ - - memset( SciRcvBuffer, 0, sizeof(SciRcvBuffer) ); - - SciRcvBufPutIndex = 0; /* clear */ - - SciRcvBufGetIndex = 0; /* clear */ - - SciRcvBufCount = 0; /* clear */ - - rtems_interrupt_enable( level ); /* restore interrupts */ - - return; /* return */ -} -#endif - - -/* - * - * SECTION 2 - * INTERRUPT BASED ENTRY POINTS FOR THE TERMIOS MODULE - */ - -/**************************************************************************** -* Func: SciInterruptOpen -* Desc: open routine for the interrupt based device driver -* Default state is 9600 baud, 8 bits, No parity, and 1 stop bit. ?? -**CHANGED** Default baud rate is now 19200, 8N1 -* called from rtems_termios_open which is called from console_open -* Inputs: major - device number -* minor - device number -* args - points to terminal info -* Outputs: success/fail -* Errors: none -* Scope: public API -****************************************************************************/ - -int SciInterruptOpen( - int major, - int minor, - void *arg -) -{ - rtems_libio_open_close_args_t * args = arg; - rtems_isr_entry old_vector; - - if ( minor != SCI_MINOR ) /* check minor device num */ - { - return -1; - } - - if ( !args ) /* must have args */ - { - return -1; - } - - SciTermioTty = args->iop->data1; /* save address of struct */ - - SciDisableAllInterrupts(); /* turn off sci interrupts */ - - /* THIS IS ACTUALLY A BAD THING - SETTING LINE PARAMETERS HERE */ - /* IT SHOULD BE DONE THROUGH TCSETATTR() WHEN THE CONSOLE IS OPENED!!! */ - -/* SciSetBaud(115200); set the baud rate */ -/* SciSetBaud( 57600); set the baud rate */ -/* SciSetBaud( 38400); set the baud rate */ -/* SciSetBaud( 19200); set the baud rate */ - SciSetBaud( 9600); /* set the baud rate */ - - SciSetParity(SCI_PARITY_NONE); /* set parity to none */ - - SciSetDataBits(SCI_8_DATA_BITS); /* set data bits to 8 */ - - /* Install our interrupt handler into RTEMS. */ - /* 68 is an unused user-defined vector. Note that the vector must be */ - /* even - it sets the low bit for SPI interrupts, and clears it for */ - /* SCI interrupts. Also note that vector 66 is used by CPU32bug on */ - /* the mrm332. */ - - rtems_interrupt_catch( SciIsr, 68, &old_vector ); - - *QSMCR = (*QSMCR & ~IARB) | 1; // Is 1 a good value for qsm iarb? - *QIVR = 68; - *QILR &= 0xf8; - *QILR |= 0x06 & 0x07; - - SciEnableTransmitter(); /* enable the transmitter */ - - SciEnableReceiver(); /* enable the receiver */ - - SciEnableReceiveInterrupts(); /* enable rcv interrupts */ - - return RTEMS_SUCCESSFUL; -} - - -/**************************************************************************** -* Func: SciInterruptClose -* Desc: close routine called by the termios module -* Inputs: major - device number -* minor - device number -* args - unused -* Outputs: success/fail -* Errors: none -* Scope: public - termio entry point -****************************************************************************/ - -int SciInterruptClose( - int major, - int minor, - void *arg -) -{ - SciDisableAllInterrupts(); - - return RTEMS_SUCCESSFUL; -} - - -/**************************************************************************** -* Func: SciInterruptWrite -* Desc: writes data to the uart using transmit interrupts -* Inputs: minor - device number -* buf - points to the data -* len - number of bytes to send -* Outputs: success/fail -* Errors: none -* Scope: public API -****************************************************************************/ - -ssize_t SciInterruptWrite( - int minor, - const char *buf, - size_t len -) -{ - /* We are using interrupt driven output so termios only sends us */ - /* one character at a time. The sci does not have a fifo. */ - - if ( !len ) /* no data? */ - { - return -1; /* return error */ - } - - if ( minor != SCI_MINOR ) /* check the minor dev num */ - { - return -1; /* return error */ - } - - if ( SciOpened == DRIVER_OPENED ) /* is the driver api open? */ - { - return -1; /* yep, throw this away */ - } - - SciWriteCharNoWait(*buf); /* try to send a char */ - - *SCSR &= SCI_CLEAR_TDRE; /* clear tx data reg empty flag */ - - SciEnableTransmitInterrupts(); /* enable the tx interrupt */ - - return 0; /* return success */ -} - - -/**************************************************************************** -* Func: SciSetAttributes -* Desc: setup the uart based on the termios modules requests -* Inputs: minor - device number -* t - pointer to the termios info struct -* Outputs: none -* Errors: none -* Scope: public API -****************************************************************************/ - -int SciSetAttributes( - int minor, - const struct termios *t -) -{ - uint32_t baud_requested; - uint32_t sci_rate = 0; - uint16_t sci_parity = 0; - uint16_t sci_databits = 0; - - if ( minor != SCI_MINOR ) /* check the minor dev num */ - { - return -1; /* return error */ - } - - /* if you look closely you will see this is the only thing we use */ - /* set the baud rate */ - - baud_requested = t->c_ospeed; /* baud rate */ - - if (!baud_requested) - { - baud_requested = B9600; /* default to 9600 baud */ - /* baud_requested = B19200; default to 19200 baud */ - } - - sci_rate = rtems_termios_baud_to_number( baud_requested ); - - /* parity error detection */ - - if (t->c_cflag & PARENB) /* enable parity detection? */ - { - if (t->c_cflag & PARODD) - { - sci_parity = SCI_PARITY_ODD; /* select odd parity */ - } - else - { - sci_parity = SCI_PARITY_EVEN; /* select even parity */ - } - } - else - { - sci_parity = SCI_PARITY_NONE; /* no parity, most common */ - } - - /* set the number of data bits, 8 is most common */ - - if (t->c_cflag & CSIZE) /* was it specified? */ - { - switch (t->c_cflag & CSIZE) - { - case CS8: sci_databits = SCI_8_DATA_BITS; break; - default : sci_databits = SCI_9_DATA_BITS; break; - } - } - else - { - sci_databits = SCI_8_DATA_BITS; /* default to 8 data bits */ - } - - /* the number of stop bits; always 1 for SCI */ - - if (t->c_cflag & CSTOPB) - { - /* do nothing */ - } - - /* setup the hardware with these serial port parameters */ - - SciSetBaud(sci_rate); /* set the baud rate */ - SciSetParity(sci_parity); /* set the parity type */ - SciSetDataBits(sci_databits); /* set the data bits */ - - return RTEMS_SUCCESSFUL; -} - - -/* - * - * SECTION 3 - * POLLING BASED ENTRY POINTS FOR THE TERMIOS MODULE - */ - -/**************************************************************************** -* Func: SciPolledOpen -* Desc: open routine for the polled i/o version of the driver -* called from rtems_termios_open which is called from console_open -* Inputs: major - device number -* minor - device number -* args - points to terminal info struct -* Outputs: success/fail -* Errors: none -* Scope: public - termios entry point -****************************************************************************/ - -int SciPolledOpen( - int major, - int minor, - void *arg -) -{ - rtems_libio_open_close_args_t * args = arg; - - if ( minor != SCI_MINOR ) /* check minor device num */ - { - return -1; - } - - if ( !args ) /* must have args */ - { - return -1; - } - - SciTermioTty = args->iop->data1; /* Store tty pointer */ - - SciDisableAllInterrupts(); /* don't generate interrupts */ - - /* THIS IS ACTUALLY A BAD THING - SETTING LINE PARAMETERS HERE */ - /* IT SHOULD BE DONE THROUGH TCSETATTR() WHEN THE CONSOLE IS OPENED!!! */ - -/* SciSetBaud(115200); set the baud rate */ -/* SciSetBaud( 57600); set the baud rate */ -/* SciSetBaud( 38400); set the baud rate */ -/* SciSetBaud( 19200); * set the baud rate */ - SciSetBaud( 9600); /* set the baud rate */ - - SciSetParity(SCI_PARITY_NONE); /* set no parity */ - - SciSetDataBits(SCI_8_DATA_BITS); /* set 8 data bits */ - - SciEnableTransmitter(); /* enable the xmitter */ - - SciEnableReceiver(); /* enable the rcvr */ - - return RTEMS_SUCCESSFUL; -} - - -/**************************************************************************** -* Func: SciPolledClose -* Desc: close routine for the device driver, same for both -* Inputs: major - device number -* minor - device number -* args - unused -* Outputs: success/fail -* Errors: none -* Scope: public termios API -****************************************************************************/ - -int SciPolledClose( - int major, - int minor, - void *arg -) -{ - SciDisableAllInterrupts(); - - return RTEMS_SUCCESSFUL; -} - - -/**************************************************************************** -* Func: SciPolledRead -* Desc: polling based read routine for the uart -* Inputs: minor - device number -* Outputs: error or the character read -* Errors: none -* Scope: public API -****************************************************************************/ - -int SciPolledRead( - int minor -) -{ - if ( minor != SCI_MINOR ) /* check the type-punned dev num */ - { - return -1; /* return error */ - } - - if ( SciCharAvailable() ) /* if a char is available */ - { - return SciReadCharNoWait(); /* read the rx data register */ - } - - return -1; /* return error */ -} - - -/**************************************************************************** -* Func: SciPolledWrite -* Desc: writes out characters in polled mode, waiting for the uart -* check in console_open, but we only seem to use interrupt mode -* Inputs: minor - device number -* buf - points to the data -* len - how many bytes -* Outputs: error or number of bytes written -* Errors: none -* Scope: public termios API -****************************************************************************/ - -ssize_t SciPolledWrite( - int minor, - const char *buf, - size_t len -) -{ - ssize_t written = 0; - - if ( minor != SCI_MINOR ) /* check minor device num */ - { - return -1; - } - - if ( SciOpened == DRIVER_OPENED ) /* is the driver api open? */ - { - return -1; /* toss the data */ - } - - /* send each byte in the string out the port */ - - while ( written < len ) - { - SciWriteCharWait(*buf++); /* send a byte */ - - written++; /* increment counter */ - } - - return written; /* return count */ -} - - -/* - * - * SECTION 4 - * DEVICE DRIVER PUBLIC API ENTRY POINTS - */ - -/**************************************************************************** -* Func: SciInit -* Desc: Initialize the lasers device driver and hardware -* Inputs: major - the major device number which is assigned by rtems -* minor - the minor device number which is undefined at this point -* arg - ????? -* Outputs: RTEMS_SUCCESSFUL -* Errors: None. -* Scope: public API -****************************************************************************/ - -rtems_device_driver SciInitialize ( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ -/* rtems_status_code status; */ - -/*printk("%s\r\n", __FUNCTION__); */ - - /* register the SCI device name for termios console i/o - * this is done over in console.c which doesn't seem exactly right - * but there were problems doing it here... - */ - -/* status = rtems_io_register_name( "/dev/sci", major, 0 ); */ - -/* if (status != RTEMS_SUCCESSFUL) */ -/* rtems_fatal_error_occurred(status); */ - - SciMajor = major; /* save the rtems major number */ - - SciOpened = DRIVER_CLOSED; /* initial state is closed */ - - /* if you have an interrupt handler, install it here */ - - SciInited = 1; /* set the inited flag */ - - return RTEMS_SUCCESSFUL; -} - - -/**************************************************************************** -* Func: SciOpen -* Desc: device driver open routine -* you must open a device before you can anything else -* only one process can have the device opened at a time -* you could look at the task id to restrict access if you want -* Inputs: major - the major device number assigned by rtems -* minor - the minor device number assigned by us -* arg - ????? -* Outputs: see below -* Errors: none -* Scope: public API -****************************************************************************/ - -rtems_device_driver SciOpen ( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ -/*printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor); */ - - if (SciInited == 0) /* must be initialized first! */ - { - return RTEMS_NOT_CONFIGURED; - } - - if (minor != SCI_MINOR) - { - return RTEMS_INVALID_NAME; /* verify minor number */ - } - - if (SciOpened == DRIVER_OPENED) - { - return RTEMS_RESOURCE_IN_USE; /* already opened! */ - } - - SciOpened = DRIVER_OPENED; /* set the opened flag */ - - return RTEMS_SUCCESSFUL; -} - - -/**************************************************************************** -* Func: SciClose -* Desc: device driver close routine -* the device must be opened before you can close it -* the device must be closed before someone (else) can open it -* Inputs: major - the major device number -* minor - the minor device number -* arg - ????? -* Outputs: see below -* Errors: none -* Scope: public API -****************************************************************************/ - -rtems_device_driver SciClose ( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ -/*printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor); */ - - if (minor != SCI_MINOR) - { - return RTEMS_INVALID_NAME; /* check the minor number */ - } - - if (SciOpened != DRIVER_OPENED) - { - return RTEMS_INCORRECT_STATE; /* must be opened first */ - } - - SciOpened = DRIVER_CLOSED; /* set the flag */ - - return RTEMS_SUCCESSFUL; -} - - -/**************************************************************************** -* Func: SciRead -* Desc: device driver read routine -* this function is not meaningful for the laser devices -* Inputs: major - the major device number -* minor - the minor device number -* arg - read/write arguments -* Outputs: see below -* Errors: none -* Scope: public API -****************************************************************************/ - -rtems_device_driver SciRead ( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_libio_rw_args_t *rw_args; /* ptr to argument struct */ - char *buffer; - - rw_args = (rtems_libio_rw_args_t *) arg; /* arguments to read() */ - - if (minor != SCI_MINOR) - { - return RTEMS_INVALID_NAME; /* check the minor number */ - } - - if (SciOpened == DRIVER_CLOSED) - { - return RTEMS_INCORRECT_STATE; /* must be opened first */ - } - - buffer = rw_args->buffer; /* points to user's buffer */ - -/* *buffer = SciReadCharWait(); wait for a character */ - - /* if there isn't a character available, wait until one shows up */ - /* or the timeout period expires, which ever happens first */ - - if ( SciRcvBufCount == 0 ) /* no chars */ - { - /* wait for someone to wake me up... */ - /*rtems_task_wake_after(SciReadTimeout); */ - } - - if ( SciRcvBufCount ) /* any characters locally? */ - { - *buffer = SciRcvBufGetChar(); /* get the character */ - - rw_args->bytes_moved = 1; /* how many we actually read */ - } - - return RTEMS_SUCCESSFUL; -} - - -/**************************************************************************** -* Func: SciWrite -* Desc: device driver write routine -* this function is not meaningful for the laser devices -* Inputs: major - the major device number -* minor - the minor device number -* arg - read/write arguments -* Outputs: see below -* Errors: non3 -* Scope: public API -****************************************************************************/ - -rtems_device_driver SciWrite ( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args; /* ptr to argument struct */ - uint8_t *buffer; - size_t length; - - rw_args = (rtems_libio_rw_args_t *) arg; - - if (minor != SCI_MINOR) - { - return RTEMS_INVALID_NAME; /* check the minor number */ - } - - if (SciOpened == DRIVER_CLOSED) - { - return RTEMS_INCORRECT_STATE; /* must be opened first */ - } - - buffer = (uint8_t*)rw_args->buffer; /* points to data */ - - length = rw_args->count; /* how many bytes */ - - while (length--) - { - SciWriteCharWait(*buffer++); /* send the bytes out */ - } - - rw_args->bytes_moved = rw_args->count; /* how many we wrote */ - - return RTEMS_SUCCESSFUL; -} - - -/**************************************************************************** -* Func: SciControl -* Desc: device driver control routine -* see below for an example of how to use the ioctl interface -* Inputs: major - the major device number -* minor - the minor device number -* arg - io control args -* Outputs: see below -* Errors: none -* Scope: public API -****************************************************************************/ - -rtems_device_driver SciControl ( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_ioctl_args_t *args = arg; /* rtems arg struct */ - uint16_t command; /* the cmd to execute */ - -/*printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor); */ - - /* do some sanity checking */ - - if (minor != SCI_MINOR) - { - return RTEMS_INVALID_NAME; /* check the minor number */ - } - - if (SciOpened == DRIVER_CLOSED) - { - return RTEMS_INCORRECT_STATE; /* must be open first */ - } - - if (args == 0) - { - return RTEMS_INVALID_ADDRESS; /* must have args */ - } - - args->ioctl_return = -1; /* assume an error */ - - command = args->command; /* get the command */ - - if (command == SCI_SEND_BREAK) /* process the command */ - { - SciSendBreak(); /* send break char */ - } - - args->ioctl_return = 0; /* return status */ - - return RTEMS_SUCCESSFUL; -} - - -/* - * - * SECTION 5 - * HARDWARE LEVEL ROUTINES - */ - -/**************************************************************************** -* Func: SciSetBaud -* Desc: setup the uart based on the termios modules requests -* Inputs: baud rate -* Outputs: none -* Errors: none -* Scope: private -****************************************************************************/ - -static void SciSetBaud(uint32_t rate) -{ - uint16_t value; - uint16_t save_sccr1; - -/* when you open the console you need to set the termio struct baud rate */ -/* it has a default value of 9600, when someone calls tcsetattr it reverts! */ - - SciBaud = rate; /* save the rate */ - - /* calculate the register value as a float and convert to an int */ - /* set baud rate - you must define the system clock constant */ - /* see mrm332.h for an example */ - - value = ( (uint16_t) ( SYS_CLOCK / rate / 32.0 + 0.5 ) & 0x1fff ); - - save_sccr1 = *SCCR1; /* save register */ - - /* also turns off the xmtr and rcvr */ - - *SCCR1 &= SCI_DISABLE_INT_ALL; /* disable interrupts */ - - *SCCR0 = value; /* write the register */ - - *SCCR1 = save_sccr1; /* restore register */ - - return; -} - - -/**************************************************************************** -* Func: SciSetParity -* Desc: setup the uart based on the termios modules requests -* Inputs: parity -* Outputs: none -* Errors: none -* Scope: private -****************************************************************************/ - -static void SciSetParity(uint16_t parity) -{ - uint16_t value; - - value = *SCCR1; /* get the register */ - - if (parity == SCI_PARITY_ODD) - { - value |= SCI_PARITY_ENABLE; /* parity enabled */ - value |= SCI_PARITY_ODD; /* parity odd */ - } - - else if (parity == SCI_PARITY_EVEN) - { - value |= SCI_PARITY_ENABLE; /* parity enabled */ - value &= ~SCI_PARITY_ODD; /* parity even */ - } - - else if (parity == SCI_PARITY_NONE) - { - value &= ~SCI_PARITY_ENABLE; /* disabled, most common */ - } - - /* else no changes */ - - *SCCR1 = value; /* write the register */ - - return; -} - - -/**************************************************************************** -* Func: SciSetDataBits -* Desc: setup the uart based on the termios modules requests -* Inputs: data bits -* Outputs: none -* Errors: none -* Scope: private -****************************************************************************/ - -static void SciSetDataBits(uint16_t bits) -{ - uint16_t value; - - value = *SCCR1; /* get the register */ - - /* note - the parity setting affects the number of data bits */ - - if (bits == SCI_9_DATA_BITS) - { - value |= SCI_9_DATA_BITS; /* 9 data bits */ - } - - else if (bits == SCI_8_DATA_BITS) - { - value &= SCI_8_DATA_BITS; /* 8 data bits */ - } - - /* else no changes */ - - *SCCR1 = value; /* write the register */ - - return; -} - - -/**************************************************************************** -* Func: SciDisableAllInterrupts -* Func: SciEnableTransmitInterrupts -* Func: SciEnableReceiveInterrupts -* Desc: handles generation of interrupts by the sci module -* Inputs: none -* Outputs: none -* Errors: none -* Scope: private -****************************************************************************/ - -static void inline SciDisableAllInterrupts( void ) -{ - /* this also turns off the xmtr and rcvr */ - - *SCCR1 &= SCI_DISABLE_INT_ALL; -} - -static void inline SciEnableReceiveInterrupts( void ) -{ - *SCCR1 |= SCI_ENABLE_INT_RX; -} - -static void inline SciDisableReceiveInterrupts( void ) -{ - *SCCR1 &= SCI_DISABLE_INT_RX; -} - -static void inline SciEnableTransmitInterrupts( void ) -{ - *SCCR1 |= SCI_ENABLE_INT_TX; -} - -static void inline SciDisableTransmitInterrupts( void ) -{ - *SCCR1 &= SCI_DISABLE_INT_TX; -} - - -/**************************************************************************** -* Func: SciEnableTransmitter, SciDisableTransmitter -* Func: SciEnableReceiver, SciDisableReceiver -* Desc: turns the transmitter and receiver on and off -* Inputs: none -* Outputs: none -* Errors: none -* Scope: private -****************************************************************************/ - -static void inline SciEnableTransmitter( void ) -{ - *SCCR1 |= SCI_ENABLE_XMTR; -} - -static void inline SciDisableTransmitter( void ) -{ - *SCCR1 &= SCI_DISABLE_XMTR; -} - -static void inline SciEnableReceiver( void ) -{ - *SCCR1 |= SCI_ENABLE_RCVR; -} - -static void inline SciDisableReceiver( void ) -{ - *SCCR1 &= SCI_DISABLE_RCVR; -} - - -/**************************************************************************** -* Func: SciWriteCharWait -* Desc: wait for room in the fifo and then put a char in -* Inputs: a byte to send -* Outputs: none -* Errors: none -* Scope: public -****************************************************************************/ - -void SciWriteCharWait(uint8_t c) -{ - /* poll the fifo, waiting for room for another character */ - - while ( ( *SCSR & SCI_XMTR_AVAILABLE ) != SCI_XMTR_AVAILABLE ) - { - /* Either we are writing to the fifo faster than - * the uart can clock bytes out onto the cable, - * or we are in flow control (actually no, we - * are ignoring flow control from the other end). - * In the first case, higher baud rates will help. - */ - /* relinquish processor while waiting */ - rtems_task_wake_after(RTEMS_YIELD_PROCESSOR); - } - - *SCDR = c; /* send the charcter */ - - SciBytesOut++; /* increment the counter */ - - return; -} - -/**************************************************************************** -* Func: SciWriteCharNoWait -* Desc: if no room in the fifo throw the char on the floor -* Inputs: a byte to send -* Outputs: none -* Errors: none -* Scope: public -****************************************************************************/ - -void SciWriteCharNoWait(uint8_t c) -{ - if ( ( *SCSR & SCI_XMTR_AVAILABLE ) == 0 ) - { - return; /* no room, throw it away */ - } - - *SCDR = c; /* put the char in the fifo */ - - SciBytesOut++; /* increment the counter */ - - return; -} - - -/**************************************************************************** -* Func: SciReadCharWait -* Desc: read a character, waiting for one to show up, if need be -* Inputs: none -* Outputs: a character -* Errors: none -* Scope: public -****************************************************************************/ - -static uint8_t inline SciReadCharWait( void ) -{ - uint8_t ch; - - while ( SciCharAvailable() == 0 ) /* anything there? */ - { - /* relinquish processor while waiting */ - rtems_task_wake_after(RTEMS_YIELD_PROCESSOR); - } - - /* if you have rcv ints enabled, then the isr will probably */ - /* get the character before you will unless you turn off ints */ - /* ie polling and ints don't mix that well */ - - ch = *SCDR; /* get the charcter */ - - SciBytesIn++; /* increment the counter */ - - return ch; /* return the char */ -} - -/**************************************************************************** -* Func: SciReadCharNoWait -* Desc: try to get a char but dont wait for one -* Inputs: none -* Outputs: a character or -1 if none -* Errors: none -* Scope: public -****************************************************************************/ - -static uint8_t inline SciReadCharNoWait( void ) -{ - uint8_t ch; - - if ( SciCharAvailable() == 0 ) /* anything there? */ - return -1; - - ch = *SCDR; /* get the character */ - - SciBytesIn++; /* increment the count */ - - return ch; /* return the char */ -} - - -/**************************************************************************** -* Func: SciCharAvailable -* Desc: is there a receive character in the data register -* Inputs: none -* Outputs: false if no char available, else true -* Errors: none -* Scope: public -****************************************************************************/ - -uint8_t inline SciCharAvailable( void ) -{ - return ( *SCSR & SCI_RCVR_READY ); /* char in data register? */ -} - - -/**************************************************************************** -* Func: SciSendBreak -* Desc: send 1 or tow breaks (all zero bits) -* Inputs: none -* Outputs: none -* Errors: none -* Scope: public -****************************************************************************/ - -void SciSendBreak( void ) -{ - /* From the Motorola QSM reference manual - */ - - /* "if SBK is toggled by writing it first to a one and then immediately */ - /* to a zero (in less than one serial frame interval), the transmitter */ - /* sends only one or two break frames before reverting to mark (idle) */ - /* or before commencing to send more data" */ - - *SCCR1 |= SCI_SEND_BREAK; /* set the bit */ - - *SCCR1 &= ~SCI_SEND_BREAK; /* clear the bit */ - - return; -} - - -/* - * - * SECTION 6 - * TEST CODE - */ - -/**************************************************************************** -* Func: SciUnitTest -* Desc: test the device driver -* Inputs: nothing -* Outputs: nothing -* Scope: public -****************************************************************************/ - -#if 0 -void SciUnitTest() -{ - uint8_t byte; /* a character */ - uint16_t fd; /* file descriptor for device */ - uint16_t result; /* result of ioctl */ - - fd = open("/dev/sci",O_RDWR); /* open the device */ - -printk("SCI open fd=%d\r\n",fd); - - result = write(fd, "abcd\r\n", 6); /* send a string */ - -printk("SCI write result=%d\r\n",result); - - result = read(fd, &byte, 1); /* read a byte */ - -printk("SCI read result=%d,byte=%x\r\n",result,byte); - - return; -} -#endif - - -/**************************************************************************** -* Func: SciPrintStats -* Desc: print out some driver information -* Inputs: nothing -* Outputs: nothing -* Scope: public -****************************************************************************/ - -void SciPrintStats ( void ) -{ - printk("\r\n"); - - printk( "SYS_CLOCK is %2.6f Mhz\r\n\n", SYS_CLOCK / 1000000.0 ); - - printk( "Current baud rate is %d bps or %d cps\r\n\n", SciBaud, SciBaud / 10 ); - - printk( "SCI Uart chars in %8" PRIu32 "\r\n", SciBytesIn ); - printk( "SCI Uart chars out %8" PRIu32 "\r\n", SciBytesOut ); - printk( "SCI Uart framing errors %8" PRIu32 "\r\n", SciErrorsFraming ); - printk( "SCI Uart parity errors %8" PRIu32 "\r\n", SciErrorsParity ); - printk( "SCI Uart overrun errors %8" PRIu32 "\r\n", SciErrorsOverrun ); - printk( "SCI Uart noise errors %8" PRIu32 "\r\n", SciErrorsNoise ); - - return; -} diff --git a/c/src/lib/libbsp/m68k/mrm332/console/sci.h b/c/src/lib/libbsp/m68k/mrm332/console/sci.h deleted file mode 100644 index 93893ecbfc..0000000000 --- a/c/src/lib/libbsp/m68k/mrm332/console/sci.h +++ /dev/null @@ -1,233 +0,0 @@ -/**************************************************************************** -* File: sci.h -* -* Desc: This is the include file for the serial communications interface. -* -* Note: See bsp.h,confdefs.h,system.h for installing drivers into RTEMS. -* -****************************************************************************/ - -#ifndef _sci_h_ -#define _sci_h_ - -/******************************************************************************* - IOCTL commands for the sci driver. - I'm still working on these... -*******************************************************************************/ - -#define SCI_IOCTL_PARITY_NONE 0x00 /* no parity bit after the data bits */ -#define SCI_IOCTL_PARITY_ODD 0x01 /* parity bit added after data bits */ -#define SCI_IOCTL_PARITY_EVEN 0x02 /* parity bit added after data bits */ -#define SCI_IOCTL_PARITY_MARK 0x03 /* parity bit is lo, -12 volts, logical 1 */ -#define SCI_IOCTL_PARITY_SPACE 0x04 /* parity bit is hi, +12 volts, logical 0 */ -#define SCI_IOCTL_PARITY_FORCED_ON 0x03 /* parity bit is forced hi or lo */ -#define SCI_IOCTL_PARITY_FORCED_OFF 0x04 /* parity bit is forced hi or lo */ - -#define SCI_IOCTL_BAUD_RATE 0x20 /* set the baud rate, arg is baud */ - -#define SCI_IOCTL_DATA_BITS 0x30 /* set the data bits, arg is # bits */ - -#define SCI_IOCTL_STOP_BITS_1 0x40 /* 1 stop bit after char frame */ -#define SCI_IOCTL_STOP_BITS_2 0x41 /* 2 stop bit after char frame */ - -#define SCI_IOCTL_MODE_NORMAL 0x50 /* normal operating mode */ -#define SCI_IOCTL_MODE_LOOP 0x51 /* internal loopback mode */ - -#define SCI_IOCTL_FLOW_NONE 0x60 /* no flow control */ -#define SCI_IOCTL_FLOW_RTS_CTS 0x61 /* hardware flow control */ - -#define SCI_IOCTL_SEND_BREAK 0x70 /* send an rs-232 break */ - -#define SCI_IOCTL_MODE_1200 0x80 /* 1200,n,8,1 download mode */ -#define SCI_IOCTL_MODE_9600 0x81 /* 9600,n,8,1 download mode */ -#define SCI_IOCTL_MODE_9_BIT 0x82 /* 9600,forced,8,1 command mode */ - - -/******************************************************************************* - SCI Registers -*******************************************************************************/ - -/* SCI Control Register 0 (SCCR0) $FFFC08 - - 8 4 2 1 - 8 4 2 1 - 8 4 2 1 - 8 4 2 1 - ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ - | | | | | | | | | | | | | | | | - | | | | | | | | | | | | | | | +----- 0 baud rate divisor - | | | | | | | | | | | | | | +------- 1 baud rate divisor - | | | | | | | | | | | | | +--------- 2 baud rate divisor - | | | | | | | | | | | | +----------- 3 baud rate divisor - | | | | | | | | | | | | - | | | | | | | | | | | +--------------- 4 baud rate divisor - | | | | | | | | | | +----------------- 5 baud rate divisor - | | | | | | | | | +------------------- 6 baud rate divisor - | | | | | | | | +--------------------- 7 baud rate divisor - | | | | | | | | - | | | | | | | +------------------------- 8 baud rate divisor - | | | | | | +--------------------------- 9 baud rate divisor - | | | | | +----------------------------- 10 baud rate divisor - | | | | +------------------------------- 11 baud rate divisor - | | | | - | | | +----------------------------------- 12 baud rate divisor - | | +------------------------------------- 13 unused - | +--------------------------------------- 14 unused - +----------------------------------------- 15 unused - - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 1 0 0 reset value - (64k baud?) - */ - -#define SCI_BAUD_57_6K 9 -#define SCI_BAUD_38_4K 14 -#define SCI_BAUD_19_2K 27 -#define SCI_BAUD_9600 55 -#define SCI_BAUD_4800 109 -#define SCI_BAUD_2400 218 -#define SCI_BAUD_1200 437 - - -/* SCI Control Register 1 (SCCR1) $FFFC0A - - 8 4 2 1 - 8 4 2 1 - 8 4 2 1 - 8 4 2 1 - ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ - | | | | | | | | | | | | | | | | - | | | | | | | | | | | | | | | +----- 0 send a break - | | | | | | | | | | | | | | +------- 1 rcvr wakeup mode - | | | | | | | | | | | | | +--------- 2 rcvr enable - | | | | | | | | | | | | +----------- 3 xmtr enable - | | | | | | | | | | | | - | | | | | | | | | | | +--------------- 4 idle line intr enable - | | | | | | | | | | +----------------- 5 rcvr intr enable - | | | | | | | | | +------------------- 6 xmit complete intr enable - | | | | | | | | +--------------------- 7 xmtr intr enable - | | | | | | | | - | | | | | | | +------------------------- 8 wakeup on address mark - | | | | | | +--------------------------- 9 mode 1=9 bits, 0=8 bits - | | | | | +----------------------------- 10 parity enable 1=on, 0=off - | | | | +------------------------------- 11 parity type 1=odd, 0=even - | | | | - | | | +----------------------------------- 12 idle line select - | | +------------------------------------- 13 wired-or mode - | +--------------------------------------- 14 loop mode - +----------------------------------------- 15 unused - - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 reset value -*/ - -#define SCI_SEND_BREAK 0x0001 /* 0000-0000-0000-0001 */ -#define SCI_RCVR_WAKEUP 0x0002 /* 0000-0000-0000-0010 */ -#define SCI_ENABLE_RCVR 0x0004 /* 0000-0000-0000-0100 */ -#define SCI_ENABLE_XMTR 0x0008 /* 0000-0000-0000-1000 */ - -#define SCI_DISABLE_RCVR 0xFFFB /* 1111-1111-1111-1011 */ -#define SCI_DISABLE_XMTR 0xFFF7 /* 1111-1111-1111-0111 */ - -#define SCI_ENABLE_INT_IDLE 0x0010 /* 0000-0000-0001-0000 */ -#define SCI_ENABLE_INT_RX 0x0020 /* 0000-0000-0010-0000 */ -#define SCI_ENABLE_INT_TX_DONE 0x0040 /* 0000-0000-0100-0000 */ -#define SCI_ENABLE_INT_TX 0x0080 /* 0000-0000-1000-0000 */ - -#define SCI_DISABLE_INT_ALL 0xFF00 /* 1111-1111-0000-0000 ??? */ - -#define SCI_DISABLE_INT_RX 0xFFDF /* 1111-1111-1101-1111 */ -#define SCI_CLEAR_RX_INT 0xFFBF /* 1111-1111-1011-1111 */ -#define SCI_DISABLE_INT_TX 0xFF7F /* 1111-1111-0111-1111 */ -#define SCI_CLEAR_TDRE 0xFEFF /* 1111-1110-1111-1111 */ - -#define SCI_RCVR_WAKE_ON_MARK 0x0100 /* 0000-0001-0000-0000 */ -#define SCI_9_DATA_BITS 0x0200 /* 0000-0010-0000-0000 */ -#define SCI_PARITY_ENABLE 0x0400 /* 0000-0100-0000-0000 */ -#define SCI_PARITY_ODD 0x0800 /* 0000-1000-0000-0000 */ - -#define SCI_RCVR_WAKE_ON_IDLE 0xFEFF /* 1111-1110-1111-1111 */ -#define SCI_8_DATA_BITS 0xFDFF /* 1111-1101-1111-1111 */ -#define SCI_PARITY_DISABLE 0xFBFF /* 1111-1011-1111-1111 */ -#define SCI_PARITY_EVEN 0xF7FF /* 1111-0111-1111-1111 */ - -#define SCI_PARITY_NONE 0xF3FF /* 1111-0011-1111-1111 */ - -#define SCI_IDLE_LINE_LONG 0x1000 /* 0001-0000-0000-0000 */ -#define SCI_TXD_OPEN_DRAIN 0x2000 /* 0010-0000-0000-0000 */ -#define SCI_LOOPBACK_MODE 0x4000 /* 0100-0000-0000-0000 */ -#define SCI_SCCR1_UNUSED 0x8000 /* 1000-0000-0000-0000 */ - - -/* SCI Status Register (SCSR) $FFFC0C - - 8 4 2 1 - 8 4 2 1 - 8 4 2 1 - 8 4 2 1 - ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ - | | | | | | | | | | | | | | | | - | | | | | | | | | | | | | | | +----- 0 PF - parity error - | | | | | | | | | | | | | | +------- 1 FE - framing error - | | | | | | | | | | | | | +--------- 2 NF - noise flag - | | | | | | | | | | | | +----------- 3 OR - overrun flag - | | | | | | | | | | | | - | | | | | | | | | | | +--------------- 4 IDLE - idle line detected - | | | | | | | | | | +----------------- 5 RAF - rcvr active flag - | | | | | | | | | +------------------- 6 RDRF - rcv data reg full - | | | | | | | | +--------------------- 7 TC - xmt complete flag - | | | | | | | | - | | | | | | | +------------------------- 8 TDRE - xmt data reg empty - | | | | | | +--------------------------- 9 always zero - | | | | | +----------------------------- 10 always zero - | | | | +------------------------------- 11 always zero - | | | | - | | | +----------------------------------- 12 always zero - | | +------------------------------------- 13 always zero - | +--------------------------------------- 14 always zero - +----------------------------------------- 15 always zero - - 0 0 0 0 - 0 0 0 1 - 1 0 0 0 - 0 0 0 0 reset value -*/ - -#define SCI_ERROR_PARITY 0x0001 /* 0000-0000-0000-0001 */ -#define SCI_ERROR_FRAMING 0x0002 /* 0000-0000-0000-0010 */ -#define SCI_ERROR_NOISE 0x0004 /* 0000-0000-0000-0100 */ -#define SCI_ERROR_OVERRUN 0x0008 /* 0000-0000-0000-1000 */ - -#define SCI_IDLE_LINE 0x0010 /* 0000-0000-0001-0000 */ -#define SCI_RCVR_ACTIVE 0x0020 /* 0000-0000-0010-0000 */ -#define SCI_RCVR_READY 0x0040 /* 0000-0000-0100-0000 */ -#define SCI_XMTR_IDLE 0x0080 /* 0000-0000-1000-0000 */ - -#define SCI_CLEAR_RX_INT 0xFFBF /* 1111-1111-1011-1111 */ - -#define SCI_XMTR_READY 0x0100 /* 0000-0001-0000-0000 */ - -#define SCI_CLEAR_TDRE 0xFEFF /* 1111-1110-1111-1111 */ - -#define SCI_XMTR_AVAILABLE 0x0180 /* 0000-0001-1000-0000 */ - - - -/******************************************************************************* - Function prototypes -*******************************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -/* look at console_open to see how this is called */ - -const rtems_termios_callbacks * SciGetTermiosHandlers( int32_t polled ); - -/* SCI interrupt */ - -/*rtems_isr SciIsr( rtems_vector_number vector ); */ - -/*int32_t SciOpenPolled ( int32_t major, int32_t minor, void *arg ); */ -/*int32_t SciOpenInterrupt ( int32_t major, int32_t minor, void *arg ); */ - -/*int32_t SciClose ( int32_t major, int32_t minor, void *arg ); */ - -/*int32_t SciWritePolled ( int32_t minor, const char *buf, int32_t len ); */ -/*int32_t SciWriteInterrupt( int32_t minor, const char *buf, int32_t len ); */ - -/*int32_t SciReadPolled ( int32_t minor ); */ - -/*int32_t SciSetAttributes ( int32_t minor, const struct termios *t ); */ - -#ifdef __cplusplus -} -#endif - -#endif /* _sci_h_ */ diff --git a/c/src/lib/libbsp/m68k/mvme147/Makefile.am b/c/src/lib/libbsp/m68k/mvme147/Makefile.am index d8397be9a4..846c77e37c 100644 --- a/c/src/lib/libbsp/m68k/mvme147/Makefile.am +++ b/c/src/lib/libbsp/m68k/mvme147/Makefile.am @@ -30,8 +30,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/mvme147/clock/ckinit.c # console -librtemsbsp_a_SOURCES += console/console.c -librtemsbsp_a_SOURCES += ../../shared/dummy_printk_support.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme147/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/printk-dummy.c # timer librtemsbsp_a_SOURCES += timer/timer.c librtemsbsp_a_SOURCES += timer/timerisr.S diff --git a/c/src/lib/libbsp/m68k/mvme147/console/console.c b/c/src/lib/libbsp/m68k/mvme147/console/console.c deleted file mode 100644 index f26ca6485a..0000000000 --- a/c/src/lib/libbsp/m68k/mvme147/console/console.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * This file contains the MVME147 console IO package. - */ - -/* - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - * MVME147 port for TNI - Telecom Bretagne - * by Dominique LE CAMPION (Dominique.LECAMPION@enst-bretagne.fr) - * May 1996 - * - * This file was taken from the DMV152 bsp - */ - -#define M147_INIT - -#include -#include -#include -#include -#include - -/* console_initialize - * - * This routine initializes the console IO driver. - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - - status = rtems_io_register_name( - "/dev/console", - major, - (rtems_device_minor_number) 0 - ); - - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - return RTEMS_SUCCESSFUL; -} - -/* inbyte - * - * This routine reads a character from the SCC. - */ -static char inbyte( void ) -{ - uint8_t rr_0; - char ch; - - for ( ; ; ) { - Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); - if ( (rr_0 & RR_0_RX_DATA_AVAILABLE) != 0 ) - break; - } - - Z8x30_READ_DATA( CONSOLE_DATA, ch ); - return ( ch ); -} - -/* outbyte - * - * This routine transmits a character out the SCC. It supports - * XON/XOFF flow control. - */ -static void outbyte( - char ch -) -{ - uint8_t rr_0; - char flow_control; - - for ( ; ; ) { - Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); - if ( (rr_0 & RR_0_TX_BUFFER_EMPTY) != 0 ) - break; - } - - for ( ; ; ) { - Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); - if ( (rr_0 & RR_0_RX_DATA_AVAILABLE) == 0 ) - break; - - Z8x30_READ_DATA( CONSOLE_DATA, flow_control ); - - if ( flow_control == XOFF ) - do { - do { - Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); - } while ( (rr_0 & RR_0_RX_DATA_AVAILABLE) == 0 ); - Z8x30_READ_DATA( CONSOLE_DATA, flow_control ); - } while ( flow_control != XON ); - } - - Z8x30_WRITE_DATA( CONSOLE_DATA, ch ); -} - -/* - * Open entry point - */ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * Close entry point - */ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * read bytes from the serial port. We only have stdin. - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args; - char *buffer; - int maximum; - int count = 0; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - for (count = 0; count < maximum; count++) { - buffer[ count ] = inbyte(); - if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { - buffer[ count++ ] = '\n'; - break; - } - } - - rw_args->bytes_moved = count; - return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; -} - -/* - * write bytes to the serial port. Stdout and stderr are the same. - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - int count; - int maximum; - rtems_libio_rw_args_t *rw_args; - char *buffer; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - for (count = 0; count < maximum; count++) { - if ( buffer[ count ] == '\n') { - outbyte('\r'); - } - outbyte( buffer[ count ] ); - } - - rw_args->bytes_moved = maximum; - return 0; -} - -/* - * IO Control entry point - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/lib/libbsp/m68k/mvme147s/Makefile.am b/c/src/lib/libbsp/m68k/mvme147s/Makefile.am index d6994289b8..f985e5454a 100644 --- a/c/src/lib/libbsp/m68k/mvme147s/Makefile.am +++ b/c/src/lib/libbsp/m68k/mvme147s/Makefile.am @@ -32,7 +32,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme147/clock/ckinit.c # console librtemsbsp_a_SOURCES += ../mvme147/console/console.c -librtemsbsp_a_SOURCES += ../../shared/dummy_printk_support.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/printk-dummy.c # timer librtemsbsp_a_SOURCES += ../mvme147/timer/timer.c librtemsbsp_a_SOURCES += ../mvme147/timer/timerisr.S diff --git a/c/src/lib/libbsp/m68k/mvme162/Makefile.am b/c/src/lib/libbsp/m68k/mvme162/Makefile.am index 8af4d1d415..72313a9473 100644 --- a/c/src/lib/libbsp/m68k/mvme162/Makefile.am +++ b/c/src/lib/libbsp/m68k/mvme162/Makefile.am @@ -31,7 +31,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/mvme162/clock/ckinit.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme162/console/console.c # timer librtemsbsp_a_SOURCES += timer/timer.c librtemsbsp_a_SOURCES += timer/timerisr.S diff --git a/c/src/lib/libbsp/m68k/mvme162/console/console.c b/c/src/lib/libbsp/m68k/mvme162/console/console.c deleted file mode 100644 index 985254d483..0000000000 --- a/c/src/lib/libbsp/m68k/mvme162/console/console.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * This file contains the MVME162 console IO package. - */ - -/* - * COPYRIGHT (c) 1989-2013. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - * Modifications of respective RTEMS file: COPYRIGHT (c) 1994. - * EISCAT Scientific Association. M.Savitski - * - * This material is a part of the MVME162 Board Support Package - * for the RTEMS executive. Its licensing policies are those of the - * RTEMS above. - */ - -#define M162_INIT - -#include -#include -#include -#include -#include - -Ring_buffer_t Console_Buffer[2]; - -/* - * Interrupt handler for receiver interrupts - */ -static rtems_isr C_Receive_ISR(rtems_vector_number vector) -{ - register int ipend, port; - - ZWRITE0(1, 0x38); /* reset highest IUS */ - - ipend = ZREAD(1, 3); /* read int pending from A side */ - - if (ipend == 0x04) port = 0; /* channel B intr pending */ - else if (ipend == 0x20) port = 1; /* channel A intr pending */ - else return; - - Ring_buffer_Add_character(&Console_Buffer[port], ZREADD(port)); - - if (ZREAD(port, 1) & 0x70) { /* check error stat */ - ZWRITE0(port, 0x30); /* reset error */ - } -} - -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - int i; - rtems_status_code status; - - /* - * Initialise receiver interrupts on both ports - */ - for (i = 0; i <= 1; i++) { - Ring_buffer_Initialize( &Console_Buffer[i] ); - ZWRITE(i, 2, SCC_VECTOR); - ZWRITE(i, 10, 0); - ZWRITE(i, 1, 0x10); /* int on all Rx chars or special condition */ - ZWRITE(i, 9, 8); /* master interrupt enable */ - } - - set_vector(C_Receive_ISR, SCC_VECTOR, 1); /* install ISR for ports A and B */ - - mcchip->vector_base = 0; - mcchip->gen_control = 2; /* MIEN */ - mcchip->SCC_int_ctl = 0x13; /* SCC IEN, IPL3 */ - - status = rtems_io_register_name( - "/dev/console", - major, - (rtems_device_minor_number) 1 - ); - - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - status = rtems_io_register_name( - "/dev/tty00", - major, - (rtems_device_minor_number) 0 - ); - - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - status = rtems_io_register_name( - "/dev/tty01", - major, - (rtems_device_minor_number) 1 - ); - - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - return RTEMS_SUCCESSFUL; -} - -/* - * Non-blocking char input - */ -bool char_ready(int port, char *ch) -{ - if ( Ring_buffer_Is_empty( &Console_Buffer[port] ) ) - return false; - - Ring_buffer_Remove_character( &Console_Buffer[port], *ch ); - - return true; -} - -/* - * Block on char input - */ -static char inbyte(int port) -{ - char tmp_char; - - while ( !char_ready(port, &tmp_char) ); - return tmp_char; -} - -/* - * This routine transmits a character out the SCC. It no longer supports - * XON/XOFF flow control. - */ -static void outbyte(char ch, int port) -{ - while (1) { - if (ZREAD0(port) & TX_BUFFER_EMPTY) break; - } - ZWRITED(port, ch); -} - -/* - * Open entry point - */ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * Close entry point - */ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * read bytes from the serial port. We only have stdin. - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args; - char *buffer; - int maximum; - int count = 0; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - if ( minor > 1 ) - return RTEMS_INVALID_NUMBER; - - for (count = 0; count < maximum; count++) { - buffer[ count ] = inbyte( minor ); - if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { - buffer[ count++ ] = '\n'; - break; - } - } - - rw_args->bytes_moved = count; - return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; -} - -/* - * write bytes to the serial port. Stdout and stderr are the same. - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - int count; - int maximum; - rtems_libio_rw_args_t *rw_args; - char *buffer; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - if ( minor > 1 ) - return RTEMS_INVALID_NUMBER; - - for (count = 0; count < maximum; count++) { - if ( buffer[ count ] == '\n') { - outbyte('\r', minor ); - } - outbyte( buffer[ count ], minor ); - } - - rw_args->bytes_moved = maximum; - return 0; -} - -/* - * IO Control entry point - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * _162Bug_output_char - * - * Output a single character using the 162Bug functions. The character - * will be written to the default output port. - */ -static void _162Bug_output_char( char c ) -{ - asm volatile( "moveb %0, -(%%sp)\n\t" /* char to output */ - "trap #15\n\t" /* Trap to 162Bug */ - ".short 0x20" /* Code for .OUTCHR */ - :: "d" (c) ); -} - -/* - * _BSP_output_char - * - * printk() function prototyped in bspIo.h. Does not use termios. - * - * If we have initialized the console device then use it, otherwise - * use the 162Bug routines to send it to the default output port. - */ -static void _BSP_output_char(char c) -{ - _162Bug_output_char(c); -} - -/* Printk function */ -BSP_output_char_function_type BSP_output_char = _BSP_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/m68k/mvme167/Makefile.am b/c/src/lib/libbsp/m68k/mvme167/Makefile.am index 1632a35b8b..ac80bf6014 100644 --- a/c/src/lib/libbsp/m68k/mvme167/Makefile.am +++ b/c/src/lib/libbsp/m68k/mvme167/Makefile.am @@ -29,7 +29,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/mvme167/clock/ckinit.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme167/console/console.c # timer librtemsbsp_a_SOURCES += timer/timer.c librtemsbsp_a_SOURCES += timer/timerisr.S diff --git a/c/src/lib/libbsp/m68k/mvme167/console/console-recording.h b/c/src/lib/libbsp/m68k/mvme167/console/console-recording.h deleted file mode 100644 index 4d8d3fc66c..0000000000 --- a/c/src/lib/libbsp/m68k/mvme167/console/console-recording.h +++ /dev/null @@ -1,572 +0,0 @@ -/* - * Copyright (c) 2000, National Research Council of Canada - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -/* CD2401 CONSOLE DRIVER DEBUG INFO RECORDING */ - -#ifdef CD2401_RECORD_DEBUG_INFO - -/* Control individual recording here. That way, we don't clutter console.c */ -#define CD2401_RECORD_WRITE -#define CD2401_RECORD_TX_ISR -#define CD2401_RECORD_RX_ISR -#define CD2401_RECORD_RE_ISR -#define CD2401_RECORD_MODEM_ISR -#define CD2401_RECORD_SET_ATTRIBUTE -#define CD2401_RECORD_FIRST_OPEN -#define CD2401_RECORD_LAST_CLOSE -#define CD2401_RECORD_START_REMOTE_TX -#define CD2401_RECORD_STOP_REMOTE_TX -#define CD2401_RECORD_DRAIN_OUTPUT -#define CD2401_RECORD_DELAY - -/* Call the data recording functions */ -#ifdef CD2401_RECORD_WRITE -#define CD2401_RECORD_WRITE_INFO( args ) cd2401_record_write_info args -#else -#define CD2401_RECORD_WRITE_INFO( args ) -#endif - -#ifdef CD2401_RECORD_TX_ISR -#define CD2401_RECORD_TX_ISR_INFO( args ) cd2401_record_tx_isr_info args -#define CD2401_RECORD_TX_ISR_SPURIOUS_INFO( args ) cd2401_record_tx_isr_spurious_info args -#define CD2401_RECORD_TX_ISR_BUSERR_INFO( args ) cd2401_record_tx_isr_buserr_info args -#else -#define CD2401_RECORD_TX_ISR_INFO( args ) -#define CD2401_RECORD_TX_ISR_SPURIOUS_INFO( args ) -#define CD2401_RECORD_TX_ISR_BUSERR_INFO( args ) -#endif - -#ifdef CD2401_RECORD_RX_ISR -#define CD2401_RECORD_RX_ISR_INFO( args ) cd2401_record_rx_isr_info args -#define CD2401_RECORD_RX_ISR_SPURIOUS_INFO( args ) cd2401_record_rx_isr_spurious_info args -#else -#define CD2401_RECORD_RX_ISR_INFO( args ) -#define CD2401_RECORD_RX_ISR_SPURIOUS_INFO( args ) -#endif - -#ifdef CD2401_RECORD_RE_ISR -#define CD2401_RECORD_RE_ISR_SPURIOUS_INFO( args ) cd2401_record_re_isr_spurious_info args -#else -#define CD2401_RECORD_RE_ISR_SPURIOUS_INFO( args ) -#endif - -#ifdef CD2401_RECORD_MODEM_ISR -#define CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO( args ) cd2401_record_modem_isr_spurious_info args -#else -#define CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO( args ) -#endif - -#ifdef CD2401_RECORD_SET_ATTRIBUTES -#define CD2401_RECORD_SET_ATTRIBUTES_INFO( args ) cd2401_record_set_attributes_info args -#else -#define CD2401_RECORD_SET_ATTRIBUTES_INFO( args ) -#endif - -#ifdef CD2401_RECORD_FIRST_OPEN -#define CD2401_RECORD_FIRST_OPEN_INFO( args ) cd2401_record_first_open_info args -#else -#define CD2401_RECORD_FIRST_OPEN_INFO( args ) -#endif - -#ifdef CD2401_RECORD_LAST_CLOSE -#define CD2401_RECORD_LAST_CLOSE_INFO( args ) cd2401_record_last_close_info args -#else -#define CD2401_RECORD_LAST_CLOSE_INFO( args ) -#endif - -#ifdef CD2401_RECORD_START_REMOTE_TX -#define CD2401_RECORD_START_REMOTE_TX_INFO( args ) cd2401_record_start_remote_tx_info args -#else -#define CD2401_RECORD_START_REMOTE_TX_INFO( args ) -#endif - -#ifdef CD2401_RECORD_STOP_REMOTE_TX -#define CD2401_RECORD_STOP_REMOTE_TX_INFO( args ) cd2401_record_stop_remote_tx_info args -#else -#define CD2401_RECORD_STOP_REMOTE_TX_INFO( args ) -#endif - -#ifdef CD2401_RECORD_DRAIN_OUTPUT -#define CD2401_RECORD_DRAIN_OUTPUT_INFO( args ) cd2401_record_drain_output_info args -#else -#define CD2401_RECORD_DRAIN_OUTPUT_INFO( args ) -#endif - -#ifdef CD2401_RECORD_DELAY -#define CD2401_RECORD_DELAY_INFO( args ) cd2401_record_delay_info args -#else -#define CD2401_RECORD_DELAY_INFO( args ) -#endif - -/* Define the data and the recording functions */ -#define CD2401_DEBUG_BUFFER_SIZE 256 -#define CD2401_DEBUG_CHAR_BUFSIZE 64 -#define CD2401_WRITE_INFO 1 -#define CD2401_TX_ISR_INFO 2 -#define CD2401_TX_ISR_SPURIOUS_INFO 3 -#define CD2401_TX_ISR_BUSERR_INFO 4 -#define CD2401_RX_ISR_INFO 5 -#define CD2401_RX_ISR_SPURIOUS_INFO 6 -#define CD2401_RE_ISR_SPURIOUS_INFO 7 -#define CD2401_MODEM_ISR_SPURIOUS_INFO 8 -#define CD2401_FIRST_OPEN_INFO 9 -#define CD2401_LAST_CLOSE_INFO 10 -#define CD2401_START_REMOTE_TX_INFO 11 -#define CD2401_STOP_REMOTE_TX_INFO 12 -#define CD2401_SET_ATTRIBUTE_INFO 13 -#define CD2401_DRAIN_OUTPUT_INFO 14 -#define CD2401_DELAY_INFO 15 - -struct cd2401_debug_info { - short discriminant; - short record_size; - union { - struct cd2401_write_info { - int length; - char buffer[CD2401_DEBUG_CHAR_BUFSIZE]; - char dmabuf; - } write_info; - struct cd2401_tx_isr_info { - unsigned char channel; - unsigned char status; - unsigned char initial_ier; - unsigned char final_ier; - uint8_t txEmpty; - } tx_isr_info; - struct cd2401_tx_isr_spurious_info { - unsigned char channel; - unsigned char status; - unsigned char initial_ier; - unsigned char final_ier; - unsigned long spurdev; - unsigned long spurcount; - } tx_isr_spurious_info; - struct cd2401_tx_isr_buserr_info { - unsigned char channel; - unsigned char status; - unsigned char initial_ier; - unsigned char buserr; - unsigned long type; - unsigned long addr; - } tx_isr_buserr_info; - struct cd2401_rx_isr_info { - unsigned char channel; - int length; - char buffer[CD2401_DEBUG_CHAR_BUFSIZE]; - } rx_isr_info; - struct cd2401_rx_isr_spurious_info { - unsigned char channel; - unsigned char status; - unsigned long spurdev; - unsigned long spurcount; - } rx_isr_spurious_info; - struct cd2401_re_isr_spurious_info { - unsigned char channel; - unsigned long spurdev; - unsigned long spurcount; - } re_isr_spurious_info; - struct cd2401_modem_isr_spurious_info { - unsigned char channel; - unsigned long spurdev; - unsigned long spurcount; - } modem_isr_spurious_info; - struct cd2401_first_open_info { - unsigned char channel; - uint8_t init_count; - } first_open_info; - struct cd2401_last_close_info { - unsigned char channel; - uint8_t init_count; - } last_close_info; - struct cd2401_start_remote_tx_info { - unsigned char channel; - } start_remote_tx_info; - struct cd2401_stop_remote_tx_info { - unsigned char channel; - } stop_remote_tx_info; - struct cd2401_set_attribute_info { - int minor; - uint8_t need_reinit; - uint8_t txEmpty; - uint8_t csize; - uint8_t cstopb; - uint8_t parodd; - uint8_t parenb; - uint8_t ignpar; - uint8_t inpck; - uint8_t hw_flow_ctl; - uint8_t sw_flow_ctl; - uint8_t extra_flow_ctl; - uint8_t icrnl; - uint8_t igncr; - uint8_t inlcr; - uint8_t brkint; - uint8_t ignbrk; - uint8_t parmrk; - uint8_t istrip; - uint16_t tx_period; - uint16_t rx_period; - uint32_t out_baud; - uint32_t in_baud; - } set_attribute_info; - struct cd2401_drain_output_info { - uint8_t txEmpty; - uint8_t own_buf_A; - uint8_t own_buf_B; - } drain_output_info; - struct cd2401_delay_info { - rtems_interval start; - rtems_interval end; - rtems_interval current; - unsigned long loop_count; - } delay_info; - } u; -}; - -struct cd2401_debug_info cd2401_debug_buffer[CD2401_DEBUG_BUFFER_SIZE]; -int cd2401_debug_index = 0; - -#include - -int cd2401_get_record_size( - int size -) -{ - /* Not the best way to do this */ - return size + 4; -} - -void cd2401_record_write_info( - int len, - const char * buf, - char dmabuf -) -{ - int max_length; - - max_length = (len < CD2401_DEBUG_CHAR_BUFSIZE ) ? len : CD2401_DEBUG_CHAR_BUFSIZE; - - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_WRITE_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_write_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.write_info.length = len; - memcpy ( &(cd2401_debug_buffer[cd2401_debug_index].u.write_info.buffer), buf, max_length ); - cd2401_debug_buffer[cd2401_debug_index].u.write_info.dmabuf = dmabuf; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_tx_isr_info( - unsigned char ch, - unsigned char status, - unsigned char initial_ier, - unsigned char final_ier, - uint8_t txEmpty -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_TX_ISR_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_tx_isr_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.channel = ch; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.status = status; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.initial_ier = initial_ier; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.final_ier = final_ier; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.txEmpty = txEmpty; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_tx_isr_spurious_info( - unsigned char ch, - unsigned char status, - unsigned char initial_ier, - unsigned char final_ier, - unsigned char spur_dev, - unsigned char spur_cnt -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_TX_ISR_SPURIOUS_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_tx_isr_spurious_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.channel = ch; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.status = status; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.initial_ier = initial_ier; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.final_ier = final_ier; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.spurdev = spur_dev; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.spurcount = spur_cnt; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_tx_isr_buserr_info( - unsigned char ch, - unsigned char status, - unsigned char initial_ier, - unsigned char buserr, - unsigned long buserr_type, - unsigned long buserr_addr -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_TX_ISR_BUSERR_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_tx_isr_buserr_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.channel = ch; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.status = status; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.initial_ier = initial_ier; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.buserr = buserr; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.type = buserr_type; - cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.addr = buserr_addr; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_rx_isr_info( - unsigned char ch, - unsigned char total, - char * buffer -) -{ - int max_length; - - max_length = (total < CD2401_DEBUG_CHAR_BUFSIZE ) ? total : CD2401_DEBUG_CHAR_BUFSIZE; - - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_RX_ISR_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_rx_isr_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_info.length = max_length; - memcpy ( &(cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_info.buffer), buffer, max_length ); - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_rx_isr_spurious_info( - unsigned char ch, - unsigned char status, - uint32_t spur_dev, - uint32_t spur_cnt -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_RX_ISR_SPURIOUS_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_rx_isr_spurious_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.channel = ch; - cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.status = status; - cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.spurdev = spur_dev; - cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.spurcount = spur_cnt; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_re_isr_spurious_info( - unsigned char ch, - uint32_t spur_dev, - uint32_t spur_cnt -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_RE_ISR_SPURIOUS_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_re_isr_spurious_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.re_isr_spurious_info.channel = ch; - cd2401_debug_buffer[cd2401_debug_index].u.re_isr_spurious_info.spurdev = spur_dev; - cd2401_debug_buffer[cd2401_debug_index].u.re_isr_spurious_info.spurcount = spur_cnt; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_modem_isr_spurious_info( - unsigned char ch, - uint32_t spur_dev, - uint32_t spur_cnt -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_MODEM_ISR_SPURIOUS_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_modem_isr_spurious_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.modem_isr_spurious_info.channel = ch; - cd2401_debug_buffer[cd2401_debug_index].u.modem_isr_spurious_info.spurdev = spur_dev; - cd2401_debug_buffer[cd2401_debug_index].u.modem_isr_spurious_info.spurcount = spur_cnt; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_first_open_info( - unsigned char ch, - uint8_t init_count -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_FIRST_OPEN_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_first_open_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.first_open_info.channel = ch; - cd2401_debug_buffer[cd2401_debug_index].u.first_open_info.init_count = init_count; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_last_close_info( - unsigned char ch, - uint8_t init_count -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_LAST_CLOSE_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_last_close_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.last_close_info.channel = ch; - cd2401_debug_buffer[cd2401_debug_index].u.last_close_info.init_count = init_count; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_start_remote_tx_info( - unsigned char ch -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_START_REMOTE_TX_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_start_remote_tx_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.start_remote_tx_info.channel = ch; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_stop_remote_tx_info( - unsigned char ch -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_STOP_REMOTE_TX_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_stop_remote_tx_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.stop_remote_tx_info.channel = ch; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_set_attributes_info( - int minor, - uint8_t need_reinit, - uint8_t csize, - uint8_t cstopb, - uint8_t parodd, - uint8_t parenb, - uint8_t ignpar, - uint8_t inpck, - uint8_t hw_flow_ctl, - uint8_t sw_flow_ctl, - uint8_t extra_flow_ctl, - uint8_t icrnl, - uint8_t igncr, - uint8_t inlcr, - uint8_t brkint, - uint8_t ignbrk, - uint8_t parmrk, - uint8_t istrip, - uint16_t tx_period, - uint16_t rx_period, - uint32_t out_baud, - uint32_t in_baud -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_SET_ATTRIBUTE_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_set_attribute_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.minor = minor; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.need_reinit = need_reinit; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.txEmpty = CD2401_Channel_Info[minor].txEmpty; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.csize = csize; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.cstopb = cstopb; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.parodd = parodd; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.parenb = parenb; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.ignpar = ignpar; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.inpck = inpck; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.hw_flow_ctl = hw_flow_ctl; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.sw_flow_ctl = sw_flow_ctl; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.extra_flow_ctl = extra_flow_ctl; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.icrnl = icrnl; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.igncr = igncr; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.inlcr = inlcr; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.brkint = brkint; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.ignbrk = ignbrk; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.parmrk = parmrk; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.istrip = istrip; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.tx_period = tx_period; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.rx_period = rx_period; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.out_baud = out_baud; - cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.in_baud = in_baud; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_drain_output_info( - uint8_t txEmpty, - uint8_t own_buf_A, - uint8_t own_buf_B -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_DRAIN_OUTPUT_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_drain_output_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.drain_output_info.txEmpty = txEmpty; - cd2401_debug_buffer[cd2401_debug_index].u.drain_output_info.own_buf_A = own_buf_A; - cd2401_debug_buffer[cd2401_debug_index].u.drain_output_info.own_buf_B = own_buf_B; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -void cd2401_record_delay_info( - rtems_interval start, - rtems_interval end, - rtems_interval current, - unsigned long loop_count -) -{ - memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) ); - cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_DELAY_INFO; - cd2401_debug_buffer[cd2401_debug_index].record_size = - cd2401_get_record_size( sizeof( struct cd2401_delay_info ) ); - cd2401_debug_buffer[cd2401_debug_index].u.delay_info.start = start; - cd2401_debug_buffer[cd2401_debug_index].u.delay_info.end = end; - cd2401_debug_buffer[cd2401_debug_index].u.delay_info.current = current; - cd2401_debug_buffer[cd2401_debug_index].u.delay_info.loop_count = loop_count; - - cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE; -} - -#else - -/* Do not call the data recording functions */ -#define CD2401_RECORD_WRITE_INFO( args ) -#define CD2401_RECORD_TX_ISR_INFO( args ) -#define CD2401_RECORD_TX_ISR_SPURIOUS_INFO( args ) -#define CD2401_RECORD_TX_ISR_BUSERR_INFO( args ) -#define CD2401_RECORD_RX_ISR_INFO( args ) -#define CD2401_RECORD_RX_ISR_SPURIOUS_INFO( args ) -#define CD2401_RECORD_RE_ISR_SPURIOUS_INFO( args ) -#define CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO( args ) -#define CD2401_RECORD_FIRST_OPEN_INFO( args ) -#define CD2401_RECORD_LAST_CLOSE_INFO( args ) -#define CD2401_RECORD_START_REMOTE_TX_INFO( args ) -#define CD2401_RECORD_STOP_REMOTE_TX_INFO( args ) -#define CD2401_RECORD_SET_ATTRIBUTES_INFO( args ) -#define CD2401_RECORD_DRAIN_OUTPUT_INFO( args ) -#define CD2401_RECORD_DELAY_INFO( args ) - -#endif diff --git a/c/src/lib/libbsp/m68k/mvme167/console/console.c b/c/src/lib/libbsp/m68k/mvme167/console/console.c deleted file mode 100644 index 0499ac46b3..0000000000 --- a/c/src/lib/libbsp/m68k/mvme167/console/console.c +++ /dev/null @@ -1,1676 +0,0 @@ -/* - * This file contains the MVME167 termios console package. Only asynchronous - * I/O is supported. - * - * /dev/tty0 is channel 0, Serial Port 1/Console on the MVME712M. - * /dev/tty1 is channel 1, Serial Port 2/TTY01 on the MVME712M. - * /dev/tty2 is channel 2, Serial Port 3 on the MVME712M. - * /dev/tty3 is channel 3, Serial Port 4 on the MVME712M. - * - * Normal I/O uses DMA for output, interrupts for input. /dev/console is - * fixed to be /dev/tty01, Serial Port 2. Very limited support is provided - * for polled I/O. Polled I/O is intended only for running the RTEMS test - * suites. In all cases, Serial Port 1/Console is allocated to 167Bug and - * is the dedicated debugger port. We configure GDB to use 167Bug for - * debugging. When debugging with GDB or 167Bug, do not open /dev/tty00. - * - * Modern I/O chips often contain a number of I/O devices that can operate - * almost independently of each other. Typically, in RTEMS, all devices in - * an I/O chip are handled by a single device driver, but that need not be - * always the case. Each device driver must supply six entry points in the - * Device Driver Table: a device initialization function, as well as an open, - * close, read, write and a control function. RTEMS assigns a device major - * number to each device driver. This major device number is the index of the - * device driver entries in the Device Driver Table, and it used to identify - * a particular device driver. To distinguish multiple I/O sub-devices within - * an I/O chip, RTEMS supports device minor numbers. When a I/O device is - * initialized, the major number is supplied to the initialization function. - * That function must register each sub-device with a separate name and minor - * number (as well as the supplied major number). When an application opens a - * device by name, the corresponding major and minor numbers are returned to - * the caller to be used in subsequent I/O operations (although these details - * are typically hidden within the library functions). - * - * Such a scheme recognizes that the initialization of the individual - * sub-devices is generally not completely independent. For example, the - * four serial ports of the CD2401 can be configured almost independently - * from each other. One port could be configured to operate in asynchronous - * mode with interrupt-driven I/O, while another port could be configured to - * operate in HDLC mode with DMA I/O. However, a device reset command will - * reset all four channels, and the width of DMA transfers and the number of - * retries following bus errors selected applies to all four channels. - * Consequently, when initializing one channel, one must be careful not to - * destroy the configuration of other channels that are already configured. - * - * One problem with the RTEMS I/O initialization model is that no information - * other than a device major number is passed to the initialization function. - * Consequently, the sub-devices must be initialized with some pre-determined - * configuration. To change the configuration of a sub-device, it is - * necessary to either rewrite the initialization function, or to make a - * series of rtems_io_control() calls after initialization. The first - * approach is not very elegant. The second approach is acceptable if an - * application is simply changing baud rates, parity or other such - * asynchronous parameters (as supplied by the termios package). But what if - * an application requires one channel to run in HDLC or Bisync mode and - * another in async mode? With a single driver per I/O chip approach, the - * device driver must support multiple protocols. This is feasible, but it - * often means that an application that only does asynchronous I/O now links - * in code for other unused protocols, thus wasting precious ROM space. - * Worse, it requires that the sub-devices be initialized in some - * configuration, and that configuration then changed through a series of - * device driver control calls. There is no standard API in RTEMS to switch - * a serial line to some synchronous protocol. - * - * A better approach is to treat each channel as a separate device, each with - * its own device device driver. The application then supplies its own device - * driver table with only the required protocols (drivers) on each line. The - * problem with this approach is that the device drivers are not really - * independent, given that the I/O sub-devices within a common chip are not - * independent themselves. Consequently, the related device drivers must - * share some information. In RTEMS, there is no standard location in which - * to share information. - * - * This driver handles all four channels, i.e. it distinguishes the - * sub-devices using minor device numbers. Only asynchronous I/O is - * supported. The console is currently fixed to be channel 1 on the CD2401, - * which corresponds to the TTY01 port (Serial Port 2) on the MVME712M - * Transition Module. - * - * The CD2401 does either interrupt-driven or DMA I/O; it does not support - * polling. In interrupt-driven or DMA I/O modes, interrupts from the CD2401 - * are routed to the MC68040, and the processor generates an interrupt - * acknowledge cycle directly to the CD2401 to obtain an interrupt vector. - * The PCCchip2 supports a pseudo-polling mode in which interrupts from the - * CD2401 are not routed to the MC68040, but can be detected by the processor - * by reading the appropriate CD2401 registers. In this mode, interrupt - * acknowledge cycles must be generated to the CD2401 by reading the - * appropriate PCCchip2 registers. - * - * Interrupts from the four channels cannot be routed independently; either - * all channels are used in the pseudo-polling mode, or all channels are used - * in interrupt-driven/DMA mode. There is no advantage in using the speudo- - * polling mode. Consenquently, this driver performs DMA input and output. - * Output is performed directly from the termios raw output buffer, while - * input is accumulated into a separate buffer. - * - * THIS MODULE IS NOT RE-ENTRANT! Simultaneous access to a device from - * multiple tasks is likely to cause significant problems! Concurrency - * control is implemented in the termios package. - * - * THE INTERRUPT LEVEL IS SET TO 1 FOR ALL CHANNELS. - * If the CD2401 is to be used for high speed synchronous serial I/O, the - * interrupt priority might need to be increased. - * - * ALL INTERRUPT HANDLERS ARE SHARED. - * When adding extra device drivers, either rewrite the interrupt handlers - * to demultiplex the interrupts, or install separate vectors. Common vectors - * are currently used to catch spurious interrupts. We could already have - * installed separate vectors for each channel and used the spurious - * interrupt handler defined in some other BSPs, but handling spurious - * interrupts from the CD2401 in this device driver allows us to record more - * information on the source of the interrupts. Furthermore, we have observed - * the occasional spurious interrupt from channel 0. We definitely do not - * to call a debugger for those. - * - * All page references are to the MVME166/MVME167/MVME187 Single Board - * Computer Programmer's Reference Guide (MVME187PG/D2) with the April - * 1993 supplements/addenda (MVME187PG/D2A1). - */ - -/* - * Copyright (c) 1998, National Research Council of Canada - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#define M167_INIT - -#include -#include -#include - -#include -#include -#include -#include /* Must be before libio.h */ - -/* Utility functions */ -void cd2401_udelay( unsigned long delay ); -void cd2401_chan_cmd( uint8_t channel, uint8_t cmd, uint8_t wait ); -uint16_t cd2401_bitrate_divisor( uint32_t clkrate, uint32_t * bitrate ); -void cd2401_initialize( void ); -void cd2401_interrupts_initialize( bool enable ); - -/* ISRs */ -rtems_isr cd2401_modem_isr( rtems_vector_number vector ); -rtems_isr cd2401_re_isr( rtems_vector_number vector ); -rtems_isr cd2401_rx_isr( rtems_vector_number vector ); -rtems_isr cd2401_tx_isr( rtems_vector_number vector ); - -/* Termios callbacks */ -int cd2401_firstOpen( int major, int minor, void *arg ); -int cd2401_lastClose( int major, int minor, void *arg ); -int cd2401_setAttributes( int minor, const struct termios *t ); -int cd2401_startRemoteTx( int minor ); -int cd2401_stopRemoteTx( int minor ); -ssize_t cd2401_write( int minor, const char *buf, size_t len ); -int cd2401_drainOutput( int minor ); -int _167Bug_pollRead( int minor ); -ssize_t _167Bug_pollWrite( int minor, const char *buf, size_t len ); - -/* Printk function */ -static void _BSP_output_char( char c ); -BSP_output_char_function_type BSP_output_char = _BSP_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - -/* '\r' character in memory. This used to live on - * the stack but storing the '\r' character is - * optimized away by gcc-4.3.2 (since it seems to - * be unused [only referenced from inline assembly - * code in _167Bug_pollWrite()]). - * Hence we make it a global constant. - */ -static const char cr_char = '\r'; - -/* Channel info */ -/* static */ volatile struct { - void *tty; /* Really a struct rtems_termios_tty * */ - int len; /* Record nb of chars being TX'ed */ - const char *buf; /* Record where DMA is coming from */ - uint32_t spur_cnt; /* Nb of spurious ints so far */ - uint32_t spur_dev; /* Indo on last spurious int */ - uint32_t buserr_addr; /* Faulting address */ - uint32_t buserr_type; /* Reason of bus error during DMA */ - uint8_t own_buf_A; /* If true, buffer A belongs to the driver */ - uint8_t own_buf_B; /* If true, buffer B belongs to the driver */ - uint8_t txEmpty; /* If true, the output FIFO should be empty */ -} CD2401_Channel_Info[4]; - -/* - * The number of channels already opened. If zero, enable the interrupts. The - * initial value must be 0. If initialized explicitly, the variable ends up - * in the .data section. Its value is not re-initialized on system restart. - * Furthermore, because the variable is changed, the .data section would not - * be ROMable. We thus leave the variable uninitialized, which causes it to - * be allocated in the .bss section, and rely on RTEMS to zero the .bss - * section on every startup. - */ -uint8_t Init_count; - -/* Record previous handlers */ -rtems_isr_entry Prev_re_isr; /* Previous rx exception isr */ -rtems_isr_entry Prev_rx_isr; /* Previous rx isr */ -rtems_isr_entry Prev_tx_isr; /* Previous tx isr */ -rtems_isr_entry Prev_modem_isr; /* Previous modem/timer isr */ - -/* Define the following symbol to trace the calls to this driver */ -/* #define CD2401_RECORD_DEBUG_INFO */ -#include "console-recording.h" - -/* - * Utility functions. - */ - -/* - * Assumes that clock ticks 1 million times per second. - * - * MAXIMUM DELAY IS ABOUT 20 ms - * - * Input parameters: - * delay: Number of microseconds to delay. - * - * Output parameters: NONE - * - * Return values: NONE - */ - void cd2401_udelay -( - unsigned long delay -) -{ - unsigned long i = 20000; /* In case clock is off */ - rtems_interval start_ticks, end_ticks, current_ticks; - - start_ticks = rtems_clock_get_ticks_since_boot(); - end_ticks = start_ticks + delay; - - do { - current_ticks = rtems_clock_get_ticks_since_boot(); - } while ( --i && (current_ticks <= end_ticks) ); - - CD2401_RECORD_DELAY_INFO(( start_ticks, end_ticks, current_ticks, i )); -} - -/* - * cd2401_chan_cmd - * - * Sends a CCR command to the specified channel. Waits for any unfinished - * previous command to complete, then sends the specified command. Optionally - * wait for the current command to finish before returning. - * - * Input parameters: - * channel - CD2401 channel number - * cmd - command byte - * wait - if non-zero, wait for specified command to complete before - * returning. - * - * Output parameters: NONE - * - * Return values: NONE - */ -void cd2401_chan_cmd( - uint8_t channel, - uint8_t cmd, - uint8_t wait -) -{ - if ( channel < 4 ) { - cd2401->car = channel; /* Select channel */ - - while ( cd2401->ccr != 0 ); /* Wait for completion of previous command */ - cd2401->ccr = cmd; /* Send command */ - if ( wait ) - while( cd2401->ccr != 0 );/* Wait for completion */ - } - else { - /* This may not be the best error message */ - rtems_fatal_error_occurred( RTEMS_INVALID_NUMBER ); - } -} - -/* - * cd2401_bitrate_divisor - * - * Compute the divisor and clock source to use to obtain the desired bitrate. - * - * Input parameters: - * clkrate - system clock rate (CLK input frequency) - * bitrate - the desired bitrate - * - * Output parameters: - * bitrate - The actual bitrate achievable, to the nearest bps. - * - * Return values: - * Returns divisor in lower byte and clock source in upper byte for the - * specified bitrate. - */ -uint16_t cd2401_bitrate_divisor( - uint32_t clkrate, - uint32_t * bitrate -) -{ - uint32_t divisor; - uint16_t clksource; - - divisor = *bitrate << 3; /* temporary; multiply by 8 for CLK/8 */ - divisor = (clkrate + (divisor>>1)) / divisor; /* divisor for clk0 (CLK/8) */ - - /* Use highest speed clock source for best precision - try clk0 to clk4 */ - for( clksource = 0; clksource < 0x0400 && divisor > 0x100; clksource += 0x0100 ) - divisor >>= 2; - divisor--; /* adjustment, see specs */ - if( divisor < 1 ) - divisor = 1; - else if( divisor > 0xFF ) - divisor = 0xFF; - *bitrate = clkrate / (1 << ((clksource >> 7)+3)) / (divisor+1); - return( clksource | divisor ); -} - -/* - * cd2401_initialize - * - * Initializes the CD2401 device. Individual channels on the chip are left in - * their default reset state, and should be subsequently configured. - * - * Input parameters: NONE - * - * Output parameters: NONE - * - * Return values: NONE - */ -void cd2401_initialize( void ) -{ - int i; - - for ( i = 3; i >= 0; i-- ) { - CD2401_Channel_Info[i].tty = NULL; - CD2401_Channel_Info[i].len = 0; - CD2401_Channel_Info[i].buf = NULL; - CD2401_Channel_Info[i].spur_cnt = 0; - CD2401_Channel_Info[i].spur_dev = 0; - CD2401_Channel_Info[i].buserr_type = 0; - CD2401_Channel_Info[i].buserr_addr = 0; - CD2401_Channel_Info[i].own_buf_A = TRUE; - CD2401_Channel_Info[i].own_buf_B = TRUE; - CD2401_Channel_Info[i].txEmpty = TRUE; - } - - /* - * Normally, do a device reset here. If we do it, we will most likely clober - * the port settings for 167Bug on channel 0. So we just shut up all the - * ports by disabling their interrupts. - */ -#if 0 - cd2401->gfrcr = 0; /* So we can detect that device init is done */ - cd2401_chan_cmd( 0x10, 0); /* Reset all */ - while(cd2401->gfrcr == 0); /* Wait for reset all */ -#endif - - /* - * The CL-CD2400/2401 manual (part no 542400-003) states on page 87 that - * the LICR "contains the number of the interrupting channel being served. - * The channel number is always that of the current acknowledged interrupt." - * THE USER MUST PROGRAM CHANNEL NUMBER IN LICR! It is not set automatically - * by the hardware, as suggested by the manual. - * - * The updated manual (part no 542400-007) has the story straight. The - * CD2401 automatically initializes the LICR to contain the channel number - * in bits 2 and 3. However, these bits are not preserved when the user - * defined bits are written. - * - * The same vector number is used for all four channels. Different vector - * numbers could be programmed for each channel, thus avoiding the need to - * demultiplex the interrupts in the ISR. - */ - for ( i = 0; i < 4; i++ ) { - cd2401->car = i; /* Select channel */ - cd2401->livr = 0x5C; /* Motorola suggested value p. 3-15 */ - cd2401->licr = i << 2; /* Don't rely on reset value */ - cd2401->ier = 0; /* Disable all interrupts */ - } - - /* - * The content of the CD2401 xpilr registers must match the A7-A0 addresses - * generated by the PCCchip2 during interrupt acknowledge cycles in order - * for the CD2401 to recognize the IACK cycle and clear its interrupt - * request. - */ - cd2401->mpilr = 0x01; /* Match pccchip2->modem_piack p. 3-27 */ - cd2401->tpilr = 0x02; /* Match pccchip2->tx_piack p. 3-28 */ - cd2401->rpilr = 0x03; /* Match pccchip2->rx_piack p. 3-29 */ - - /* Global CD2401 registers */ - cd2401->dmr = 0; /* 16-bit DMA transfers when possible */ - cd2401->bercnt = 0; /* Do not retry DMA upon bus errors */ - - /* - * Setup timer prescaler period, which clocks timers 1 and 2 (or rx timeout - * and tx delay). The prescaler is clocked by the system clock) / 2048. The - * register must be in the range 0x0A..0xFF, ie. a rescaler period range of - * about 1ms..26ms for a nominal system clock rate of 20MHz. - */ - cd2401->tpr = 0x0A; /* Same value as 167Bug */ -} - -/* - * cd2401_interrupts_initialize - * - * This routine enables or disables the CD2401 interrupts to the MC68040. - * Interrupts cannot be enabled/disabled on a per-channel basis. - * - * Input parameters: - * enable - if true, enable the interrupts, else disable them. - * - * Output parameters: NONE - * - * Return values: NONE - * - * THE FIRST CD2401 CHANNEL OPENED SHOULD ENABLE INTERRUPTS. - * THE LAST CD2401 CHANNEL CLOSED SHOULD DISABLE INTERRUPTS. - */ -void cd2401_interrupts_initialize( - bool enable -) -{ - if ( enable ) { - /* - * Enable interrupts from the CD2401 in the PCCchip2. - * During DMA transfers, the MC68040 supplies dirty data during read cycles - * from the CD2401 and leaves the data dirty in its data cache if there is - * a cache hit. The MC68040 updates the data cache during write cycles from - * the CD2401 if there is a cache hit. - */ - pccchip2->SCC_error = 0x01; - pccchip2->SCC_modem_int_ctl = 0x10 | CD2401_INT_LEVEL; - pccchip2->SCC_tx_int_ctl = 0x10 | CD2401_INT_LEVEL; - pccchip2->SCC_rx_int_ctl = 0x50 | CD2401_INT_LEVEL; - - pccchip2->gen_control |= 0x02; /* Enable pccchip2 interrupts */ - } - else { - /* Disable interrupts */ - pccchip2->SCC_modem_int_ctl &= 0xEF; - pccchip2->SCC_tx_int_ctl &= 0xEF; - pccchip2->SCC_rx_int_ctl &= 0xEF; - } -} - -/* ISRs */ - -/* - * cd2401_modem_isr - * - * Modem/timer interrupt (group 1) from CD2401. These are not used, and not - * expected. Record as spurious and clear. - * - * Input parameters: - * vector - vector number - * - * Output parameters: NONE - * - * Return values: NONE - */ -rtems_isr cd2401_modem_isr( - rtems_vector_number vector -) -{ - uint8_t ch; - - /* Get interrupting channel ID */ - ch = cd2401->licr >> 2; - - /* Record interrupt info for debugging */ - CD2401_Channel_Info[ch].spur_dev = - (vector << 24) | (cd2401->stk << 16) | (cd2401->mir << 8) | cd2401->misr; - CD2401_Channel_Info[ch].spur_cnt++; - - cd2401->meoir = 0; /* EOI */ - CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO(( ch, - CD2401_Channel_Info[ch].spur_dev, - CD2401_Channel_Info[ch].spur_cnt )); -} - -/* - * cd2401_re_isr - * - * RX exception interrupt (group 3, receiver exception) from CD2401. These are - * not used, and not expected. Record as spurious and clear. - * - * FIX THIS ISR TO DETECT BREAK CONDITIONS AND RAISE SIGINT - * - * Input parameters: - * vector - vector number - * - * Output parameters: NONE - * - * Return values: NONE - */ -rtems_isr cd2401_re_isr( - rtems_vector_number vector -) -{ - uint8_t ch; - - /* Get interrupting channel ID */ - ch = cd2401->licr >> 2; - - /* Record interrupt info for debugging */ - CD2401_Channel_Info[ch].spur_dev = - (vector << 24) | (cd2401->stk << 16) | (cd2401->rir << 8) | cd2401->u5.b.risrl; - CD2401_Channel_Info[ch].spur_cnt++; - - if ( cd2401->u5.b.risrl & 0x80 ) /* Timeout interrupt? */ - cd2401->ier &= 0xDF; /* Disable rx timeout interrupt */ - cd2401->reoir = 0x08; /* EOI; exception char not read */ - CD2401_RECORD_RE_ISR_SPURIOUS_INFO(( ch, - CD2401_Channel_Info[ch].spur_dev, - CD2401_Channel_Info[ch].spur_cnt )); -} - -/* - * cd2401_rx_isr - * - * RX interrupt (group 3, receiver data) from CD2401. - * - * Input parameters: - * vector - vector number - * - * Output parameters: NONE - * - * Return values: NONE - */ -rtems_isr cd2401_rx_isr( - rtems_vector_number vector -) -{ - char c; - uint8_t ch, status, nchars, total; - #ifdef CD2401_RECORD_DEBUG_INFO - uint8_t i = 0; - char buffer[256]; - #endif - - (void) total; /* avoid set but not used warnings when not recording info */ - - status = cd2401->u5.b.risrl; - ch = cd2401->licr >> 2; - - /* Has this channel been initialized or is it a condition we ignore? */ - if ( CD2401_Channel_Info[ch].tty && !status ) { - /* Normal Rx Int, read chars, enqueue them, and issue EOI */ - total = nchars = cd2401->rfoc; /* Nb of chars to retrieve from rx FIFO */ - while ( nchars-- > 0 ) { - c = (char)cd2401->dr; /* Next char in rx FIFO */ - rtems_termios_enqueue_raw_characters( CD2401_Channel_Info[ch].tty ,&c, 1 ); - #ifdef CD2401_RECORD_DEBUG_INFO - buffer[i++] = c; - #endif - } - cd2401->reoir = 0; /* EOI */ - CD2401_RECORD_RX_ISR_INFO(( ch, total, buffer )); - } else { - /* No, record as spurious interrupt */ - CD2401_Channel_Info[ch].spur_dev = - (vector << 24) | (cd2401->stk << 16) | (cd2401->rir << 8) | cd2401->u5.b.risrl; - CD2401_Channel_Info[ch].spur_cnt++; - cd2401->reoir = 0x04; /* EOI - character not read */ - CD2401_RECORD_RX_ISR_SPURIOUS_INFO(( ch, status, - CD2401_Channel_Info[ch].spur_dev, - CD2401_Channel_Info[ch].spur_cnt )); - } -} - -/* - * cd2401_tx_isr - * - * TX interrupt (group 2) from CD2401. - * - * Input parameters: - * vector - vector number - * - * Output parameters: NONE - * - * Return values: NONE - */ -rtems_isr cd2401_tx_isr( - rtems_vector_number vector -) -{ - uint8_t ch, status, buserr, initial_ier, final_ier; - - status = cd2401->tisr; - ch = cd2401->licr >> 2; - initial_ier = cd2401->ier; - - #ifndef CD2401_RECORD_DEBUG_INFO - /* - * When the debug is disabled, these variables are really not read. - * But when debug is enabled, they are. - */ - (void) initial_ier; /* avoid set but not used warning */ - (void) final_ier; /* avoid set but not used warning */ - #endif - - /* Has this channel been initialized? */ - if ( !CD2401_Channel_Info[ch].tty ) { - /* No, record as spurious interrupt */ - CD2401_Channel_Info[ch].spur_dev = - (vector << 24) | (cd2401->stk << 16) | (cd2401->tir << 8) | cd2401->tisr; - CD2401_Channel_Info[ch].spur_cnt++; - final_ier = cd2401->ier &= 0xFC;/* Shut up, whoever you are */ - - cd2401->teoir = 0x88; /* EOI - Terminate buffer and no transfer */ - CD2401_RECORD_TX_ISR_SPURIOUS_INFO(( ch, status, initial_ier, final_ier, - CD2401_Channel_Info[ch].spur_dev, - CD2401_Channel_Info[ch].spur_cnt )); - return; - } - - if ( status & 0x80 ) { - /* - * Bus error occurred during DMA transfer. For now, just record. - * Get reason for DMA bus error and clear the report for the next - * occurrence - */ - buserr = pccchip2->SCC_error; - pccchip2->SCC_error = 0x01; - CD2401_Channel_Info[ch].buserr_type = - (vector << 24) | (buserr << 16) | (cd2401->tir << 8) | cd2401->tisr; - CD2401_Channel_Info[ch].buserr_addr = - (((uint32_t)cd2401->tcbadru) << 16) | cd2401->tcbadrl; - - cd2401->teoir = 0x80; /* EOI - terminate bad buffer */ - CD2401_RECORD_TX_ISR_BUSERR_INFO(( ch, status, initial_ier, buserr, - CD2401_Channel_Info[ch].buserr_type, - CD2401_Channel_Info[ch].buserr_addr )); - return; - } - - if ( status & 0x20 ) { - /* DMA done -- Turn off TxD int, turn on TxMpty */ - final_ier = cd2401->ier = (cd2401->ier & 0xFE) | 0x02; - if( status & 0x08 ) { - /* Transmit buffer B was released */ - CD2401_Channel_Info[ch].own_buf_B = TRUE; - } - else { - /* Transmit buffer A was released */ - CD2401_Channel_Info[ch].own_buf_A = TRUE; - } - CD2401_RECORD_TX_ISR_INFO(( ch, status, initial_ier, final_ier, - CD2401_Channel_Info[ch].txEmpty )); - - /* This call can result in a call to cd2401_write() */ - rtems_termios_dequeue_characters ( - CD2401_Channel_Info[ch].tty, - CD2401_Channel_Info[ch].len ); - cd2401->teoir = 0x08; /* EOI - no data transfered */ - } - else if ( status & 0x02 ) { - /* TxEmpty */ - CD2401_Channel_Info[ch].txEmpty = TRUE; - final_ier = cd2401->ier &= 0xFD;/* Shut up the interrupts */ - cd2401->teoir = 0x08; /* EOI - no data transfered */ - CD2401_RECORD_TX_ISR_INFO(( ch, status, initial_ier, final_ier, - CD2401_Channel_Info[ch].txEmpty )); - } - else { - /* Why did we get a Tx interrupt? */ - CD2401_Channel_Info[ch].spur_dev = - (vector << 24) | (cd2401->stk << 16) | (cd2401->tir << 8) | cd2401->tisr; - CD2401_Channel_Info[ch].spur_cnt++; - cd2401->teoir = 0x08; /* EOI - no data transfered */ - CD2401_RECORD_TX_ISR_SPURIOUS_INFO(( ch, status, initial_ier, 0xFF, - CD2401_Channel_Info[ch].spur_dev, - CD2401_Channel_Info[ch].spur_cnt )); - } -} - -/* - * termios callbacks - */ - -/* - * cd2401_firstOpen - * - * This is the first time that this minor device (channel) is opened. - * Complete the asynchronous initialization. - * - * Input parameters: - * major - device major number - * minor - channel number - * arg - pointer to a struct rtems_libio_open_close_args_t - * - * Output parameters: NONE - * - * Return value: IGNORED - */ -int cd2401_firstOpen( - int major, - int minor, - void *arg -) -{ - rtems_libio_open_close_args_t *args = arg; - rtems_libio_ioctl_args_t newarg; - struct termios termios; - rtems_status_code sc; - rtems_interrupt_level level; - - rtems_interrupt_disable (level); - - /* - * Set up the line with the specified parameters. The difficulty is that - * the line parameters are stored in the struct termios field of a - * struct rtems_termios_tty that is not defined in a public header file. - * Therefore, we do not have direct access to the termios passed in with - * arg. So we make a rtems_termios_ioctl() call to get a pointer to the - * termios structure. - * - * THIS KLUDGE MAY BREAK IN THE FUTURE! - * - * We could have made a tcgetattr() call if we had our fd. - */ - newarg.iop = args->iop; - newarg.command = TIOCGETA; - newarg.buffer = &termios; - sc = rtems_termios_ioctl (&newarg); - if (sc != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (sc); - - /* - * Turn off hardware flow control. It is a pain with 3-wire cables. - * The rtems_termios_ioctl() call below results in a call to - * cd2401_setAttributes to initialize the line. The caller will "wait" - * on the ttyMutex that it already owns; this is safe in RTEMS. - */ - termios.c_cflag |= CLOCAL; /* Ignore modem status lines */ - newarg.command = TIOCGETA; - sc = rtems_termios_ioctl (&newarg); - if (sc != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (sc); - - /* Mark that the channel as initialized */ - CD2401_Channel_Info[minor].tty = args->iop->data1; - - /* If the first of the four channels to open, set up the interrupts */ - if ( !Init_count++ ) { - /* Install the interrupt handlers */ - Prev_re_isr = (rtems_isr_entry) set_vector( cd2401_re_isr, 0x5C, 1 ); - Prev_modem_isr = (rtems_isr_entry) set_vector( cd2401_modem_isr, 0x5D, 1 ); - Prev_tx_isr = (rtems_isr_entry) set_vector( cd2401_tx_isr, 0x5E, 1 ); - Prev_rx_isr = (rtems_isr_entry) set_vector( cd2401_rx_isr, 0x5F, 1 ); - - cd2401_interrupts_initialize( TRUE ); - } - - CD2401_RECORD_FIRST_OPEN_INFO(( minor, Init_count )); - - rtems_interrupt_enable (level); - - /* Return something */ - return RTEMS_SUCCESSFUL; -} - -/* - * cd2401_lastClose - * - * There are no more opened file descriptors to this device. Close it down. - * - * Input parameters: - * major - device major number - * minor - channel number - * arg - pointer to a struct rtems_libio_open_close_args_t - */ -int cd2401_lastClose( - int major, - int minor, - void *arg -) -{ - rtems_interrupt_level level; - - rtems_interrupt_disable (level); - - /* Mark that the channel is no longer is use */ - CD2401_Channel_Info[minor].tty = NULL; - - /* If the last of the four channels to close, disable the interrupts */ - if ( !--Init_count ) { - cd2401_interrupts_initialize( FALSE ); - - /* De-install the interrupt handlers */ - set_vector( Prev_re_isr, 0x5C, 1 ); - set_vector( Prev_modem_isr, 0x5D, 1 ); - set_vector( Prev_tx_isr, 0x5E, 1 ); - set_vector( Prev_rx_isr, 0x5F, 1 ); - } - - CD2401_RECORD_LAST_CLOSE_INFO(( minor, Init_count )); - - rtems_interrupt_enable (level); - - /* return something */ - return RTEMS_SUCCESSFUL; -} - -/* - * cd2401_setAttributes - * - * Set up the selected channel of the CD2401 chip for doing asynchronous - * I/O with DMA. - * - * The chip must already have been initialized by cd2401_initialize(). - * - * This code was written for clarity. The code space it occupies could be - * reduced. The code could also be compiled with aggressive optimization - * turned on. - * - * Input parameters: - * minor - the selected channel - * t - the termios parameters - * - * Output parameters: NONE - * - * Return value: IGNORED - */ -int cd2401_setAttributes( - int minor, - const struct termios *t -) -{ - uint8_t csize, cstopb, parodd, parenb, ignpar, inpck; - uint8_t hw_flow_ctl, sw_flow_ctl, extra_flow_ctl; - uint8_t icrnl, igncr, inlcr, brkint, ignbrk, parmrk, istrip; - uint8_t need_reinitialization = FALSE; - uint8_t read_enabled; - uint16_t tx_period, rx_period; - uint32_t out_baud, in_baud; - rtems_interrupt_level level; - - /* Determine what the line parameters should be */ - - /* baud rates */ - out_baud = rtems_termios_baud_to_number(t->c_ospeed); - in_baud = rtems_termios_baud_to_number(t->c_ispeed); - - /* Number of bits per char */ - csize = 0x07; /* to avoid a warning */ - switch ( t->c_cflag & CSIZE ) { - case CS5: csize = 0x04; break; - case CS6: csize = 0x05; break; - case CS7: csize = 0x06; break; - case CS8: csize = 0x07; break; - } - - /* Parity */ - if ( t->c_cflag & PARODD ) - parodd = 0x80; /* Odd parity */ - else - parodd = 0; - - if ( t->c_cflag & PARENB ) - parenb = 0x40; /* Parity enabled on Tx and Rx */ - else - parenb = 0x00; /* No parity on Tx and Rx */ - - /* CD2401 IGNPAR and INPCK bits are inverted wrt POSIX standard? */ - if ( t->c_iflag & INPCK ) - ignpar = 0; /* Check parity on input */ - else - ignpar = 0x10; /* Do not check parity on input */ - if ( t->c_iflag & IGNPAR ) { - inpck = 0x03; /* Discard error character */ - parmrk = 0; - } else { - if ( t->c_iflag & PARMRK ) { - inpck = 0x01; /* Translate to 0xFF 0x00 */ - parmrk = 0x04; - } else { - inpck = 0x01; /* Translate to 0x00 */ - parmrk = 0; - } - } - - /* Stop bits */ - if ( t->c_cflag & CSTOPB ) - cstopb = 0x04; /* Two stop bits */ - else - cstopb = 0x02; /* One stop bit */ - - /* Modem flow control */ - if ( t->c_cflag & CLOCAL ) - hw_flow_ctl = 0x04; /* Always assert RTS before Tx */ - else - hw_flow_ctl = 0x07; /* Always assert RTS before Tx, - wait for CTS and DSR */ - - /* XON/XOFF Tx flow control */ - if ( t->c_iflag & IXON ) { - sw_flow_ctl = 0x40; /* Tx in-band flow ctl enabled, wait for XON */ - extra_flow_ctl = 0x30; /* Eat XON/XOFF, XON/XOFF in SCHR1, SCHR2 */ - } - else { - sw_flow_ctl = 0; /* Tx in-band flow ctl disabled */ - extra_flow_ctl = 0; /* Pass on XON/XOFF */ - } - - /* CL/LF translation */ - if ( t->c_iflag & ICRNL ) - icrnl = 0x40; /* Map CR to NL on input */ - else - icrnl = 0; /* Pass on CR */ - if ( t->c_iflag & INLCR ) - inlcr = 0x20; /* Map NL to CR on input */ - else - inlcr = 0; /* Pass on NL */ - if ( t->c_iflag & IGNCR ) - igncr = 0x80; /* CR discarded on input */ - else - igncr = 0; - - /* Break handling */ - if ( t->c_iflag & IGNBRK ) { - ignbrk = 0x10; /* Ignore break on input */ - brkint = 0x08; - } else { - if ( t->c_iflag & BRKINT ) { - ignbrk = 0; /* Generate SIGINT (interrupt ) */ - brkint = 0; - } else { - ignbrk = 0; /* Convert to 0x00 */ - brkint = 0x08; - } - } - - /* Stripping */ - if ( t->c_iflag & ISTRIP ) - istrip = 0x80; /* Strip to 7 bits */ - else - istrip = 0; /* Leave as 8 bits */ - - rx_period = cd2401_bitrate_divisor( 20000000Ul, &in_baud ); - tx_period = cd2401_bitrate_divisor( 20000000Ul, &out_baud ); - - /* - * If this is the first time that the line characteristics are set up, then - * the device must be re-initialized. - * Also check if we need to change anything. It is preferable to not touch - * the device if nothing changes. As soon as we touch it, it tends to - * glitch. If anything changes, we reprogram all registers. This is - * harmless. - */ - if ( ( CD2401_Channel_Info[minor].tty == 0 ) || - ( cd2401->cor1 != (parodd | parenb | ignpar | csize) ) || - ( cd2401->cor2 != (sw_flow_ctl | hw_flow_ctl) ) || - ( cd2401->cor3 != (extra_flow_ctl | cstopb) ) || - ( cd2401->cor6 != (igncr | icrnl | inlcr | ignbrk | brkint | parmrk | inpck) ) || - ( cd2401->cor7 != istrip ) || - ( cd2401->u1.async.schr1 != t->c_cc[VSTART] ) || - ( cd2401->u1.async.schr2 != t->c_cc[VSTOP] ) || - ( cd2401->rbpr != (unsigned char)rx_period ) || - ( cd2401->rcor != (unsigned char)(rx_period >> 8) ) || - ( cd2401->tbpr != (unsigned char)tx_period ) || - ( cd2401->tcor != ( (tx_period >> 3) & 0xE0 ) ) ) - need_reinitialization = TRUE; - - /* Write to the ports */ - rtems_interrupt_disable (level); - - cd2401->car = minor; /* Select channel */ - read_enabled = cd2401->csr & 0x80 ? TRUE : FALSE; - - if ( (t->c_cflag & CREAD ? TRUE : FALSE ) != read_enabled ) { - /* Read enable status is changing */ - need_reinitialization = TRUE; - } - - if ( need_reinitialization ) { - /* - * Could not find a way to test whether the CD2401 was done transmitting. - * The TxEmpty interrupt does not seem to indicate that the FIFO is empty - * in DMA mode. So, just wait a while for output to drain. May not be - * enough, but it will have to do (should be long enough for 1 char at - * 9600 bsp)... - */ - cd2401_udelay( 2000L ); - - /* Clear channel */ - cd2401_chan_cmd (minor, 0x40, 1); - - cd2401->car = minor; /* Select channel */ - cd2401->cmr = 0x42; /* Interrupt Rx, DMA Tx, async mode */ - cd2401->cor1 = parodd | parenb | ignpar | csize; - cd2401->cor2 = sw_flow_ctl | hw_flow_ctl; - cd2401->cor3 = extra_flow_ctl | cstopb; - cd2401->cor4 = 0x0A; /* No DSR/DCD/CTS detect; FIFO threshold of 10 */ - cd2401->cor5 = 0x0A; /* No DSR/DCD/CTS detect; DTR threshold of 10 */ - cd2401->cor6 = igncr | icrnl | inlcr | ignbrk | brkint | parmrk | inpck; - cd2401->cor7 = istrip; /* No LNext; ignore XON/XOFF if frame error; no tx translations */ - /* Special char 1: XON character */ - cd2401->u1.async.schr1 = t->c_cc[VSTART]; - /* special char 2: XOFF character */ - cd2401->u1.async.schr2 = t->c_cc[VSTOP]; - - /* - * Special chars 3 and 4, char range, LNext, RFAR[1..4] and CRC - * are unused, left as is. - */ - - /* Set baudrates for receiver and transmitter */ - cd2401->rbpr = (unsigned char)rx_period; - cd2401->rcor = (unsigned char)(rx_period >> 8); /* no DPLL */ - cd2401->tbpr = (unsigned char)tx_period; - cd2401->tcor = (tx_period >> 3) & 0xE0; /* no x1 ext clk, no loopback */ - - /* Timeout for 4 chars at 9600, 8 bits per char, 1 stop bit */ - cd2401->u2.w.rtpr = 0x04; /* NEED TO LOOK AT THIS LINE! */ - - if ( t->c_cflag & CREAD ) { - /* Re-initialize channel, enable rx and tx */ - cd2401_chan_cmd (minor, 0x2A, 1); - /* Enable rx data ints */ - cd2401->ier = 0x08; - } else { - /* Re-initialize channel, enable tx, disable rx */ - cd2401_chan_cmd (minor, 0x29, 1); - } - } - - CD2401_RECORD_SET_ATTRIBUTES_INFO(( minor, need_reinitialization, csize, - cstopb, parodd, parenb, ignpar, inpck, - hw_flow_ctl, sw_flow_ctl, extra_flow_ctl, - icrnl, igncr, inlcr, brkint, ignbrk, - parmrk, istrip, tx_period, rx_period, - out_baud, in_baud )); - - rtems_interrupt_enable (level); - - /* - * Looks like the CD2401 needs time to settle after initialization. Give it - * 10 ms. I don't really believe it, but if output resumes to quickly after - * this call, the first few characters are not right. - */ - if ( need_reinitialization ) - cd2401_udelay( 10000L ); - - /* Return something */ - return RTEMS_SUCCESSFUL; -} - -/* - * cd2401_startRemoreTx - * - * Defined as a callback, but it would appear that it is never called. The - * POSIX standard states that when the tcflow() function is called with the - * TCION action, the system wall transmit a START character. Presumably, - * tcflow() is called internally when IXOFF is set in the termios c_iflag - * field when the input buffer can accomodate enough characters. It should - * probably be called from fillBufferQueue(). Clearly, the function is also - * explicitly callable by user code. The action is clearly to send the START - * character, regardless of whether START/STOP flow control is in effect. - * - * Input parameters: - * minor - selected channel - * - * Output parameters: NONE - * - * Return value: IGNORED - * - * PROPER START CHARACTER MUST BE PROGRAMMED IN SCHR1. - */ -int cd2401_startRemoteTx( - int minor -) -{ - rtems_interrupt_level level; - - rtems_interrupt_disable (level); - - cd2401->car = minor; /* Select channel */ - cd2401->stcr = 0x01; /* Send SCHR1 ahead of chars in FIFO */ - - CD2401_RECORD_START_REMOTE_TX_INFO(( minor )); - - rtems_interrupt_enable (level); - - /* Return something */ - return RTEMS_SUCCESSFUL; -} - -/* - * cd2401_stopRemoteTx - * - * Defined as a callback, but it would appear that it is never called. The - * POSIX standard states that when the tcflow() function is called with the - * TCIOFF function, the system wall transmit a STOP character. Presumably, - * tcflow() is called internally when IXOFF is set in the termios c_iflag - * field as the input buffer is about to overflow. It should probably be - * called from rtems_termios_enqueue_raw_characters(). Clearly, the function - * is also explicitly callable by user code. The action is clearly to send - * the STOP character, regardless of whether START/STOP flow control is in - * effect. - * - * Input parameters: - * minor - selected channel - * - * Output parameters: NONE - * - * Return value: IGNORED - * - * PROPER STOP CHARACTER MUST BE PROGRAMMED IN SCHR2. - */ -int cd2401_stopRemoteTx( - int minor -) -{ - rtems_interrupt_level level; - - rtems_interrupt_disable (level); - - cd2401->car = minor; /* Select channel */ - cd2401->stcr = 0x02; /* Send SCHR2 ahead of chars in FIFO */ - - CD2401_RECORD_STOP_REMOTE_TX_INFO(( minor )); - - rtems_interrupt_enable (level); - - /* Return something */ - return RTEMS_SUCCESSFUL; -} - -/* - * cd2401_write - * - * Initiate DMA output. Termios guarantees that the buffer does not wrap - * around, so we can do DMA strait from the supplied buffer. - * - * Input parameters: - * minor - selected channel - * buf - output buffer - * len - number of chars to output - * - * Output parameters: NONE - * - * Return value: IGNORED - * - * MUST BE EXECUTED WITH THE CD2401 INTERRUPTS DISABLED! - * The processor is placed at interrupt level CD2401_INT_LEVEL explicitly in - * console_write(). The processor is necessarily at interrupt level 1 in - * cd2401_tx_isr(). - */ -ssize_t cd2401_write( - int minor, - const char *buf, - size_t len -) -{ - if (len > 0) { - cd2401->car = minor; /* Select channel */ - - if ( (cd2401->dmabsts & 0x08) == 0 ) { - /* Next buffer is A. Wait for it to be ours. */ - while ( cd2401->atbsts & 0x01 ); - - CD2401_Channel_Info[minor].own_buf_A = FALSE; - CD2401_Channel_Info[minor].len = len; - CD2401_Channel_Info[minor].buf = buf; - cd2401->atbadru = (uint16_t)( ( (uint32_t) buf ) >> 16 ); - cd2401->atbadrl = (uint16_t)( (uint32_t) buf ); - cd2401->atbcnt = len; - CD2401_RECORD_WRITE_INFO(( len, buf, 'A' )); - cd2401->atbsts = 0x03; /* CD2401 owns buffer, int when empty */ - } - else { - /* Next buffer is B. Wait for it to be ours. */ - while ( cd2401->btbsts & 0x01 ); - - CD2401_Channel_Info[minor].own_buf_B = FALSE; - CD2401_Channel_Info[minor].len = len; - CD2401_Channel_Info[minor].buf = buf; - cd2401->btbadru = (uint16_t)( ( (uint32_t) buf ) >> 16 ); - cd2401->btbadrl = (uint16_t)( (uint32_t) buf ); - cd2401->btbcnt = len; - CD2401_RECORD_WRITE_INFO(( len, buf, 'B' )); - cd2401->btbsts = 0x03; /* CD2401 owns buffer, int when empty */ - } - /* Nuts -- Need TxD ints */ - CD2401_Channel_Info[minor].txEmpty = FALSE; - cd2401->ier |= 0x01; - } - - /* Return something */ - return len; -} - -#if 0 -/* - * cd2401_drainOutput - * - * Wait for the txEmpty indication on the specified channel. - * - * Input parameters: - * minor - selected channel - * - * Output parameters: NONE - * - * Return value: IGNORED - * - * MUST NOT BE EXECUTED WITH THE CD2401 INTERRUPTS DISABLED! - * The txEmpty flag is set by the tx ISR. - * - * DOES NOT WORK! DO NOT ENABLE THIS CODE. THE CD2401 DOES NOT COOPERATE! - * The code is here to document that the output FIFO is NOT empty when - * the CD2401 reports that the Tx buffer is empty. - */ -int cd2401_drainOutput( - int minor -) -{ - CD2401_RECORD_DRAIN_OUTPUT_INFO(( CD2401_Channel_Info[minor].txEmpty, - CD2401_Channel_Info[minor].own_buf_A, - CD2401_Channel_Info[minor].own_buf_B )); - - while( ! (CD2401_Channel_Info[minor].txEmpty && - CD2401_Channel_Info[minor].own_buf_A && - CD2401_Channel_Info[minor].own_buf_B) ); - - /* Return something */ - return RTEMS_SUCCESSFUL; -} -#endif - -/* - * _167Bug_pollRead - * - * Read a character from the 167Bug console, and return it. Return -1 - * if there is no character in the input FIFO. - * - * Input parameters: - * minor - selected channel - * - * Output parameters: NONE - * - * Return value: char returned as positive signed int - * -1 if no character is present in the input FIFO. - * - * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! - */ -int _167Bug_pollRead( - int minor -) -{ - int char_not_available; - unsigned char c; - rtems_interrupt_level previous_level; - - /* - * Redirection of .INSTAT does not work: 167-Bug crashes. - * Switch the input stream to the specified port. - * Make sure this is atomic code. - */ - rtems_interrupt_disable( previous_level ); - - __asm__ volatile( "movew %1, -(%%sp)\n\t"/* Channel */ - "trap #15\n\t" /* Trap to 167Bug */ - ".short 0x61\n\t" /* Code for .REDIR_I */ - "trap #15\n\t" /* Trap to 167Bug */ - ".short 0x01\n\t" /* Code for .INSTAT */ - "move %%cc, %0\n\t" /* Get condition codes */ - "andil #4, %0" /* Keep the Zero bit */ - : "=d" (char_not_available) : "d" (minor): "%%cc" ); - - if (char_not_available) { - rtems_interrupt_enable( previous_level ); - return -1; - } - - /* Read the char and return it */ - __asm__ volatile( "subq.l #2,%%a7\n\t" /* Space for result */ - "trap #15\n\t" /* Trap to 167 Bug */ - ".short 0x00\n\t" /* Code for .INCHR */ - "moveb (%%a7)+, %0" /* Pop char into c */ - : "=d" (c) : ); - - rtems_interrupt_enable( previous_level ); - - return (int)c; -} - -/* - * _167Bug_pollWrite - * - * Output buffer through 167Bug. Returns only once every character has been - * sent (polled output). - * - * Input parameters: - * minor - selected channel - * buf - output buffer - * len - number of chars to output - * - * Output parameters: NONE - * - * Return value: IGNORED - * - * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! - */ -ssize_t _167Bug_pollWrite( - int minor, - const char *buf, - size_t len -) -{ - const char *endbuf = buf + len; - - __asm__ volatile( "pea (%0)\n\t" /* endbuf */ - "pea (%1)\n\t" /* buf */ - "movew #0x21, -(%%sp)\n\t" /* Code for .OUTSTR */ - "movew %2, -(%%sp)\n\t" /* Channel */ - "trap #15\n\t" /* Trap to 167Bug */ - ".short 0x60" /* Code for .REDIR */ - :: "a" (endbuf), "a" (buf), "d" (minor) ); - - /* Return something */ - return len; -} - -/* - * do_poll_read - * - * Input characters through 167Bug. Returns has soon as a character has been - * received. Otherwise, if we wait for the number of requested characters, we - * could be here forever! - * - * CR is converted to LF on input. The terminal should not send a CR/LF pair - * when the return or enter key is pressed. - * - * Input parameters: - * major - ignored. Should be the major number for this driver. - * minor - selected channel. - * arg->buffer - where to put the received characters. - * arg->count - number of characters to receive before returning--Ignored. - * - * Output parameters: - * arg->bytes_moved - the number of characters read. Always 1. - * - * Return value: RTEMS_SUCCESSFUL - * - * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! - */ -static rtems_status_code do_poll_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args = arg; - int c; - - while( (c = _167Bug_pollRead (minor)) == -1 ); - rw_args->buffer[0] = (uint8_t)c; - if( rw_args->buffer[0] == '\r' ) - rw_args->buffer[0] = '\n'; - rw_args->bytes_moved = 1; - return RTEMS_SUCCESSFUL; -} - -/* - * do_poll_write - * - * Output characters through 167Bug. Returns only once every character has - * been sent. - * - * CR is transmitted AFTER a LF on output. - * - * Input parameters: - * major - ignored. Should be the major number for this driver. - * minor - selected channel - * arg->buffer - where to get the characters to transmit. - * arg->count - the number of characters to transmit before returning. - * - * Output parameters: - * arg->bytes_moved - the number of characters read - * - * Return value: RTEMS_SUCCESSFUL - * - * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! - */ -static rtems_status_code do_poll_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args = arg; - uint32_t i; - - for( i = 0; i < rw_args->count; i++ ) { - _167Bug_pollWrite(minor, &(rw_args->buffer[i]), 1); - if ( rw_args->buffer[i] == '\n' ) - _167Bug_pollWrite(minor, &cr_char, 1); - } - rw_args->bytes_moved = i; - return RTEMS_SUCCESSFUL; -} - -/* - * _BSP_output_char - * - * printk() function prototyped in bspIo.h. Does not use termios. - */ -void _BSP_output_char(char c) -{ - rtems_device_minor_number printk_minor; - - /* - * Can't rely on console_initialize having been called before this function - * is used. - */ - if ( NVRAM_CONFIGURE ) - /* J1-4 is on, use NVRAM info for configuration */ - printk_minor = (nvram->console_printk_port & 0x30) >> 4; - else - printk_minor = PRINTK_MINOR; - - _167Bug_pollWrite(printk_minor, &c, 1); -} - -/* - *************** - * BOILERPLATE * - *************** - * - * All these functions are prototyped in rtems/c/src/lib/include/console.h. - */ - -/* - * Initialize and register the device - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - rtems_device_minor_number console_minor; - - /* - * Set up TERMIOS if needed - */ - if ( NVRAM_CONFIGURE ) { - /* J1-4 is on, use NVRAM info for configuration */ - console_minor = nvram->console_printk_port & 0x03; - - if ( nvram->console_mode & 0x01 ) - /* termios */ - rtems_termios_initialize (); - } - else { - console_minor = CONSOLE_MINOR; -#if CD2401_USE_TERMIOS == 1 - rtems_termios_initialize (); -#endif - } - - /* - * Do device-specific initialization - * Does not affect 167-Bug. - */ - cd2401_initialize (); - - /* - * Register the devices - */ - status = rtems_io_register_name ("/dev/tty0", major, 0); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - status = rtems_io_register_name ("/dev/tty1", major, 1); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - status = rtems_io_register_name ("/dev/console", major, console_minor); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - status = rtems_io_register_name ("/dev/tty2", major, 2); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - status = rtems_io_register_name ("/dev/tty3", major, 3); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - return RTEMS_SUCCESSFUL; -} - -/* - * Open the device - */ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - static const rtems_termios_callbacks pollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - _167Bug_pollRead, /* pollRead */ - _167Bug_pollWrite, /* write */ - NULL, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - 0 /* outputUsesInterrupts */ - }; - - static const rtems_termios_callbacks intrCallbacks = { - cd2401_firstOpen, /* firstOpen */ - cd2401_lastClose, /* lastClose */ - NULL, /* pollRead */ - cd2401_write, /* write */ - cd2401_setAttributes, /* setAttributes */ - cd2401_stopRemoteTx, /* stopRemoteTx */ - cd2401_startRemoteTx, /* startRemoteTx */ - 1 /* outputUsesInterrupts */ - }; - - if ( NVRAM_CONFIGURE ) - /* J1-4 is on, use NVRAM info for configuration */ - if ( nvram->console_mode & 0x01 ) - /* termios */ - if ( nvram->console_mode & 0x02 ) - /* interrupt-driven I/O */ - return rtems_termios_open (major, minor, arg, &intrCallbacks); - else - /* polled I/O */ - return rtems_termios_open (major, minor, arg, &pollCallbacks); - else - /* no termios -- default to polled I/O */ - return RTEMS_SUCCESSFUL; -#if CD2401_USE_TERMIOS == 1 -#if CD2401_IO_MODE != 1 - else - /* termios & polled I/O*/ - return rtems_termios_open (major, minor, arg, &pollCallbacks); -#else - else - /* termios & interrupt-driven I/O*/ - return rtems_termios_open (major, minor, arg, &intrCallbacks); -#endif -#else - else - /* no termios -- default to polled I/O */ - return RTEMS_SUCCESSFUL; -#endif -} - -/* - * Close the device - */ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - if ( NVRAM_CONFIGURE ) { - /* J1-4 is on, use NVRAM info for configuration */ - if ( nvram->console_mode & 0x01 ) - /* termios */ - return rtems_termios_close (arg); - else - /* no termios */ - return RTEMS_SUCCESSFUL; - } -#if CD2401_USE_TERMIOS == 1 - else - /* termios */ - return rtems_termios_close (arg); -#else - else - /* no termios */ - return RTEMS_SUCCESSFUL; -#endif -} - -/* - * Read from the device - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - if ( NVRAM_CONFIGURE ) { - /* J1-4 is on, use NVRAM info for configuration */ - if ( nvram->console_mode & 0x01 ) - /* termios */ - return rtems_termios_read (arg); - else - /* no termios -- default to polled */ - return do_poll_read (major, minor, arg); - } -#if CD2401_USE_TERMIOS == 1 - else - /* termios */ - return rtems_termios_read (arg); -#else - else - /* no termios -- default to polled */ - return do_poll_read (major, minor, arg); -#endif -} - -/* - * Write to the device - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - if ( NVRAM_CONFIGURE ) { - /* J1-4 is on, use NVRAM info for configuration */ - if ( nvram->console_mode & 0x01 ) - /* termios */ - return rtems_termios_write (arg); - else - /* no termios -- default to polled */ - return do_poll_write (major, minor, arg); - } -#if CD2401_USE_TERMIOS == 1 - else - /* termios */ - return rtems_termios_write (arg); -#else - else - /* no termios -- default to polled */ - return do_poll_write (major, minor, arg); -#endif -} - -/* - * Handle ioctl request. - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - if ( NVRAM_CONFIGURE ) { - /* J1-4 is on, use NVRAM info for configuration */ - if ( nvram->console_mode & 0x01 ) - /* termios */ - return rtems_termios_ioctl (arg); - else - /* no termios -- default to polled */ - return RTEMS_SUCCESSFUL; - } -#if CD2401_USE_TERMIOS == 1 - else - /* termios */ - return rtems_termios_ioctl (arg); -#else - else - /* no termios -- default to polled */ - return RTEMS_SUCCESSFUL; -#endif -} diff --git a/c/src/lib/libbsp/m68k/uC5282/Makefile.am b/c/src/lib/libbsp/m68k/uC5282/Makefile.am index 237e2096c1..de7e43acb8 100644 --- a/c/src/lib/libbsp/m68k/uC5282/Makefile.am +++ b/c/src/lib/libbsp/m68k/uC5282/Makefile.am @@ -29,7 +29,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/setvec.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/uC5282/clock/clock.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/uC5282/console/console.c # timer librtemsbsp_a_SOURCES += timer/timer.c diff --git a/c/src/lib/libbsp/m68k/uC5282/console/console.c b/c/src/lib/libbsp/m68k/uC5282/console/console.c deleted file mode 100644 index 276d0c6f18..0000000000 --- a/c/src/lib/libbsp/m68k/uC5282/console/console.c +++ /dev/null @@ -1,774 +0,0 @@ -/* - * Multi UART console serial I/O. - * - * TO DO: Add DMA input/output - * - * Author: W. Eric Norum - * - * COPYRIGHT (c) 2005. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x)) - -#define MCF5282_UART_USR_ERROR ( MCF5282_UART_USR_RB | \ - MCF5282_UART_USR_FE | \ - MCF5282_UART_USR_PE | \ - MCF5282_UART_USR_OE ) - -static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len); -static ssize_t IntUartInterruptWrite (int minor, const char *buf, size_t len); - -static void -_BSP_null_char( char c ) -{ - int level; - - rtems_interrupt_disable(level); - while ( (MCF5282_UART_USR(CONSOLE_PORT) & MCF5282_UART_USR_TXRDY) == 0 ) - continue; - MCF5282_UART_UTB(CONSOLE_PORT) = c; - while ( (MCF5282_UART_USR(CONSOLE_PORT) & MCF5282_UART_USR_TXRDY) == 0 ) - continue; - rtems_interrupt_enable(level); -} - -BSP_polling_getchar_function_type BSP_poll_char = NULL; -BSP_output_char_function_type BSP_output_char = _BSP_null_char; - -/* - * The MCF5282 has three UARTs. Enable all them here. I/O pin selection - * is assumed to have been done elsewher. - */ -#define MAX_UART_INFO 3 -#define RX_BUFFER_SIZE 512 - -struct IntUartInfoStruct -{ - int iomode; - volatile int uimr; - int baud; - int databits; - int parity; - int stopbits; - int hwflow; - int rx_in; - int rx_out; - char rx_buffer[RX_BUFFER_SIZE]; - void *ttyp; -}; - -struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO]; - -/*************************************************************************** - Function : IntUartSet - - Description : This updates the hardware UART settings. - ***************************************************************************/ -static void -IntUartSet(int minor, int baud, int databits, int parity, int stopbits, int hwflow) -{ - int divisor; - uint32_t clock_speed; - uint8_t umr1 = 0; - uint8_t umr2 = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - int level; - - rtems_interrupt_disable(level); - - - /* disable interrupts, clear RTS line, and disable the UARTS */ - MCF5282_UART_UIMR(minor) = 0; - MCF5282_UART_UOP0(minor) = 1; - MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_DISABLED | MCF5282_UART_UCR_RX_DISABLED); - - /* save the current values */ - info->uimr = 0; - info->baud = baud; - info->databits = databits; - info->parity = parity; - info->stopbits = stopbits; - info->hwflow = hwflow; - - clock_speed = bsp_get_CPU_clock_speed(); - /* determine the baud divisor value */ - divisor = (clock_speed / ( 32 * baud )); - if ( divisor < 2 ) { - divisor = 2; - } - - /* check to see if doing hardware flow control */ - if ( hwflow ) - { - /* set hardware flow options */ - umr1 |= MCF5282_UART_UMR1_RXRTS; - umr2 |= MCF5282_UART_UMR2_TXCTS; - } - - /* determine the new umr values */ - umr1 |= (parity | databits); - umr2 |= (stopbits); - - /* reset the uart */ - MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_ERROR; - MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_RX; - MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_TX; - - /* reset the uart mode register and update values */ - MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_MR; - MCF5282_UART_UMR(minor) = umr1; - MCF5282_UART_UMR(minor) = umr2; - - /* set the baud rate values */ - MCF5282_UART_UCSR(minor) = (MCF5282_UART_UCSR_RCS_SYS_CLK | MCF5282_UART_UCSR_TCS_SYS_CLK); - MCF5282_UART_UBG1(minor) = (divisor & 0xff00) >> 8; - MCF5282_UART_UBG2(minor) = (divisor & 0x00ff); - - /* enable the uart */ - MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_ENABLED | MCF5282_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if ( info->iomode != TERMIOS_POLLED ) - { - /* enable rx interrupts */ - info->uimr |= MCF5282_UART_UIMR_FFULL; - MCF5282_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if ( hwflow ) - { - /* assert the RTS line */ - MCF5282_UART_UOP1(minor) = 1; - } - - rtems_interrupt_enable(level); - -} - - -/*************************************************************************** - Function : IntUartSetAttributes - - Description : This provides the hardware-dependent portion of tcsetattr(). - value and sets it. At the moment this just sets the baud rate. - - Note: The highest baudrate is 115200 as this stays within - an error of +/- 5% at 25MHz processor clock - ***************************************************************************/ -static int -IntUartSetAttributes(int minor, const struct termios *t) -{ - /* set default index values */ - int baud = (int)9600; - int databits = (int)MCF5282_UART_UMR1_BC_8; - int parity = (int)MCF5282_UART_UMR1_PM_NONE; - int stopbits = (int)MCF5282_UART_UMR2_STOP_BITS_1; - int hwflow = (int)0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* check to see if input is valid */ - if ( t != (const struct termios *)0 ) - { - /* determine baud rate index */ - baud = rtems_termios_baud_to_number(t->c_ospeed); - - /* determine data bits */ - switch ( t->c_cflag & CSIZE ) - { - case CS5: - databits = (int)MCF5282_UART_UMR1_BC_5; - break; - case CS6: - databits = (int)MCF5282_UART_UMR1_BC_6; - break; - case CS7: - databits = (int)MCF5282_UART_UMR1_BC_7; - break; - case CS8: - databits = (int)MCF5282_UART_UMR1_BC_8; - break; - } - - /* determine if parity is enabled */ - if ( t->c_cflag & PARENB ) - { - if ( t->c_cflag & PARODD ) - { - /* odd parity */ - parity = (int)MCF5282_UART_UMR1_PM_ODD; - } - else - { - /* even parity */ - parity = (int)MCF5282_UART_UMR1_PM_EVEN; - } - } - - /* determine stop bits */ - if ( t->c_cflag & CSTOPB ) - { - /* two stop bits */ - stopbits = (int)MCF5282_UART_UMR2_STOP_BITS_2; - } - - /* check to see if hardware flow control */ - if ( t->c_cflag & CRTSCTS ) - { - hwflow = 1; - } - } - - /* check to see if values have changed */ - if ( ( baud != info->baud ) || - ( databits != info->databits ) || - ( parity != info->parity ) || - ( stopbits != info->stopbits ) || - ( hwflow != info->hwflow ) ) - { - - /* call function to set values */ - IntUartSet(minor, baud, databits, parity, stopbits, hwflow); - } - - return( RTEMS_SUCCESSFUL ); - -} - -/*************************************************************************** - Function : IntUartInterruptHandler - - Description : This is the interrupt handler for the internal uart. It - determines which channel caused the interrupt before queueing any received - chars and dequeueing chars waiting for transmission. - ***************************************************************************/ -static rtems_isr -IntUartInterruptHandler(rtems_vector_number v) -{ - unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0); - struct IntUartInfoStruct *info = &IntUartInfo[chan]; - - /* check to see if received data */ - if ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_RXRDY ) - { - /* read data and put into the receive buffer */ - while ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_RXRDY ) - { - - if ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_ERROR ) - { - /* clear the error */ - MCF5282_UART_UCR(chan) = MCF5282_UART_UCR_RESET_ERROR; - } - /* put data in rx buffer and check for errors */ - info->rx_buffer[info->rx_in] = MCF5282_UART_URB(chan); - - /* update buffer values */ - info->rx_in++; - - if ( info->rx_in >= RX_BUFFER_SIZE ) - { - info->rx_in = 0; - } - } - /* Make sure the port has been opened */ - if ( info->ttyp ) - { - - /* check to see if task driven */ - if ( info->iomode == TERMIOS_TASK_DRIVEN ) - { - /* notify rx task that rx buffer has data */ - rtems_termios_rxirq_occured(info->ttyp); - } - else - { - /* Push up the received data */ - rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, info->rx_in); - info->rx_in = 0; - } - } - } - - /* check to see if data needs to be transmitted */ - if ( ( info->uimr & MCF5282_UART_UIMR_TXRDY ) && - ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_TXRDY ) ) - { - - /* disable tx interrupts */ - info->uimr &= ~MCF5282_UART_UIMR_TXRDY; - MCF5282_UART_UIMR(chan) = info->uimr; - - /* tell upper level that character has been sent */ - if ( info->ttyp ) - rtems_termios_dequeue_characters(info->ttyp, 1); - } -} - - - -/*************************************************************************** - Function : IntUartInitialize - - Description : This initialises the internal uart hardware for all - internal uarts. If the internal uart is to be interrupt driven then the - interrupt vectors are hooked. - ***************************************************************************/ -static void -IntUartInitialize(void) -{ - unsigned int chan; - struct IntUartInfoStruct *info; - rtems_isr_entry old_handler; - int level; - - for ( chan = 0; chan < MAX_UART_INFO; chan++ ) - { - info = &IntUartInfo[chan]; - - info->ttyp = NULL; - info->rx_in = 0; - info->rx_out = 0; - info->baud = -1; - info->databits = -1; - info->parity = -1; - info->stopbits = -1; - info->hwflow = -1; - - MCF5282_UART_UACR(chan) = 0; - MCF5282_UART_UIMR(chan) = 0; - if ( info->iomode != TERMIOS_POLLED ) - { - rtems_interrupt_catch (IntUartInterruptHandler, - UART_INTC0_IRQ_VECTOR(chan), - &old_handler); - } - - /* set uart default values */ - IntUartSetAttributes(chan, NULL); - - /* unmask interrupt */ - rtems_interrupt_disable(level); - switch(chan) { - case 0: - bsp_allocate_interrupt(UART0_IRQ_LEVEL, UART0_IRQ_PRIORITY); - MCF5282_INTC0_ICR13 = MCF5282_INTC_ICR_IL(UART0_IRQ_LEVEL) | - MCF5282_INTC_ICR_IP(UART0_IRQ_PRIORITY); - MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT13 | - MCF5282_INTC_IMRL_MASKALL); - break; - - case 1: - bsp_allocate_interrupt(UART1_IRQ_LEVEL, UART1_IRQ_PRIORITY); - MCF5282_INTC0_ICR14 = MCF5282_INTC_ICR_IL(UART1_IRQ_LEVEL) | - MCF5282_INTC_ICR_IP(UART1_IRQ_PRIORITY); - MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT14 | - MCF5282_INTC_IMRL_MASKALL); - break; - - case 2: - bsp_allocate_interrupt(UART2_IRQ_LEVEL, UART2_IRQ_PRIORITY); - MCF5282_INTC0_ICR15 = MCF5282_INTC_ICR_IL(UART2_IRQ_LEVEL) | - MCF5282_INTC_ICR_IP(UART2_IRQ_PRIORITY); - MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT15 | - MCF5282_INTC_IMRL_MASKALL); - break; - } - rtems_interrupt_enable(level); - - } /* of chan loop */ - - -} /* IntUartInitialise */ - - -/*************************************************************************** - Function : IntUartInterruptWrite - - Description : This writes a single character to the appropriate uart - channel. This is either called during an interrupt or in the user's task - to initiate a transmit sequence. Calling this routine enables Tx - interrupts. - ***************************************************************************/ -static ssize_t -IntUartInterruptWrite (int minor, const char *buf, size_t len) -{ - if (len > 0) { - /* write out character */ - MCF5282_UART_UTB(minor) = *buf; - - /* enable tx interrupt */ - IntUartInfo[minor].uimr |= MCF5282_UART_UIMR_TXRDY; - MCF5282_UART_UIMR(minor) = IntUartInfo[minor].uimr; - } - - return 0; -} - -/*************************************************************************** - Function : IntUartInterruptOpen - - Description : This enables interrupts when the tty is opened. - ***************************************************************************/ -static int -IntUartInterruptOpen(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - int level; - - /* - * Enable serial I/O pin assignments - */ - rtems_interrupt_disable(level); - switch(minor) { - case 0: - MCF5282_GPIO_PUAPAR |= MCF5282_GPIO_PUAPAR_PUAPA1|MCF5282_GPIO_PUAPAR_PUAPA0; - break; - case 1: - MCF5282_GPIO_PUAPAR |= MCF5282_GPIO_PUAPAR_PUAPA3|MCF5282_GPIO_PUAPAR_PUAPA2; - break; - case 2: - MCF5282_GPIO_PASPAR = - (MCF5282_GPIO_PASPAR - & ~(MCF5282_GPIO_PASPAR_PASPA3(3)|MCF5282_GPIO_PASPAR_PASPA2(3))) - | (MCF5282_GPIO_PASPAR_PASPA3(2)|MCF5282_GPIO_PASPAR_PASPA2(2)); - break; - } - rtems_interrupt_enable(level); - /* enable the uart */ - MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_ENABLED | MCF5282_UART_UCR_RX_ENABLED); - - /* check to see if interrupts need to be enabled */ - if ( info->iomode != TERMIOS_POLLED ) - { - /* enable rx interrupts */ - info->uimr |= MCF5282_UART_UIMR_FFULL; - MCF5282_UART_UIMR(minor) = info->uimr; - } - - /* check to see if doing hardware flow control */ - if ( info->hwflow ) - { - /* assert the RTS line */ - MCF5282_UART_UOP1(minor) = 1; - } - - return( 0 ); -} - - - -/*************************************************************************** - Function : IntUartInterruptClose - - Description : This disables interrupts when the tty is closed. - ***************************************************************************/ -static int -IntUartInterruptClose(int major, int minor, void *arg) -{ - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* disable the interrupts and the uart */ - MCF5282_UART_UIMR(minor) = 0; - MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_DISABLED | MCF5282_UART_UCR_RX_DISABLED); - - /* reset values */ - info->ttyp = NULL; - info->uimr = 0; - info->rx_in = 0; - info->rx_out = 0; - - return( 0 ); -} - -/*************************************************************************** - Function : IntUartTaskRead - - Description : This reads all available characters from the internal uart - and places them into the termios buffer. The rx interrupts will be - re-enabled after all data has been read. - ***************************************************************************/ -static int -IntUartTaskRead(int minor) -{ - char buffer[RX_BUFFER_SIZE]; - int count; - int rx_in; - int index = 0; - struct IntUartInfoStruct *info = &IntUartInfo[minor]; - - /* determine number of values to copy out */ - rx_in = info->rx_in; - if ( info->rx_out <= rx_in ) - { - count = rx_in - info->rx_out; - } - else - { - count = (RX_BUFFER_SIZE - info->rx_out) + rx_in; - } - - /* copy data into local buffer from rx buffer */ - while ( ( index < count ) && ( index < RX_BUFFER_SIZE ) ) - { - /* copy data byte */ - buffer[index] = info->rx_buffer[info->rx_out]; - index++; - - /* increment rx buffer values */ - info->rx_out++; - if ( info->rx_out >= RX_BUFFER_SIZE ) - { - info->rx_out = 0; - } - } - - /* check to see if buffer is not empty */ - if ( count > 0 ) - { - /* set characters into termios buffer */ - rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count); - } - - return( EOF ); -} - - - -/*************************************************************************** - Function : IntUartPollRead - - Description : This reads a character from the internal uart. It returns - to the caller without blocking if not character is waiting. - ***************************************************************************/ -static int -IntUartPollRead (int minor) -{ - if ( (MCF5282_UART_USR(minor) & MCF5282_UART_USR_RXRDY) == 0 ) - return(-1); - - return(MCF5282_UART_URB(minor)); -} - - -/*************************************************************************** - Function : IntUartPollWrite - - Description : This writes out each character in the buffer to the - appropriate internal uart channel waiting till each one is sucessfully - transmitted. - ***************************************************************************/ -static ssize_t -IntUartPollWrite (int minor, const char *buf, size_t len) -{ - size_t retval = len; - /* loop over buffer */ - while ( len-- ) - { - /* block until we can transmit */ - while ( (MCF5282_UART_USR(minor) & MCF5282_UART_USR_TXRDY) == 0 ) - continue; - /* transmit data byte */ - MCF5282_UART_UTB(minor) = *buf++; - } - return retval; -} - -/*************************************************************************** - Function : console_initialize - - Description : This initialises termios, all uart hardware before - registering /dev/tty devices for each channel and the system /dev/console. - ***************************************************************************/ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg ) -{ - rtems_status_code status; - int chan; - - /* Set up TERMIOS */ - rtems_termios_initialize (); - - /* set io modes for the different channels and initialize device */ - for ( chan = 0; chan < MAX_UART_INFO; chan++ ) - IntUartInfo[chan].iomode = TERMIOS_IRQ_DRIVEN; - IntUartInitialize(); - - /* Register the console port */ - status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - - /* Register the other ports */ - if ( CONSOLE_PORT != 0 ) - { - status = rtems_io_register_name ("/dev/tty00", major, 0); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - } - if ( CONSOLE_PORT != 1 ) - { - status = rtems_io_register_name ("/dev/tty01", major, 1); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - } - status = rtems_io_register_name ("/dev/tty02", major, 2); - if ( status != RTEMS_SUCCESSFUL ) - { - rtems_fatal_error_occurred (status); - } - - return(RTEMS_SUCCESSFUL); -} - -/*************************************************************************** - Function : console_open - - Description : This actually opens the device depending on the minor - number set during initialisation. The device specific access routines are - passed to termios when the devices is opened depending on whether it is - polled or not. - ***************************************************************************/ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - rtems_status_code status = RTEMS_INVALID_NUMBER; - rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *)arg; - struct IntUartInfoStruct *info; - - static const rtems_termios_callbacks IntUartPollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - IntUartPollRead, /* pollRead */ - IntUartPollWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_POLLED /* mode */ - }; - static const rtems_termios_callbacks IntUartIntrCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - NULL, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_IRQ_DRIVEN /* mode */ - }; - - static const rtems_termios_callbacks IntUartTaskCallbacks = { - IntUartInterruptOpen, /* firstOpen */ - IntUartInterruptClose, /* lastClose */ - IntUartTaskRead, /* pollRead */ - IntUartInterruptWrite, /* write */ - IntUartSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_TASK_DRIVEN /* mode */ - }; - - /* open the port depending on the minor device number */ - if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) ) - { - info = &IntUartInfo[minor]; - switch ( info->iomode ) - { - case TERMIOS_POLLED: - status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks); - break; - case TERMIOS_IRQ_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks); - info->ttyp = args->iop->data1; - break; - case TERMIOS_TASK_DRIVEN: - status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks); - info->ttyp = args->iop->data1; - break; - } - } - - return( status ); -} - -/*************************************************************************** - Function : console_close - - Description : This closes the device via termios - ***************************************************************************/ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return(rtems_termios_close (arg)); -} - -/****************** -********************************************************* - Function : console_read - - Description : Read from the device via termios - ***************************************************************************/ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return(rtems_termios_read (arg)); -} - -/*************************************************************************** - Function : console_write - - Description : Write to the device via termios - ***************************************************************************/ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return(rtems_termios_write (arg)); -} - -/*************************************************************************** - Function : console_ioctl - - Description : Pass the IOCtl call to termios - ***************************************************************************/ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg) -{ - return( rtems_termios_ioctl (arg) ); -} - diff --git a/c/src/lib/libbsp/mips/csb350/Makefile.am b/c/src/lib/libbsp/mips/csb350/Makefile.am index 58d0ada987..49d28530d0 100644 --- a/c/src/lib/libbsp/mips/csb350/Makefile.am +++ b/c/src/lib/libbsp/mips/csb350/Makefile.am @@ -28,8 +28,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/sbrk.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/mips/csb350/clock/clockdrv.c # console -librtemsbsp_a_SOURCES += console/console-io.c -librtemsbsp_a_SOURCES += ../../shared/console-polled.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/mips/csb350/console/console-io.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-polled.c # timer librtemsbsp_a_SOURCES += timer/timer.c #isr diff --git a/c/src/lib/libbsp/mips/csb350/console/console-io.c b/c/src/lib/libbsp/mips/csb350/console/console-io.c deleted file mode 100644 index e1beff8460..0000000000 --- a/c/src/lib/libbsp/mips/csb350/console/console-io.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * This file contains the hardware specific portions of the TTY driver - * for the serial ports on the csb350. - */ - -/* - * COPYRIGHT (c) 1989-2000. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include - -/* - * console_initialize_hardware - * - * This routine initializes the console hardware. - * - */ -void console_initialize_hardware(void) -{ - uart0->fifoctrl = 0xf1; /* enable fifo, max sizes */ - au_sync(); -} - - -/* - * console_outbyte_polled - * - * This routine transmits a character using polling. - */ -void console_outbyte_polled( - int port, - char ch -) -{ - /* wait for the fifo to make room */ - while ((uart0->linestat & 0x20) == 0) { - continue; - } - - uart0->txdata = ch; - au_sync(); -} -/* - * console_inbyte_nonblocking - * - * This routine polls for a character. - */ - -int console_inbyte_nonblocking( - int port -) -{ - unsigned char c; - - if (uart0->linestat & 1) { - c = (char)uart0->rxdata; - return c; - } else { - return -1; - } -} - -#include - -static void csb250_output_char(char c) -{ - console_outbyte_polled( 0, c ); -} - -static int csb250_get_char(void) -{ - return console_inbyte_nonblocking(0); -} - -BSP_output_char_function_type BSP_output_char = csb250_output_char; -BSP_polling_getchar_function_type BSP_poll_char = csb250_get_char; - diff --git a/c/src/lib/libbsp/mips/hurricane/Makefile.am b/c/src/lib/libbsp/mips/hurricane/Makefile.am index f789d0835e..b3963916a4 100644 --- a/c/src/lib/libbsp/mips/hurricane/Makefile.am +++ b/c/src/lib/libbsp/mips/hurricane/Makefile.am @@ -34,7 +34,7 @@ librtemsbsp_a_SOURCES += startup/usc.S librtemsbsp_a_SOURCES +=../../../../../../bsps/mips/hurricane/clock/ckinit.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/mips/hurricane/console/console.c # liblnk librtemsbsp_a_SOURCES += ../shared/liblnk/lnklib.S librtemsbsp_a_SOURCES += ../shared/liblnk/pmon.S diff --git a/c/src/lib/libbsp/mips/hurricane/console/console.c b/c/src/lib/libbsp/mips/hurricane/console/console.c deleted file mode 100644 index 219cc964c0..0000000000 --- a/c/src/lib/libbsp/mips/hurricane/console/console.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * This file contains the IDT 4650 console IO package. - */ - -/* - * Author: Craig Lebakken - * - * COPYRIGHT (c) 1996 by Transition Networks Inc. - * - * To anyone who acknowledges that this file is provided "AS IS" - * without any express or implied warranty: - * permission to use, copy, modify, and distribute this file - * for any purpose is hereby granted without fee, provided that - * the above copyright notice and this notice appears in all - * copies, and that the name of Transition Networks not be used in - * advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * Transition Networks makes no representations about the suitability - * of this software for any purpose. - * - * Derived from c/src/lib/libbsp/no_cpu/no_bsp/console/console.c: - * - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include -#include - -/* PMON entry points */ -int mon_read(int fd, char *buf, int cnt); /* stdin is fd=0 */ -int mon_write(int fd, char *buf, int cnt); /* stdout is fd=1 */ - -/* console_initialize - * - * This routine initializes the console IO driver. - * - * Input parameters: NONE - * - * Output parameters: NONE - * - * Return values: - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - - status = rtems_io_register_name( - "/dev/console", - major, - (rtems_device_minor_number) 0 - ); - - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - return RTEMS_SUCCESSFUL; -} - -/* inbyte - * - * This routine reads a character from the SOURCE. - */ -static char inbyte( void ) -{ - char buf[10]; - - /* - * If polling, wait until a character is available. - */ - mon_read(0, buf, 1); /* stdin is fd=0, read 1 byte */ - - return (buf[0]); -} - -/* outbyte - * - * This routine transmits a character out the SOURCE. It may support - * XON/XOFF flow control. - */ -static void outbyte( - char ch -) -{ - char buf[10]; - /* - * If polling, wait for the transmitter to be ready. - * Check for flow control requests and process. - * Then output the character. - */ - buf[0] = ch; - - mon_write( 1, buf, 1 ); /* stdout is fd=1, write 1 byte */ -} - -/* - * Open entry point - */ - -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * Close entry point - */ - -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * read bytes from the serial port. We only have stdin. - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args; - char *buffer; - int maximum; - int count = 0; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - for (count = 0; count < maximum; count++) { - buffer[ count ] = inbyte(); - if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { - buffer[ count++ ] = '\n'; - break; - } - } - - rw_args->bytes_moved = count; - return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; -} - -/* - * write bytes to the serial port. Stdout and stderr are the same. - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - int count; - int maximum; - rtems_libio_rw_args_t *rw_args; - char *buffer; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - for (count = 0; count < maximum; count++) { - if ( buffer[ count ] == '\n') { - outbyte('\r'); - } - outbyte( buffer[ count ] ); - } - - rw_args->bytes_moved = maximum; - return 0; -} - -/* - * IO Control entry point - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -#include - -static void hurricane_output_char(char c) { outbyte( c ); } - -BSP_output_char_function_type BSP_output_char = hurricane_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - diff --git a/c/src/lib/libbsp/mips/jmr3904/Makefile.am b/c/src/lib/libbsp/mips/jmr3904/Makefile.am index 67b357e470..5b9516beaf 100644 --- a/c/src/lib/libbsp/mips/jmr3904/Makefile.am +++ b/c/src/lib/libbsp/mips/jmr3904/Makefile.am @@ -27,8 +27,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/sbrk.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/mips/jmr3904/clock/clockdrv.c # console -librtemsbsp_a_SOURCES += ../../shared/console-polled.c -librtemsbsp_a_SOURCES += console/console-io.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-polled.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/mips/jmr3904/console/console-io.c # timer librtemsbsp_a_SOURCES += timer/timer.c #isr diff --git a/c/src/lib/libbsp/mips/jmr3904/console/console-io.c b/c/src/lib/libbsp/mips/jmr3904/console/console-io.c deleted file mode 100644 index a7f3204d25..0000000000 --- a/c/src/lib/libbsp/mips/jmr3904/console/console-io.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * This file contains the hardware specific portions of the TTY driver - * for the serial ports on the jmr3904. - * - * Logic based on the jmr3904-io.c file in newlib 1.8.2 - */ - -/* - * COPYRIGHT (c) 1989-2000. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include - -/* external prototypes for monitor interface routines */ - -#define READ_UINT8( _register_, _value_ ) \ - ((_value_) = *((volatile unsigned char *)(_register_))) - -#define WRITE_UINT8( _register_, _value_ ) \ - (*((volatile unsigned char *)(_register_)) = (_value_)) - -#define READ_UINT16( _register_, _value_ ) \ - ((_value_) = *((volatile unsigned short *)(_register_))) - -#define WRITE_UINT16( _register_, _value_ ) \ - (*((volatile unsigned short *)(_register_)) = (_value_)) - - /* - Board specific addresses for serial chip */ -#define DIAG_BASE 0xfffff300 -#define DIAG_SLCR (DIAG_BASE+0x00) -#define DIAG_SLSR (DIAG_BASE+0x04) -#define DIAG_SLDICR (DIAG_BASE+0x08) -#define DIAG_SLDISR (DIAG_BASE+0x0C) -#define DIAG_SFCR (DIAG_BASE+0x10) -#define DIAG_SBRG (DIAG_BASE+0x14) -#define DIAG_TFIFO (DIAG_BASE+0x20) -#define DIAG_RFIFO (DIAG_BASE+0x30) - -#define BRG_T0 0x0000 -#define BRG_T2 0x0100 -#define BRG_T4 0x0200 -#define BRG_T5 0x0300 - -/* - * Eventually console-polled.c should hook to this better. - */ - -/* - * console_initialize_hardware - * - * This routine initializes the console hardware. - * - */ - -void console_initialize_hardware(void) -{ - WRITE_UINT16 (DIAG_SLCR, 0x0020); - WRITE_UINT16 (DIAG_SLDICR, 0x0000); - WRITE_UINT16 (DIAG_SFCR, 0x0000); - WRITE_UINT16 (DIAG_SBRG, BRG_T2 | 5); -} - -/* - * console_outbyte_polled - * - * This routine transmits a character using polling. - */ - -void console_outbyte_polled( - int port, - char ch -) -{ - unsigned short disr; - - for (;;) { - READ_UINT16 (DIAG_SLDISR, disr); - if (disr & 0x0002) - break; - } - disr = disr & ~0x0002; - WRITE_UINT8 (DIAG_TFIFO, (unsigned char) ch); - WRITE_UINT16 (DIAG_SLDISR, disr); -} - -/* - * console_inbyte_nonblocking - * - * This routine polls for a character. - */ - -int console_inbyte_nonblocking( - int port -) -{ - unsigned char c; - unsigned short disr; - - READ_UINT16 (DIAG_SLDISR, disr); - if (disr & 0x0001) { - disr = disr & ~0x0001; - READ_UINT8 (DIAG_RFIFO, c); - WRITE_UINT16 (DIAG_SLDISR, disr); - return (char) c; - } - return -1; -} - -#include - -static void JMR3904_output_char(char c) { console_outbyte_polled( 0, c ); } - -BSP_output_char_function_type BSP_output_char = JMR3904_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/mips/malta/Makefile.am b/c/src/lib/libbsp/mips/malta/Makefile.am index c875d4b09c..c955b58a4a 100644 --- a/c/src/lib/libbsp/mips/malta/Makefile.am +++ b/c/src/lib/libbsp/mips/malta/Makefile.am @@ -41,8 +41,8 @@ librtemsbsp_a_SOURCES +=../../../../../../bsps/mips/shared/clock/mips_timer.S librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c -librtemsbsp_a_SOURCES += console/conscfg.c -librtemsbsp_a_SOURCES += console/printk_support.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/mips/malta/console/conscfg.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/mips/malta/console/printk_support.c # timer librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/btimer/btimer-stub.c diff --git a/c/src/lib/libbsp/mips/malta/console/conscfg.c b/c/src/lib/libbsp/mips/malta/console/conscfg.c deleted file mode 100644 index 8d84c9321c..0000000000 --- a/c/src/lib/libbsp/mips/malta/console/conscfg.c +++ /dev/null @@ -1,158 +0,0 @@ -/** - * @file - * - * This file contains the libchip configuration information - * to instantiate the libchip driver for the serial ports. - */ - -/* - * COPYRIGHT (c) 1989-2012. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include /* write */ - -#include -#include -#include -#include -#include - -#if 1 -#define COM_CONSOLE_FUNCTIONS &ns16550_fns_polled -#else -#define COM_CONSOLE_FUNCTIONS &ns16550_fns -#endif - -/* - * Base IO for UART - */ -#define COM1_BASE_IO 0x3F8 -#define COM2_BASE_IO 0x3E8 - -// #define CLOCK_RATE 368640 -#define CLOCK_RATE (115200 * 16) - -#define COM_IO_BASE_ADDRESS (0xa0000000UL | 0x18000000UL) - -static uint8_t com_get_register(uintptr_t addr, uint8_t i); -static void com_set_register(uintptr_t addr, uint8_t i, uint8_t val); -static uint8_t tty2_get_register(uintptr_t addr, uint8_t i); -static void tty2_set_register(uintptr_t addr, uint8_t i, uint8_t val); - - -uint8_t com_get_register(uintptr_t addr, uint8_t i) -{ - uint8_t val; - volatile uint8_t *ptr; - ptr = (volatile uint8_t *) COM_IO_BASE_ADDRESS; - ptr += addr; - ptr += i; - val = *ptr; - - return val; -} - -void com_set_register(uintptr_t addr, uint8_t i, uint8_t val) -{ - volatile uint8_t *ptr; - - ptr = (volatile uint8_t *) COM_IO_BASE_ADDRESS; - ptr += addr; - ptr += i; - *ptr = val; -} - -uint8_t tty2_get_register(uintptr_t addr, uint8_t i) -{ - uint8_t val; - volatile uint8_t *ptr; - - ptr = (volatile uint8_t *) COM_IO_BASE_ADDRESS; - ptr += addr; - ptr += (i * 8); - val = *ptr; - - return val; -} - -void tty2_set_register(uintptr_t addr, uint8_t i, uint8_t val) -{ - volatile uint8_t *ptr; - - ptr = (volatile uint8_t *) COM_IO_BASE_ADDRESS; - ptr += addr; - ptr += (i * 8); - *ptr = val; -} - -console_tbl Console_Configuration_Ports[] = { - { - "/dev/tty0", /* sDeviceName */ - SERIAL_NS16550, /* deviceType */ - COM_CONSOLE_FUNCTIONS, /* pDeviceFns */ - NULL, /* deviceProbe, assume it is there */ - NULL, /* pDeviceFlow */ - 16, /* ulMargin */ - 8, /* ulHysteresis */ - (void *) 9600, /* Baud Rate */ /* pDeviceParams */ - COM1_BASE_IO, /* ulCtrlPort1 */ - 0x00000000, /* ulCtrlPort2 */ - COM1_BASE_IO, /* ulDataPort */ - com_get_register, /* getRegister */ - com_set_register, /* setRegister */ - NULL,/* unused */ /* getData */ - NULL,/* unused */ /* setData */ - CLOCK_RATE, /* ulClock */ - MALTA_IRQ_TTY0 /* ulIntVector -- base for port */ - }, - { - "/dev/tty1", /* sDeviceName */ - SERIAL_NS16550, /* deviceType */ - COM_CONSOLE_FUNCTIONS, /* pDeviceFns */ - NULL, /* deviceProbe, assume it is there */ - NULL, /* pDeviceFlow */ - 16, /* ulMargin */ - 8, /* ulHysteresis */ - (void *) 9600, /* Baud Rate */ /* pDeviceParams */ - COM2_BASE_IO, /* ulCtrlPort1 */ - 0x00000000, /* ulCtrlPort2 */ - COM2_BASE_IO, /* ulDataPort */ - com_get_register, /* getRegister */ - com_set_register, /* setRegister */ - NULL,/* unused */ /* getData */ - NULL,/* unused */ /* setData */ - CLOCK_RATE, /* ulClock */ - MALTA_IRQ_TTY1 /* ulIntVector -- base for port */ - }, - { - "/dev/tty2", /* sDeviceName */ - SERIAL_NS16550, /* deviceType */ - COM_CONSOLE_FUNCTIONS, /* pDeviceFns */ - NULL, /* deviceProbe, assume it is there */ - NULL, /* pDeviceFlow */ - 16, /* ulMargin */ - 8, /* ulHysteresis */ - (void *) 9600, /* Baud Rate */ /* pDeviceParams */ - 0, /* IGNORED */ /* ulCtrlPort1 */ - 0, /* IGNORED */ /* ulCtrlPort2 */ - 0, /* IGNORED */ /* ulDataPort */ - tty2_get_register, /* getRegister */ - tty2_set_register, /* setRegister */ - NULL,/* unused */ /* getData */ - NULL,/* unused */ /* setData */ - CLOCK_RATE, /* ulClock */ - MALTA_CPU_INT2 /* ulIntVector -- base for port */ - }, -}; - -/* - * Define a variable that contains the number of statically configured - * console devices. - */ -unsigned long Console_Configuration_Count = \ - (sizeof(Console_Configuration_Ports)/sizeof(console_tbl)); diff --git a/c/src/lib/libbsp/mips/malta/console/printk_support.c b/c/src/lib/libbsp/mips/malta/console/printk_support.c deleted file mode 100644 index e548485222..0000000000 --- a/c/src/lib/libbsp/mips/malta/console/printk_support.c +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @file - * - * This file contains a stub for the required printk support. - */ - -/* - * COPYRIGHT (c) 1989-2012. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include - -rtems_device_minor_number BSPPrintkPort = 0; - -void BSP_com_outch(char ch); -int BSP_com_inch( void ); - -/* - * Following assume all are ns16650 - */ -void BSP_com_outch(char ch) -{ - console_tbl *cptr; - - cptr = &Console_Configuration_Ports[BSPPrintkPort]; - - return ns16550_outch_polled( cptr, ch ); -} - -int BSP_com_inch( void ) -{ - int result; - console_tbl *cptr; - - cptr = &Console_Configuration_Ports[BSPPrintkPort]; - - do { - result = ns16550_inch_polled( cptr ); - } while (result == -1); - - return result; -} - -BSP_output_char_function_type BSP_output_char = BSP_com_outch; -BSP_polling_getchar_function_type BSP_poll_char = BSP_com_inch; diff --git a/c/src/lib/libbsp/mips/rbtx4925/Makefile.am b/c/src/lib/libbsp/mips/rbtx4925/Makefile.am index fbf3027670..76b2ef77d1 100644 --- a/c/src/lib/libbsp/mips/rbtx4925/Makefile.am +++ b/c/src/lib/libbsp/mips/rbtx4925/Makefile.am @@ -33,7 +33,7 @@ librtemsbsp_a_SOURCES += ../shared/irq/exception.S # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/mips/rbtx4925/clock/clockdrv.c # console -librtemsbsp_a_SOURCES += console/console-io.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/mips/rbtx4925/console/console-io.c # liblnk librtemsbsp_a_SOURCES += ../shared/liblnk/lnklib.S librtemsbsp_a_SOURCES += ../shared/liblnk/pmon.S diff --git a/c/src/lib/libbsp/mips/rbtx4925/console/console-io.c b/c/src/lib/libbsp/mips/rbtx4925/console/console-io.c deleted file mode 100644 index 75cca1ebbd..0000000000 --- a/c/src/lib/libbsp/mips/rbtx4925/console/console-io.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * This file contains the RBTX4925 console IO package. - */ - -/* - * Author: Craig Lebakken - * - * COPYRIGHT (c) 1996 by Transition Networks Inc. - * - * To anyone who acknowledges that this file is provided "AS IS" - * without any express or implied warranty: - * permission to use, copy, modify, and distribute this file - * for any purpose is hereby granted without fee, provided that - * the above copyright notice and this notice appears in all - * copies, and that the name of Transition Networks not be used in - * advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * Transition Networks makes no representations about the suitability - * of this software for any purpose. - * - * Derived from c/src/lib/libbsp/no_cpu/no_bsp/console/console.c: - * - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include -#include - -/* PMON entry points */ -int mon_read(int fd, char *buf, int cnt); /* stdin is fd=0 */ -int mon_write(int fd, char *buf, int cnt); /* stdout is fd=1 */ - -/* console_initialize - * - * This routine initializes the console IO driver. - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - - status = rtems_io_register_name( - "/dev/console", - major, - (rtems_device_minor_number) 0 - ); - - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - return RTEMS_SUCCESSFUL; -} - -/* inbyte - * - * This routine reads a character from the SOURCE. - */ -static char inbyte( void ) -{ - char buf[10]; - - /* - * If polling, wait until a character is available. - */ - - mon_read(0, buf, 1); /* stdin is fd=0, read 1 byte */ - - return (buf[0]); -} - -/* outbyte - * - * This routine transmits a character out the SOURCE. It may support - * XON/XOFF flow control. - */ -static void outbyte( - char ch -) -{ - char buf[10]; - - /* - * If polling, wait for the transmitter to be ready. - * Check for flow control requests and process. - * Then output the character. - */ - buf[0] = ch; - - mon_write( 1, buf, 1 ); /* stdout is fd=1, write 1 byte */ -} - -/* - * Open entry point - */ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * Close entry point - */ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * read bytes from the serial port. We only have stdin. - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args; - char *buffer; - int maximum; - int count = 0; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - for (count = 0; count < maximum; count++) { - buffer[ count ] = inbyte(); - if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { - buffer[ count++ ] = '\n'; - break; - } - } - - rw_args->bytes_moved = count; - return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; -} - -/* - * write bytes to the serial port. Stdout and stderr are the same. - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - int count; - int maximum; - rtems_libio_rw_args_t *rw_args; - char *buffer; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - for (count = 0; count < maximum; count++) { - if ( buffer[ count ] == '\n') { - outbyte('\r'); - } - outbyte( buffer[ count ] ); - } - - rw_args->bytes_moved = maximum; - return 0; -} - -/* - * IO Control entry point - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -#include - -static void RBTX4925_output_char(char c) { outbyte( c ); } - -BSP_output_char_function_type BSP_output_char = RBTX4925_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - diff --git a/c/src/lib/libbsp/mips/rbtx4938/Makefile.am b/c/src/lib/libbsp/mips/rbtx4938/Makefile.am index 6061fe10df..6af4ffc71d 100644 --- a/c/src/lib/libbsp/mips/rbtx4938/Makefile.am +++ b/c/src/lib/libbsp/mips/rbtx4938/Makefile.am @@ -34,7 +34,7 @@ librtemsbsp_a_SOURCES += ../shared/irq/exception.S # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/mips/rbtx4938/clock/clockdrv.c # console -librtemsbsp_a_SOURCES += console/console-io.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/mips/rbtx4938/console/console-io.c # liblnk librtemsbsp_a_SOURCES += ../shared/liblnk/lnklib.S librtemsbsp_a_SOURCES += ../shared/liblnk/pmon.S diff --git a/c/src/lib/libbsp/mips/rbtx4938/console/console-io.c b/c/src/lib/libbsp/mips/rbtx4938/console/console-io.c deleted file mode 100644 index b0dbc3b365..0000000000 --- a/c/src/lib/libbsp/mips/rbtx4938/console/console-io.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * This file contains the RBTX4938 console IO package. - */ - -/* - * Author: Craig Lebakken - * - * COPYRIGHT (c) 1996 by Transition Networks Inc. - * - * To anyone who acknowledges that this file is provided "AS IS" - * without any express or implied warranty: - * permission to use, copy, modify, and distribute this file - * for any purpose is hereby granted without fee, provided that - * the above copyright notice and this notice appears in all - * copies, and that the name of Transition Networks not be used in - * advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * Transition Networks makes no representations about the suitability - * of this software for any purpose. - * - * Derived from c/src/lib/libbsp/no_cpu/no_bsp/console/console.c: - * - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include -#include - -#include "yamon_api.h" - -/* PMON entry points */ -int mon_read(int fd, char *buf, int cnt); /* stdin is fd=0 */ -int mon_write(int fd, char *buf, int cnt); /* stdout is fd=1 */ - - -/* console_initialize - * - * This routine initializes the console IO driver. - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - - status = rtems_io_register_name( - "/dev/console", - major, - (rtems_device_minor_number) 0 - ); - - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - return RTEMS_SUCCESSFUL; -} - -/* inbyte - * - * This routine reads a character from the SOURCE. - */ -static char inbyte( void ) -{ - char buf[10]; - - /* - * If polling, wait until a character is available. - */ - while (YAMON_FUNC_GETCHAR(buf) == YAMON_FALSE); - - return (buf[0]); -} - -/* outbyte - * - * This routine transmits a character out the SOURCE. It may support - * XON/XOFF flow control. - */ -static void outbyte( - char ch -) -{ - char buf[10]; - - /* - * If polling, wait for the transmitter to be ready. - * Check for flow control requests and process. - * Then output the character. - */ - buf[0] = ch; - - YAMON_FUNC_PRINT_COUNT(buf,1); -} - -/* - * Open entry point - */ - -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * Close entry point - */ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * read bytes from the serial port. We only have stdin. - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args; - char *buffer; - int maximum; - int count = 0; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - for (count = 0; count < maximum; count++) { - buffer[ count ] = inbyte(); - if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { - buffer[ count++ ] = '\n'; - break; - } - } - - rw_args->bytes_moved = count; - return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; -} - -/* - * write bytes to the serial port. Stdout and stderr are the same. - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - int count; - int maximum; - rtems_libio_rw_args_t *rw_args; - char *buffer; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - for (count = 0; count < maximum; count++) { - if ( buffer[ count ] == '\n') { - outbyte('\r'); - } - outbyte( buffer[ count ] ); - } - - rw_args->bytes_moved = maximum; - return 0; -} - -/* - * IO Control entry point - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -#include - -static void RBTX4938_output_char(char c) { outbyte( c ); } - -BSP_output_char_function_type BSP_output_char = RBTX4938_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - diff --git a/c/src/lib/libbsp/mips/rbtx4938/console/yamon_api.h b/c/src/lib/libbsp/mips/rbtx4938/console/yamon_api.h deleted file mode 100644 index 529cf16a3f..0000000000 --- a/c/src/lib/libbsp/mips/rbtx4938/console/yamon_api.h +++ /dev/null @@ -1,631 +0,0 @@ -/************************************************************************ - * - * yamon_api.h - * - * YAMON interface definitions - * - * ###################################################################### - * - * mips_start_of_legal_notice - * - * Copyright (c) 2003 MIPS Technologies, Inc. All rights reserved. - * - * - * Unpublished rights (if any) reserved under the copyright laws of the - * United States of America and other countries. - * - * This code is proprietary to MIPS Technologies, Inc. ("MIPS - * Technologies"). Any copying, reproducing, modifying or use of this code - * (in whole or in part) that is not expressly permitted in writing by MIPS - * Technologies or an authorized third party is strictly prohibited. At a - * minimum, this code is protected under unfair competition and copyright - * laws. Violations thereof may result in criminal penalties and fines. - * - * MIPS Technologies reserves the right to change this code to improve - * function, design or otherwise. MIPS Technologies does not assume any - * liability arising out of the application or use of this code, or of any - * error or omission in such code. Any warranties, whether express, - * statutory, implied or otherwise, including but not limited to the implied - * warranties of merchantability or fitness for a particular purpose, are - * excluded. Except as expressly provided in any written license agreement - * from MIPS Technologies or an authorized third party, the furnishing of - * this code does not give recipient any license to any intellectual - * property rights, including any patent rights, that cover this code. - * - * This code shall not be exported or transferred for the purpose of - * reexporting in violation of any U.S. or non-U.S. regulation, treaty, - * Executive Order, law, statute, amendment or supplement thereto. - * - * This code constitutes one or more of the following: commercial computer - * software, commercial computer software documentation or other commercial - * items. If the user of this code, or any related documentation of any - * kind, including related technical data or manuals, is an agency, - * department, or other entity of the United States government - * ("Government"), the use, duplication, reproduction, release, - * modification, disclosure, or transfer of this code, or any related - * documentation of any kind, is restricted in accordance with Federal - * Acquisition Regulation 12.212 for civilian agencies and Defense Federal - * Acquisition Regulation Supplement 227.7202 for military agencies. The use - * of this code by the Government is further restricted in accordance with - * the terms of the license agreement(s) and/or applicable contract terms - * and conditions covering this code from MIPS Technologies or an authorized - * third party. - * - * - * mips_end_of_legal_notice - * - * - ************************************************************************/ - -#ifndef YAMON_API_H -#define YAMON_API_H - -/************************************************************************ - * Include files - ************************************************************************/ - - -/************************************************************************ - * Definitions -*************************************************************************/ - -/* Basic types */ - -typedef unsigned int t_yamon_uint32; -typedef unsigned short t_yamon_uint16; -typedef unsigned char t_yamon_uint8; -typedef signed int t_yamon_int32; -typedef signed short t_yamon_int16; -typedef signed char t_yamon_int8; - -typedef unsigned char t_yamon_bool; - -#define YAMON_FALSE 0 -#define YAMON_TRUE (!YAMON_FALSE) - -/* YAMON Environment variable */ -typedef struct -{ - char *name; - char *val; -} -t_yamon_env_var; - -/* Format of application function */ -typedef t_yamon_uint32 -(*t_yamon_appl_main)( - t_yamon_uint32 argc, /* Number of tokens in argv array */ - char **argv, /* Array of tokens (first is "go") */ - t_yamon_env_var *env, /* Array of env. variables */ - t_yamon_uint32 memsize ); /* Size of memory (byte count) */ - - -/* ID of YAMON configuration object */ -typedef t_yamon_uint32 t_yamon_syscon_id; - - -/* Number used by the exception registration functions in order to register - * a default ISR/ESR. - */ -#define YAMON_DEFAULT_HANDLER 0xfffffff0 - -/* Number used by the exception registration functions in order to register - * an EJTAG debug exception ESR. - */ -#define YAMON_DEFAULT_EJTAG_ESR 0xfffffff1 - -/* Registered Interrupt Service Routine (ISR) */ -typedef void (*t_yamon_isr)(void *data); - -/* Registered Exception Service Routine (ESR) */ -typedef void (*t_yamon_esr)(void); - -/* Entry point called by ESRs wishing to pass control back to YAMON */ -typedef void (*t_yamon_retfunc)(void); - -/* Handle used for deregistration of ISR/ESR */ -typedef void *t_yamon_ref; - - -/* YAMONE Vector table address */ -#define YAMON_FUNCTION_BASE 0x9fc00500 - -/* YAMON Vector table offsets */ -#define YAMON_FUNC_PRINT_COUNT_OFS 0x04 -#define YAMON_FUNC_EXIT_OFS 0x20 -#define YAMON_FUNC_FLUSH_CACHE_OFS 0x2C -#define YAMON_FUNC_PRINT_OFS 0x34 -#define YAMON_FUNC_REGISTER_CPU_ISR_OFS 0x38 -#define YAMON_FUNC_DEREGISTER_CPU_ISR_OFS 0x3c -#define YAMON_FUNC_REGISTER_IC_ISR_OFS 0x40 -#define YAMON_FUNC_DEREGISTER_IC_ISR_OFS 0x44 -#define YAMON_FUNC_REGISTER_ESR_OFS 0x48 -#define YAMON_FUNC_DEREGISTER_ESR_OFS 0x4c -#define YAMON_FUNC_GETCHAR_OFS 0x50 -#define YAMON_FUNC_SYSCON_READ_OFS 0x54 - -/* Macro for accessing YAMON function */ -#define YAMON_FUNC(ofs)\ - (*(t_yamon_uint32 *)(YAMON_FUNCTION_BASE + (ofs))) - - -/************************************************************************ - * Public variables - ************************************************************************/ - -/************************************************************************ - * Public functions - ************************************************************************/ - - -/************************************************************************ - * - * t_yamon_exit - * Description : - * ------------- - * - * Exit application and return to YAMON. - * - * Parameters : - * ------------ - * - * 'rc' (OUT) : Return code - * - * Return values : - * --------------- - * - * None (never returns) - * - ************************************************************************/ -typedef void -(*t_yamon_exit)( - t_yamon_uint32 rc ); /* Return code */ - -#define YAMON_FUNC_EXIT( rc )\ - ((t_yamon_exit)( YAMON_FUNC(YAMON_FUNC_EXIT_OFS) ))\ - ( rc ) - - -/************************************************************************ - * - * t_yamon_print - * Description : - * ------------- - * - * Print null-terminated string to tty0. - * - * Parameters : - * ------------ - * - * 'port' (OUT) : Ignored, always prints to tty0. Not included in macro. - * 's' (OUT) : String to print. - * - * Return values : - * --------------- - * - * None - * - ************************************************************************/ -typedef void -(*t_yamon_print)( - t_yamon_uint32 port, /* Output port (not used, always tty0) */ - const char *s ); /* String to output */ - -#define YAMON_FUNC_PRINT( s )\ - ((t_yamon_print)( YAMON_FUNC(YAMON_FUNC_PRINT_OFS) ))\ - ( 0, s ) - - -/************************************************************************ - * - * t_yamon_print_count - * Description : - * ------------- - * - * Print specified number of characters to tty0. - * - * Parameters : - * ------------ - * - * 'port' (OUT) : Ignored, always prints to tty0. Not included in macro. - * 's' (OUT) : Array of characters to print. - * 'count' (OUT) : Number of characters to print. - * - * Return values : - * --------------- - * - * None - * - ************************************************************************/ -typedef void -(*t_yamon_print_count)( - t_yamon_uint32 port, /* Output port (not used, always tty0 */ - char *s, /* String to output */ - t_yamon_uint32 count ); /* Number of characters to output */ - -#define YAMON_FUNC_PRINT_COUNT( s, count )\ - ((t_yamon_print_count)( YAMON_FUNC(YAMON_FUNC_PRINT_COUNT_OFS) ))\ - ( 0, s, count ) - - -/************************************************************************ - * - * t_yamon_getchar - * Description : - * ------------- - * - * Get character from tty0 if character is available. Function - * returns immediately if no character is available. - * - * Parameters : - * ------------ - * - * 'port' (OUT) : Ignored, always uses tty0. Not included in macro. - * 'ch' (OUT) : Character read (if available). - * - * Return values : - * --------------- - * - * YAMON_TRUE if character was available, else YAMON_FALSE. - * - ************************************************************************/ -typedef t_yamon_bool -(*t_yamon_getchar)( - t_yamon_uint32 port, /* Output port (not used, always tty0 */ - char *ch ); /* Character to output */ - -#define YAMON_FUNC_GETCHAR( ch )\ - ((t_yamon_getchar)( YAMON_FUNC(YAMON_FUNC_GETCHAR_OFS) ))\ - ( 0, ch ) - - -/************************************************************************ - * - * t_yamon_syscon_read - * Description : - * ------------- - * - * Read the value of system configuration object given by 'id'. - * - * See syscon_api.h in YAMON source distribution for further details - * on object IDs and error codes. - * - * Parameters : - * ------------ - * - * 'id' (IN) : Object id. - * 'param' (INOUT) : Buffer for object value. - * 'size' (IN) : Size of buffer (must match size of object). - * - * Return values : - * --------------- - * - * 0 : Returned parameter is valid. - * Other values indicate error. - * - ************************************************************************/ -typedef t_yamon_int32 -(*t_yamon_syscon_read)( - t_yamon_syscon_id id, /* Object ID */ - void *param, /* Buffer for object value */ - t_yamon_uint32 size); /* Buffer size (bytes) */ - -#define YAMON_FUNC_SYSCON_READ( id, param, size )\ - ((t_yamon_syscon_read)( YAMON_FUNC(YAMON_FUNC_SYSCON_READ_OFS) ))\ - ( id, param, size ) - - -/************************************************************************ - * - * t_yamon_flush_cache - * Description : - * ------------- - * - * Flush I-or D-cache - * - * Function performs "writeback and invalidate" operations on D-cache - * lines and "invalidate" operations on I-cache lines. - * - * Parameters : - * ------------ - * - * 'type' (IN) : Cache to be flushed. - * - * Return values : - * --------------- - * - * None - * - ************************************************************************/ -typedef void -(*t_yamon_flush_cache)( -#define YAMON_FLUSH_ICACHE 0 -#define YAMON_FLUSH_DCACHE 1 - t_yamon_uint32 type ); /* I- or D-cache indication */ - -#define YAMON_FUNC_FLUSH_CACHE( type )\ - ((t_yamon_flush_cache)( YAMON_FUNC(YAMON_FUNC_FLUSH_CACHE_OFS) ))\ - ( type ) - - -/************************************************************************ - * - * t_yamon_register_esr - * Description : - * ------------- - * - * Registers an exception handler, also known as an "Exception Service - * Routine" (ESR) for the specified exception. - * - * Two special exception IDs are defined : - * YAMON_DEFAULT_HANDLER used for a default ESR. - * YAMON_DEFAULT_EJTAG_ESR used for EJTAG exceptions. - * - * The default ESR is called if no other ESR is registered - * for an exception. If no default ESR is registered, a static - * (i.e. not registered) "super default" function is invoked. - * This function prints out the registers and halts. - * - * Deregistration of an ESR may be be done by calling this function - * with 'esr' set to NULL. - * An ESR can also be deregistered using the 'yamon_deregister_esr' - * function. - * - * An ESR may be registered even if a previously registered - * ESR has not been deregistered. In this case the previously - * registered ESR is lost. - * - * The ESR will get called with registers in the state they were - * when the exception occurred. This includes all CP0 registers and - * CPU registers $0..$31, except for k0,k1 ($26,$27). - * - * In case an ESR does not want to handle the exception, it may - * call the return function passed in the 'retfunc' parameter. - * - * Case 1 : 'retfunc' called by ESR registered for the - * INTERRUPT exception. - * - * We assume an application has registered this ESR and wants - * YAMON to process the (remaining) interrupts. - * - * Case 2 : 'retfunc' called by an ESR registered for a specific - * exception (not INTERRUPT). - * - * Default handling will be done. - * - * Case 3 : 'retfunc' is called by the ESR registered as default ESR. - * - * The exception will be handled as though no ESR is registered - * (i.e. the "super default" function is called). - * - * Parameters : - * ------------ - * - * 'exception' (IN) : Exception code - * or YAMON_DEFAULT_HANDLER for a default ESR - * or YAMON_DEFAULT_EJTAG_ESR for ejtag exceptions. - * 'esr' (IN) : Function pointer for ESR. - * 'ref' (OUT) : Handle used for deregistration of ESR. - * 'retfunc' (OUT) : Pointer to function pointer for the return - * function described above. - * - * Return values : - * --------------- - * - * 0 : Registration went well. - * Other values indicate error. - * - ************************************************************************/ -typedef t_yamon_int32 -(*t_yamon_register_esr)( - t_yamon_uint32 exception, /* Exception identification */ - t_yamon_esr esr, /* ESR to be registered */ - t_yamon_ref *ref, /* Handle for deregistration */ - t_yamon_retfunc *retfunc ); /* Return function */ - -#define YAMON_FUNC_REGISTER_ESR( exc, esr, ref, retfunc )\ - ((t_yamon_register_esr)( YAMON_FUNC(YAMON_FUNC_REGISTER_ESR_OFS) ))\ - ( exc, esr, ref, retfunc ) - - -/************************************************************************ - * - * t_yamon_deregister_esr - * Description : - * ------------- - * - * Deregisters ESR.. - * - * Parameters : - * ------------ - * - * 'ref' (IN) : Handle obtained when calling 'yamon_register_esr'. - * - * Return values : - * --------------- - * - * 0 : Deregistration went well. - * Other values indicate error. - * - ************************************************************************/ -typedef t_yamon_int32 -(*t_yamon_deregister_esr)( - t_yamon_ref ref ); /* Handle for deregistration */ - -#define YAMON_FUNC_DEREGISTER_ESR( ref )\ - ((t_yamon_deregister_esr)( YAMON_FUNC(YAMON_FUNC_DEREGISTER_ESR_OFS) ))\ - ( ref ) - - -/************************************************************************ - * - * t_yamon_register_cpu_isr - * Description : - * ------------- - * - * Registers an Interrupt Service Routine (ISR) for the specified - * CPU interrupt. - * The highest service priority is attached to HW-INT5, which is - * connected to the CPU-built-in CP0-timer. SW_INT0 gets the lowest - * service priority. During registration, the interrupt mask field - * in the CPU CP0-status register is updated to enable interrupts - * from the specified interrupt source. - * - * A special ID is defined : - * YAMON_DEFAULT_HANDLER used for a default ISR. - * - * The default ISR is called if no other ISR is registered - * for a CPU interrupt. - * - * Deregistration of the default ISR may be done by calling - * this function with 'isr' set to NULL. - * Also, a new default ISR may be registered even if a - * previously registered ISR has not been deregistered. - * ISRs for specific CPU interrupts must be deregistered using - * 'yamon_deregister_cpu_isr'. - * - * Parameters : - * ------------ - * - * 'cpu_int' (IN) : CPU interrupt (0..7) - * or YAMON_DEFAULT_HANDLER for a default ISR. - * 'isr' (IN) : Function pointer for ISR. - * 'data' (IN) : Data pointer (may be NULL). Will be passed to - * ISR when called. - * 'ref' (OUT) : Handle used for deregistration of ISR. - * - * Return values : - * --------------- - * - * 0 : Registration went well. - * Other values indicate error. - * - ************************************************************************/ -typedef t_yamon_int32 -(*t_yamon_register_cpu_isr)( - t_yamon_uint32 cpu_int, /* CPU interrupt (0..7) */ - t_yamon_isr isr, /* ISR to be registered */ - void *data, /* Data reference to be registered */ - t_yamon_ref *ref ); /* Handle for deregistration */ - -#define YAMON_FUNC_REGISTER_CPU_ISR( cpu_int, isr, data, ref )\ - ((t_yamon_register_cpu_isr)( YAMON_FUNC(YAMON_FUNC_REGISTER_CPU_ISR_OFS) ))\ - ( cpu_int, isr, data, ref ) - - -/************************************************************************ - * - * t_yamon_deregister_cpu_isr - * Description : - * ------------- - * - * Deregisters ISR for CPU interrupt. - * - * Parameters : - * ------------ - * - * 'ref' (IN) : Handle obtained when calling 'yamon_register_cpu_isr'. - * - * Return values : - * --------------- - * - * 0 : Deregistration went well. - * Other values indicate error - * - ************************************************************************/ -typedef t_yamon_int32 -(*t_yamon_deregister_cpu_isr)( - t_yamon_ref ref ); /* Handle for deregistration */ - -#define YAMON_FUNC_DEREGISTER_CPU_ISR( ref )\ - ((t_yamon_deregister_cpu_isr)( YAMON_FUNC(YAMON_FUNC_DEREGISTER_CPU_ISR_OFS) ))\ - ( ref ) - - -/************************************************************************ - * - * t_yamon_register_ic_isr - * Description : - * ------------- - * - * Registers an Interrupt Service Routine (ISR) for the specified - * source in the interrupt controller. - * - * A special ID is defined : - * YAMON_DEFAULT_HANDLER used for a default ISR. - * - * The default ISR is called if no other ISR is registered - * for an interrupt. - * - * Deregistration of the default ISR may be done by calling - * this function with 'isr' set to NULL. - * Also, a new default ISR may be registered even if a - * previously registered ISR has not been deregistered. - * ISRs for specific interrupts must be deregistered using - * 'yamon_deregister_ic_isr'. - * - * Parameters : - * ------------ - * - * 'ic_line' (IN) : Interrupt source line in Int. Controller - * or YAMON_DEFAULT_HANDLER for a default ISR. - * 'isr', (IN) : Function pointer for user defined ISR. - * 'data' (IN) : Data pointer (may be NULL). Will be passed to - * ISR when called. - * 'ref', (OUT) : Handle used for deregistration of ISR. - * - * Return values : - * --------------- - * - * 0 : Registration went well. - * Other values indicate error. - * - ************************************************************************/ -typedef t_yamon_int32 -(*t_yamon_register_ic_isr)( - t_yamon_uint32 ic_line, /* Interrupt controller line */ - t_yamon_isr isr, /* ISR to be registered */ - void *data, /* Data reference to be registered */ - t_yamon_ref *ref ); /* Handle for deregistration */ - -#define YAMON_FUNC_REGISTER_IC_ISR( ic_line, isr, data, ref )\ - ((t_yamon_register_ic_isr)( YAMON_FUNC(YAMON_FUNC_REGISTER_IC_ISR_OFS) ))\ - ( ic_line, isr, data, ref ) - - -/************************************************************************ - * - * t_yamon_deregister_ic_isr - * Description : - * ------------- - * - * Deregisters ISR for source in interrupt controller. - * - * Parameters : - * ------------ - * - * 'ref' (IN) : Handle obtained when calling 'yamon_register_ic_isr'. - * - * Return values : - * --------------- - * - * 0 : Deregistration went well. - * Other values indicate error - * - ************************************************************************/ -typedef t_yamon_int32 -(*t_yamon_deregister_ic_isr)( - t_yamon_ref ref ); /* Handle for deregistration */ - -#define YAMON_FUNC_DEREGISTER_IC_ISR( ref )\ - ((t_yamon_deregister_ic_isr)( YAMON_FUNC(YAMON_FUNC_DEREGISTER_IC_ISR_OFS) ))\ - ( ref ) - - -#endif /* #ifndef YAMON_API_H */ - - - - - - diff --git a/c/src/lib/libbsp/moxie/moxiesim/Makefile.am b/c/src/lib/libbsp/moxie/moxiesim/Makefile.am index cf68a64180..16ce5b6d5e 100644 --- a/c/src/lib/libbsp/moxie/moxiesim/Makefile.am +++ b/c/src/lib/libbsp/moxie/moxiesim/Makefile.am @@ -30,9 +30,9 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c # clock librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/clock/clock-simidle.c # console -librtemsbsp_a_SOURCES += ../../shared/console-polled.c -librtemsbsp_a_SOURCES += console/console-io.c -librtemsbsp_a_SOURCES += console/syscalls.S +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-polled.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/moxie/moxiesim/console/console-io.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/moxie/moxiesim/console/syscalls.S # timer librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/btimer/btimer-stub.c diff --git a/c/src/lib/libbsp/moxie/moxiesim/console/console-io.c b/c/src/lib/libbsp/moxie/moxiesim/console/console-io.c deleted file mode 100644 index de058eba8b..0000000000 --- a/c/src/lib/libbsp/moxie/moxiesim/console/console-io.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * This file contains the hardware specific portions of the TTY driver - * for the Moxie GDB simulator. - */ - -/* - * COPYRIGHT (c) 2011. - * Anthony Green. - * - * COPYRIGHT (c) 1989-2008. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - */ - -#include -#include -#include -#include -#include - -/* - * console_initialize_hardware - * - * This routine initializes the console hardware. - * - */ - -void console_initialize_hardware(void) -{ - return; -} - -/* - * console_outbyte_polled - * - * This routine transmits a character using polling. - */ -ssize_t _sys_write(int fd, const void *buf, size_t count); -void console_outbyte_polled( - int port, - char ch -) -{ - _sys_write( 1, &ch, 1 ); -} - -/* - * console_inbyte_nonblocking - * - * This routine polls for a character. - */ - -int console_inbyte_nonblocking( - int port -) -{ - return -1; -} - -#include - -static void moxiesim_output_char(char c) { console_outbyte_polled( 0, c ); } - -BSP_output_char_function_type BSP_output_char = moxiesim_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/moxie/moxiesim/console/syscalls.S b/c/src/lib/libbsp/moxie/moxiesim/console/syscalls.S deleted file mode 100644 index f9a63a29b5..0000000000 --- a/c/src/lib/libbsp/moxie/moxiesim/console/syscalls.S +++ /dev/null @@ -1,15 +0,0 @@ -/* - * System call support for simulator in gdb. - * - * COPYRIGHT (c) 2011 Anthony Green - */ - -#define SYS_write 5 - - .section .text - .align 2 - .global _sys_write -_sys_write: - swi SYS_write - ret - .end diff --git a/c/src/lib/libbsp/nios2/nios2_iss/Makefile.am b/c/src/lib/libbsp/nios2/nios2_iss/Makefile.am index c05ddd151f..2fe8023b42 100644 --- a/c/src/lib/libbsp/nios2/nios2_iss/Makefile.am +++ b/c/src/lib/libbsp/nios2/nios2_iss/Makefile.am @@ -31,8 +31,8 @@ librtemsbsp_a_SOURCES += startup/setvec.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/nios2/nios2_iss/clock/clock.c # console -librtemsbsp_a_SOURCES += console/console.c -librtemsbsp_a_SOURCES += ../../shared/console-polled.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/nios2/nios2_iss/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-polled.c # timer librtemsbsp_a_SOURCES += timer/timer.c diff --git a/c/src/lib/libbsp/nios2/nios2_iss/console/console.c b/c/src/lib/libbsp/nios2/nios2_iss/console/console.c deleted file mode 100644 index 9197c6486c..0000000000 --- a/c/src/lib/libbsp/nios2/nios2_iss/console/console.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * This file implements simple console IO via JTAG UART. - */ - -/* - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * Altera-specific code is - * COPYRIGHT (c) 2005-2006 Kolja Waschk, rtemsdev/ixo.de - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#define NO_BSP_INIT - -#include -#include -#include - -/* #define JTAG_UART_REGS \ - ((altera_avalon_jtag_uart_regs*)NIOS2_IO_BASE(JTAG_UART_BASE)) */ - -/* is_character_ready - * - * If a character is available, this routine reads it and stores - * it in reads the character and stores - */ -static bool is_character_ready( - char *ch -) -{ - altera_avalon_jtag_uart_regs *ajur = NIOS2_IO_BASE(JTAG_UART_BASE); - unsigned int data = ajur->data; - - if (data & ALTERA_AVALON_JTAG_UART_DATA_RVALID_MSK) { - *ch = (data & ALTERA_AVALON_JTAG_UART_DATA_DATA_MSK) - >> ALTERA_AVALON_JTAG_UART_DATA_DATA_OFST; - return true; - } - - return false; -} - -void console_initialize_hardware(void) -{ -} - -/* - * This routine reads a character from the SOURCE. - */ -int console_inbyte_nonblocking( - int port -) -{ - char ch; - - /* - * Wait until a character is available. - */ - if (is_character_ready(&ch)) - return ch; - return -1; -} - -/* - * This routine transmits a character out the SOURCE. - */ -void console_outbyte_polled( - int port, - char ch -) -{ - altera_avalon_jtag_uart_regs *ajur = NIOS2_IO_BASE(JTAG_UART_BASE); - - /* - * Wait for the transmitter to be ready. - * Check for flow control requests and process. - * Then output the character. - */ - while ((ajur->control & ALTERA_AVALON_JTAG_UART_CONTROL_WSPACE_MSK) == 0); - - ajur->data = ch; -} - -/* - * To support printk - */ - -#include - -static void ISS_output_char(char c) { console_outbyte_polled( 0, c ); } - -BSP_output_char_function_type BSP_output_char = ISS_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/Makefile.am b/c/src/lib/libbsp/no_cpu/no_bsp/Makefile.am index 6ce91f2d65..8b2b05c7e2 100644 --- a/c/src/lib/libbsp/no_cpu/no_bsp/Makefile.am +++ b/c/src/lib/libbsp/no_cpu/no_bsp/Makefile.am @@ -23,7 +23,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/no_cpu/no_bsp/clock/ckinit.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/no_cpu/no_bsp/console/console.c # timer librtemsbsp_a_SOURCES += timer/timer.c librtemsbsp_a_SOURCES += timer/timerisr.c diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/console/console.c b/c/src/lib/libbsp/no_cpu/no_bsp/console/console.c deleted file mode 100644 index 41c17c29ef..0000000000 --- a/c/src/lib/libbsp/no_cpu/no_bsp/console/console.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * This file contains the template for a console IO package. - * - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#define NO_BSP_INIT - -#include -#include - -/* console_initialize - * - * This routine initializes the console IO driver. - * - * Input parameters: NONE - * - * Output parameters: NONE - * - * Return values: - */ - -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - - status = rtems_io_register_name( - "/dev/console", - major, - (rtems_device_minor_number) 0 - ); - - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - return RTEMS_SUCCESSFUL; -} - -/* is_character_ready - * - * This routine returns TRUE if a character is available. - * - * Input parameters: NONE - * - * Output parameters: NONE - * - * Return values: - */ - -bool is_character_ready( - char *ch -) -{ - *ch = '\0'; /* return NULL for no particular reason */ - return true; -} - -/* inbyte - * - * This routine reads a character from the SOURCE. - * - * Input parameters: NONE - * - * Output parameters: NONE - * - * Return values: - * character read from SOURCE - */ - -char inbyte( void ) -{ - /* - * If polling, wait until a character is available. - */ - - return '\0'; -} - -/* outbyte - * - * This routine transmits a character out the SOURCE. It may support - * XON/XOFF flow control. - * - * Input parameters: - * ch - character to be transmitted - * - * Output parameters: NONE - */ - -void outbyte( - char ch -) -{ - /* - * If polling, wait for the transmitter to be ready. - * Check for flow control requests and process. - * Then output the character. - */ - - /* - * Carriage Return/New line translation. - */ - - if ( ch == '\n' ) - outbyte( '\r' ); -} - -/* - * Open entry point - */ - -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * Close entry point - */ - -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} - -/* - * read bytes from the serial port. We only have stdin. - */ - -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args; - char *buffer; - int maximum; - int count = 0; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - for (count = 0; count < maximum; count++) { - buffer[ count ] = inbyte(); - if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { - buffer[ count++ ] = '\n'; - break; - } - } - - rw_args->bytes_moved = count; - return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; -} - -/* - * write bytes to the serial port. Stdout and stderr are the same. - */ - -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - int count; - int maximum; - rtems_libio_rw_args_t *rw_args; - char *buffer; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - for (count = 0; count < maximum; count++) { - if ( buffer[ count ] == '\n') { - outbyte('\r'); - } - outbyte( buffer[ count ] ); - } - - rw_args->bytes_moved = maximum; - return 0; -} - -/* - * IO Control entry point - */ - -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/lib/libbsp/or1k/generic_or1k/Makefile.am b/c/src/lib/libbsp/or1k/generic_or1k/Makefile.am index 4f1fbe083b..dd8b7a5c75 100644 --- a/c/src/lib/libbsp/or1k/generic_or1k/Makefile.am +++ b/c/src/lib/libbsp/or1k/generic_or1k/Makefile.am @@ -51,8 +51,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/stackalloc.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c -librtemsbsp_a_SOURCES += console/console-config.c -librtemsbsp_a_SOURCES += console/uart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/or1k/generic_or1k/console/console-config.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/or1k/generic_or1k/console/uart.c # Timer librtemsbsp_a_SOURCES += timer/timer.c diff --git a/c/src/lib/libbsp/or1k/generic_or1k/console/console-config.c b/c/src/lib/libbsp/or1k/generic_or1k/console/console-config.c deleted file mode 100644 index 5fc75dcf0c..0000000000 --- a/c/src/lib/libbsp/or1k/generic_or1k/console/console-config.c +++ /dev/null @@ -1,55 +0,0 @@ -/** - * @file - * - * @ingroup generic_or1k_uart - * - * @brief Console Configuration. - */ - -/* - * Copyright (c) 2014-2015 Hesham ALMatary - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE - */ - -#include - -#include - -#include -#include -#include - -console_tbl Console_Configuration_Ports [] = { - { - .sDeviceName = "/dev/ttyS0", - .deviceType = SERIAL_CUSTOM, - .pDeviceFns = &generic_or1k_uart_fns, - .deviceProbe = NULL, - .pDeviceFlow = NULL, - .ulCtrlPort1 = OR1K_BSP_UART_BASE, - .ulCtrlPort2 = 0, - .ulClock = OR1K_UART_DEFAULT_BAUD, - .ulIntVector = OR1K_BSP_UART_IRQ - } -}; - -#define PORT_COUNT \ - (sizeof(Console_Configuration_Ports) \ - / sizeof(Console_Configuration_Ports [0])) - -unsigned long Console_Configuration_Count = PORT_COUNT; - -static void output_char(char c) -{ - const console_fns *con = - Console_Configuration_Ports [Console_Port_Minor].pDeviceFns; - - con->deviceWritePolled((int) Console_Port_Minor, c); -} - -BSP_output_char_function_type BSP_output_char = output_char; - -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/or1k/generic_or1k/console/uart.c b/c/src/lib/libbsp/or1k/generic_or1k/console/uart.c deleted file mode 100644 index 6f8a49443d..0000000000 --- a/c/src/lib/libbsp/or1k/generic_or1k/console/uart.c +++ /dev/null @@ -1,152 +0,0 @@ -/** - * @file - * - * @ingroup generic_or1k_uart - * - * @brief UART support. - */ - -/* - * COPYRIGHT (c) 2014-2015 Hesham ALMatary - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE - */ - -#include -#include -#include -#include -#include -#include - -static void uart_initialize(int minor); -static int uart_first_open(int major, int minor, void *arg); -static int uart_last_close(int major, int minor, void *arg); -static int uart_read_polled(int minor); -static ssize_t uart_write(int minor, const char *buf, size_t len); -static void uart_write_polled(int minor, char c); -static int uart_set_attributes(int minor, const struct termios *t); - -#if 0 -/* - * These will be useful when the driver supports interrupt driven IO. - */ -static rtems_vector_number uart_get_irq_number(const console_tbl *ct) -{ - return ct->ulIntVector; -} - -static uint32_t uart_get_baud(const console_tbl *ct) -{ - return ct->ulClock; -} -#endif - -static void uart_set_baud(int baud) -{ - uint16_t divisor = (OR1K_BSP_CLOCK_FREQ) / (16 * baud); - OR1K_REG(OR1K_BSP_UART_REG_LINE_CTRL) = - OR1K_BSP_UART_REG_LINE_CTRL_DLAB; - - OR1K_REG(OR1K_BSP_UART_REG_DEV_LATCH_LOW) = divisor & 0xff; - - OR1K_REG(OR1K_BSP_UART_REG_DEV_LATCH_HIGH) = - (divisor >> 8); -} - -static void uart_initialize(int minor) -{ - /* Set baud rate */ - uart_set_baud(OR1K_UART_DEFAULT_BAUD); - - /* Set data pattern configuration */ - OR1K_REG(OR1K_BSP_UART_REG_LINE_CTRL) = - OR1K_BSP_UART_REG_LINE_CTRL_WLEN8; - - /* Reset receiver and transmitter */ - OR1K_REG(OR1K_BSP_UART_REG_FIFO_CTRL) = - OR1K_BSP_UART_REG_FIFO_CTRL_ENABLE_FIFO | - OR1K_BSP_UART_REG_FIFO_CTRL_CLEAR_RCVR | - OR1K_BSP_UART_REG_FIFO_CTRL_TRIGGER_14; - - /* Disable all interrupts */ - OR1K_REG(OR1K_BSP_UART_REG_INT_ENABLE) = 0x00; - -} - -static int uart_first_open(int major, int minor, void *arg) -{ - rtems_libio_open_close_args_t *oc = (rtems_libio_open_close_args_t *) arg; - struct rtems_termios_tty *tty = (struct rtems_termios_tty *) oc->iop->data1; - const console_tbl *ct = Console_Port_Tbl [minor]; - console_data *cd = &Console_Port_Data [minor]; - - cd->termios_data = tty; - rtems_termios_set_initial_baud(tty, ct->ulClock); - - return 0; -} - -static int uart_last_close(int major, int minor, void *arg) -{ - return 0; -} - -static int uart_read_polled(int minor) -{ - unsigned char lsr; - - /* Get a character when avaiable */ - do { - lsr = OR1K_REG(OR1K_BSP_UART_REG_LINE_STATUS); - } while ((lsr & OR1K_BSP_UART_REG_LINE_STATUS_DR) - != OR1K_BSP_UART_REG_LINE_STATUS_DR); - - return OR1K_REG(OR1K_BSP_UART_REG_RX); -} - -static void uart_write_polled(int minor, char c) -{ - unsigned char lsr; - - /* Wait until there is no pending data in the transmitter FIFO (empty) */ - do { - lsr = OR1K_REG(OR1K_BSP_UART_REG_LINE_STATUS); - } while (!(lsr & OR1K_BSP_UART_REG_LINE_STATUS_THRE)); - - OR1K_REG(OR1K_BSP_UART_REG_TX) = c; -} - -static ssize_t uart_write( - int minor, - const char *s, - size_t n -) -{ - ssize_t i = 0; - - for (i = 0; i < n; ++i){ - uart_write_polled(minor, s [i]); - } - - return n; -} - -static int uart_set_attributes(int minor, const struct termios *term) -{ - return -1; -} - -const console_fns generic_or1k_uart_fns = { - .deviceProbe = libchip_serial_default_probe, - .deviceFirstOpen = uart_first_open, - .deviceLastClose = uart_last_close, - .deviceRead = uart_read_polled, - .deviceWrite = uart_write, - .deviceInitialize = uart_initialize, - .deviceWritePolled = uart_write_polled, - .deviceSetAttributes = uart_set_attributes, - .deviceOutputUsesInterrupts = false -}; diff --git a/c/src/lib/libbsp/powerpc/beatnik/Makefile.am b/c/src/lib/libbsp/powerpc/beatnik/Makefile.am index 97219cc82b..bb295f3a80 100644 --- a/c/src/lib/libbsp/powerpc/beatnik/Makefile.am +++ b/c/src/lib/libbsp/powerpc/beatnik/Makefile.am @@ -58,8 +58,8 @@ librtemsbsp_a_SOURCES += startup/bspclean.c librtemsbsp_a_SOURCES +=../../../../../../bsps/powerpc/shared/clock/p_clock.c #console -librtemsbsp_a_SOURCES += ../shared/console/uart.c -librtemsbsp_a_SOURCES += ../shared/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/console/uart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/console/console.c #irq librtemsbsp_a_SOURCES += irq/irq_init.c diff --git a/c/src/lib/libbsp/powerpc/gen5200/Makefile.am b/c/src/lib/libbsp/powerpc/gen5200/Makefile.am index 11d011fc34..2138ad053a 100644 --- a/c/src/lib/libbsp/powerpc/gen5200/Makefile.am +++ b/c/src/lib/libbsp/powerpc/gen5200/Makefile.am @@ -56,7 +56,7 @@ librtemsbsp_a_SOURCES += bestcomm/tasksetup_pci_tx.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/powerpc/shared/clock/clock.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/gen5200/console/console.c # i2c librtemsbsp_a_SOURCES += i2c/i2c.c librtemsbsp_a_SOURCES += i2c/i2cdrv.c diff --git a/c/src/lib/libbsp/powerpc/gen5200/console/console.c b/c/src/lib/libbsp/powerpc/gen5200/console/console.c deleted file mode 100644 index d7325032c4..0000000000 --- a/c/src/lib/libbsp/powerpc/gen5200/console/console.c +++ /dev/null @@ -1,835 +0,0 @@ -/*===============================================================*\ -| Project: RTEMS generic MPC5200 BSP | -+-----------------------------------------------------------------+ -| Partially based on the code references which are named below. | -| Adaptions, modifications, enhancements and any recent parts of | -| the code are: | -| Copyright (c) 2005 | -| Embedded Brains GmbH | -| Obere Lagerstr. 30 | -| D-82178 Puchheim | -| Germany | -| rtems@embedded-brains.de | -+-----------------------------------------------------------------+ -| The license and distribution terms for this file may be | -| found in the file LICENSE in this distribution or at | -| | -| http://www.rtems.org/license/LICENSE. | -| | -+-----------------------------------------------------------------+ -| this file contains the console driver functions | -\*===============================================================*/ -/***********************************************************************/ -/* */ -/* Module: console.c */ -/* Date: 07/17/2003 */ -/* Purpose: RTEMS MPC5x00 console driver */ -/* */ -/*---------------------------------------------------------------------*/ -/* */ -/* Description: */ -/* */ -/* The PSCs of mpc5200 are assigned as follows */ -/* */ -/* Channel Device Minor Note */ -/* PSC1 /dev/tty0 0 */ -/* PSC2 /dev/tty1 1 */ -/* PSC3 /dev/tty2 2 */ -/* */ -/*---------------------------------------------------------------------*/ -/* */ -/* Code */ -/* References: Serial driver for MPC8260ads */ -/* Module: console-generic.c */ -/* Project: RTEMS 4.6.0pre1 / MPC8260ads BSP */ -/* Version 1.3 */ -/* Date: 2002/11/04 */ -/* */ -/* Author(s) / Copyright(s): */ -/* */ -/* Author: Jay Monkman (jmonkman@frasca.com) */ -/* Copyright (C) 1998 by Frasca International, Inc. */ -/* */ -/* Derived from c/src/lib/libbsp/m68k/gen360/console/console.c */ -/* written by: */ -/* W. Eric Norum */ -/* Saskatchewan Accelerator Laboratory */ -/* University of Saskatchewan */ -/* Saskatoon, Saskatchewan, CANADA */ -/* eric@skatter.usask.ca */ -/* */ -/* COPYRIGHT (c) 1989-2008. */ -/* On-Line Applications Research Corporation (OAR). */ -/* */ -/* Modifications by Darlene Stewart */ -/* and Charles-Antoine Gauthier */ -/* Copyright (c) 1999, National Research Council of Canada */ -/* */ -/* Modifications by Andy Dachs to add MPC8260 */ -/* support. */ -/* Copyright (c) 2001, Surrey Satellite Technology Ltd */ -/* */ -/* The license and distribution terms for this file may be */ -/* found in the file LICENSE in this distribution or at */ -/* http://www.rtems.org/license/LICENSE. */ -/* */ -/*---------------------------------------------------------------------*/ -/* */ -/* Partially based on the code references which are named above. */ -/* Adaptions, modifications, enhancements and any recent parts of */ -/* the code are under the right of */ -/* */ -/* IPR Engineering, Dachauer Straße 38, D-80335 München */ -/* Copyright(C) 2003 */ -/* */ -/*---------------------------------------------------------------------*/ -/* */ -/* IPR Engineering makes no representation or warranties with */ -/* respect to the performance of this computer program, and */ -/* specifically disclaims any responsibility for any damages, */ -/* special or consequential, connected with the use of this program. */ -/* */ -/*---------------------------------------------------------------------*/ -/* */ -/* Version history: 1.0 */ -/* */ -/***********************************************************************/ - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - - -#define NUM_PORTS MPC5200_PSC_NO - -#define PSC1_MINOR 0 -#define PSC2_MINOR 1 -#define PSC3_MINOR 2 -#define PSC4_MINOR 3 -#define PSC5_MINOR 4 -#define PSC6_MINOR 5 - -uint32_t mpc5200_uart_avail_mask = BSP_UART_AVAIL_MASK; - -#if defined(UARTS_USE_TERMIOS_INT) - uint8_t psc_minor_to_irqname[NUM_PORTS] = { - BSP_SIU_IRQ_PSC1, - BSP_SIU_IRQ_PSC2, - BSP_SIU_IRQ_PSC3, - BSP_SIU_IRQ_PSC4, - BSP_SIU_IRQ_PSC5, - BSP_SIU_IRQ_PSC6 - }; - - static int mpc5200_psc_irqname_to_minor(int name) { - int minor; - uint8_t *chrptr; - - chrptr = memchr(psc_minor_to_irqname, name, sizeof(psc_minor_to_irqname)); - if (chrptr != NULL) { - minor = chrptr - psc_minor_to_irqname; - } else { - minor = -1; - } - return minor; - } -#endif - -static void A_BSP_output_char(char c); -static int A_BSP_get_char(void); -BSP_output_char_function_type BSP_output_char = A_BSP_output_char; - -BSP_polling_getchar_function_type BSP_poll_char = A_BSP_get_char; - -/* Used to handle premature outputs of printk */ -bool console_initialized = false; - -/* per channel info structure */ -struct per_channel_info { - uint16_t shadow_imr; - uint8_t shadow_mode1; - uint8_t shadow_mode2; - int cur_tx_len; - int rx_interrupts; - int tx_interrupts; - int rx_characters; - int tx_characters; - int breaks_detected; - int framing_errors; - int parity_errors; - int overrun_errors; -}; - -/* Used to handle more than one channel */ -struct per_channel_info channel_info[NUM_PORTS]; - -/* - * XXX: there are only 6 PSCs, but PSC6 has an extra register gap - * from PSC5, therefore we instantiate seven(!) PSC register sets - */ -uint8_t psc_minor_to_regset[MPC5200_PSC_NO] = {0,1,2,3,4,6}; - -/* Used to track termios private data for callbacks */ -struct rtems_termios_tty *ttyp[NUM_PORTS]; - -static int mpc5200_psc_setAttributes( - int minor, - const struct termios *t -) -{ - int baud; - uint8_t csize=0, cstopb, parenb, parodd; - struct mpc5200_psc *psc = - (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); - - /* Baud rate */ - baud = rtems_termios_baud_to_number(t->c_ospeed); - if (baud > 0) { - /* - * Calculate baud rate - * round divider to nearest! - */ - baud = (IPB_CLOCK + baud *16) / (baud * 32); - } - - /* Number of data bits */ - switch ( t->c_cflag & CSIZE ) { - case CS5: csize = 0x00; break; - case CS6: csize = 0x01; break; - case CS7: csize = 0x02; break; - case CS8: csize = 0x03; break; - } - - /* Stop bits */ - if(csize == 0) { - if(t->c_cflag & CSTOPB) - cstopb = 0x0F; /* Two stop bits */ - else - cstopb = 0x00; /* One stop bit */ - } else { - if(t->c_cflag & CSTOPB) - cstopb = 0x0F; /* Two stop bits */ - else - cstopb = 0x07; /* One stop bit */ - } - - /* Parity */ - if (t->c_cflag & PARENB) - parenb = 0x00; /* Parity enabled on Tx and Rx */ - else - parenb = 0x10; /* No parity on Tx and Rx */ - - if (t->c_cflag & PARODD) - parodd = 0x04; /* Odd parity */ - else - parodd = 0x00; - - /* - * Set upper timer counter - */ - psc->ctur = (uint8_t) (baud >> 8); - - /* - * Set lower timer counter - */ - psc->ctlr = (uint8_t) baud; - - /* - * Reset mode pointer - */ - psc->cr = ((1 << 4) << 8); - - /* - * Set mode1 register - */ - channel_info[minor].shadow_mode1 &= ~(0x1F); - psc->mr = channel_info[minor].shadow_mode1 | (csize | parenb | parodd); - - /* - * Set mode2 register - */ - channel_info[minor].shadow_mode2 &= ~(0x0F); - psc->mr = channel_info[minor].shadow_mode2 | cstopb; - - return 0; - -} - - -static int mpc5200_uart_setAttributes(int minor, const struct termios *t) -{ - /* - * Check that port number is valid - */ - if( (minor < PSC1_MINOR) || (minor > NUM_PORTS-1) ) - return 0; - - return mpc5200_psc_setAttributes(minor, t); - -} - -#ifdef UARTS_USE_TERMIOS_INT -/* - * Interrupt handlers - */ -static void mpc5200_psc_interrupt_handler(rtems_irq_hdl_param handle) -{ - unsigned char c; - uint16_t isr; - int minor = (int)handle; - struct mpc5200_psc *psc = - (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); - - /* - * get content of psc interrupt status - */ - isr = psc->isr_imr; - - /* - * Character received? - */ - if (isr & ISR_RX_RDY_FULL) { - - channel_info[minor].rx_interrupts++; - - -#ifndef SINGLE_CHAR_MODE - while(psc->rfnum) { -#endif - /* - * get the character - */ - c = (psc->rb_tb >> 24); - - if (ttyp[minor] != NULL) { - rtems_termios_enqueue_raw_characters( - (void *)ttyp[minor], (char *)&c, (int)1); - channel_info[minor].rx_characters++; - } - -#ifndef SINGLE_CHAR_MODE - } -#endif - - } - - /* - * Character transmitted ? - */ - if (isr & ISR_TX_RDY & channel_info[minor].shadow_imr) { - channel_info[minor].tx_interrupts++; - - if (ttyp[minor] != NULL) { - #ifndef SINGLE_CHAR_MODE - rtems_termios_dequeue_characters( - (void *)ttyp[minor], channel_info[minor].cur_tx_len); - channel_info[minor].tx_characters += channel_info[minor].cur_tx_len; - #else - rtems_termios_dequeue_characters((void *)ttyp[minor], (int)1); - channel_info[minor].tx_characters++; - #endif - } - } - - if(isr & ISR_ERROR) { - if(isr & ISR_RB) - channel_info[minor].breaks_detected++; - if(isr & ISR_FE) - channel_info[minor].framing_errors++; - if(isr & ISR_PE) - channel_info[minor].parity_errors++; - if(isr & ISR_OE) - channel_info[minor].overrun_errors++; - - /* - * Reset error status - */ - psc->cr = ((4 << 4) << 8); - } -} - -static void mpc5200_psc_enable( - const rtems_irq_connect_data* ptr -) -{ - struct mpc5200_psc *psc; - int minor = mpc5200_psc_irqname_to_minor(ptr->name); - - if (minor >= 0) { - psc = (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); - psc->isr_imr = channel_info[minor].shadow_imr |= - (IMR_RX_RDY_FULL | IMR_TX_RDY); - } -} - - -static void mpc5200_psc_disable( - const rtems_irq_connect_data* ptr -) -{ - struct mpc5200_psc *psc; - int minor = mpc5200_psc_irqname_to_minor(ptr->name); - - if (minor >= 0) { - psc = (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); - psc->isr_imr = channel_info[minor].shadow_imr &= - ~(IMR_RX_RDY_FULL | IMR_TX_RDY); - } -} - -static int mpc5200_psc_isOn( - const rtems_irq_connect_data* ptr -) -{ - struct mpc5200_psc *psc; - int minor = mpc5200_psc_irqname_to_minor(ptr->name); - - if (minor >= 0) { - psc = (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); - return ((psc->isr_imr & IMR_RX_RDY_FULL) & (psc->isr_imr & IMR_TX_RDY)); - } - return false; -} - - -static rtems_irq_connect_data consoleIrqData; -#endif - -static void mpc5200_uart_psc_initialize( - int minor -) -{ - uint32_t baud_divider; - struct mpc5200_psc *psc = - (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); - - /* - * Check that minor number is valid - */ - if ((minor < PSC1_MINOR) || (minor >= (PSC1_MINOR + NUM_PORTS))) - return; - - /* - * Clear per channel info - */ - memset((void *)&channel_info[minor], 0, sizeof(struct per_channel_info)); - - /* - * Reset receiver and transmitter - */ - psc->cr = ((2 << 4) << 8); - psc->cr = ((3 << 4) << 8); - - /* - * Reset mode pointer - */ - psc->cr = ((1 << 4) << 8); - - /* - * Set clock select register - */ - psc->sr_csr = 0; - - /* - * Set mode1 register - */ - psc->mr = channel_info[minor].shadow_mode1 = 0x33; /* 8Bit / no parity */ - - /* - * Set mode2 register - */ - psc->mr = channel_info[minor].shadow_mode2 = 7; /* 1 stop bit */ - - /* - * Set rx FIFO alarm - */ - psc->rfalarm = RX_FIFO_SIZE - 1; - - /* - * Set tx FIFO alarm - */ - psc->tfalarm = 1; - - baud_divider = - (IPB_CLOCK + GEN5200_CONSOLE_BAUD *16) / (GEN5200_CONSOLE_BAUD * 32); - - /* - * Set upper timer counter - */ - psc->ctur = baud_divider >> 16; - - /* - * Set lower timer counter - */ - - psc->ctlr = baud_divider & 0x0000ffff; - - /* - * Disable Frame mode / set granularity 0 - */ - psc->tfcntl = 0; - -#ifdef UARTS_USE_TERMIOS_INT - /* - * Tie interrupt dependent routines - */ - consoleIrqData.on = mpc5200_psc_enable; - consoleIrqData.off = mpc5200_psc_disable; - consoleIrqData.isOn = mpc5200_psc_isOn; - consoleIrqData.handle = (rtems_irq_hdl_param)minor; - consoleIrqData.hdl = (rtems_irq_hdl)mpc5200_psc_interrupt_handler; - - /* - * Tie interrupt handler - */ - consoleIrqData.name = psc_minor_to_irqname[minor]; - - /* - * Install rtems irq handler - */ - assert(BSP_install_rtems_irq_handler(&consoleIrqData) == 1); -#endif - - /* - * Reset rx fifo errors Error/UF/OF - */ - psc->rfstat |= 0x70; - - /* - * Reset tx fifo errors Error/UF/OF - */ - psc->tfstat |= 0x70; - -#ifdef UARTS_USE_TERMIOS_INT - /* - * Unmask receive interrupt - */ - psc->isr_imr = channel_info[minor].shadow_imr = IMR_RX_RDY_FULL; -#endif - - /* - * Enable receiver - */ - psc->cr = ((1 << 0) << 8); - - /* - * Enable transmitter - */ - psc->cr = ((1 << 2) << 8); -} - - -static int mpc5200_uart_pollRead( - int minor -) -{ - unsigned char c; - struct mpc5200_psc *psc = - (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); - - if (psc->sr_csr & (1 << 8)) - c = (psc->rb_tb >> 24); - else - return -1; - - return c; -} - - -static ssize_t mpc5200_uart_pollWrite( - int minor, - const char *buf, - size_t len -) -{ - size_t retval = len; - const char *tmp_buf = buf; - struct mpc5200_psc *psc = - (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); - - while(len--) { - while(!(psc->sr_csr & (1 << 11))) - continue; - - /*rtems_cache_flush_multiple_data_lines( (void *)buf, 1);*/ - - psc->rb_tb = (*tmp_buf << 24); - - tmp_buf++; - - } - return retval; - -} - -static ssize_t mpc5200_uart_write( - int minor, - const char *buf, - size_t len -) -{ - struct mpc5200_psc *psc = - (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); - - if (len > 0) { - int frame_len = len; - const char *frame_buf = buf; - - /* - * Check tx fifo space - */ - if(len > (TX_FIFO_SIZE - psc->tfnum)) - frame_len = TX_FIFO_SIZE - psc->tfnum; - -#ifndef SINGLE_CHAR_MODE - channel_info[minor].cur_tx_len = frame_len; -#else - frame_len = 1; -#endif - - /*rtems_cache_flush_multiple_data_lines( (void *)frame_buf, frame_len);*/ - - while (frame_len--) - /* perform byte write to avoid extra NUL characters */ - (* (volatile char *)&(psc->rb_tb)) = *frame_buf++; - - /* - * unmask interrupt - */ - psc->isr_imr = channel_info[minor].shadow_imr |= IMR_TX_RDY; - } else { - /* - * mask interrupt - */ - psc->isr_imr = channel_info[minor].shadow_imr &= ~(IMR_TX_RDY); - } - - return 0; -} - -/* - * Print functions prototyped in bspIo.h - */ -static void A_BSP_output_char( - char c -) -{ - /* - * If we are using U-Boot, then the console is already initialized - * and we can just poll bytes out at any time. - */ - #if !defined(HAS_UBOOT) - if (console_initialized == false) - return; - #endif - -#define PRINTK_WRITE mpc5200_uart_pollWrite - - PRINTK_WRITE(PRINTK_MINOR, &c, 1 ); -} - -static int A_BSP_get_char(void) -{ - /* - * If we are using U-Boot, then the console is already initialized - * and we can just poll bytes in at any time. - */ - #if !defined(HAS_UBOOT) - if (console_initialized == false) - return -1; - #endif - - return mpc5200_uart_pollRead(0); -} - -/* - *************** - * BOILERPLATE * - *************** - * - * All these functions are prototyped in rtems/c/src/lib/include/console.h. - */ - -/* - * Initialize and register the device - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - rtems_device_minor_number console_minor; - char dev_name[] = "/dev/ttyx"; - uint32_t tty_num = 0; - bool first = true; - - /* - * Always use and set up TERMIOS - */ - console_minor = PSC1_MINOR; - rtems_termios_initialize(); - - for (console_minor = PSC1_MINOR; - console_minor < PSC1_MINOR + NUM_PORTS; - console_minor++) { - /* - * check, whether UART is available for this board - */ - if (0 != ((1 << console_minor) & (mpc5200_uart_avail_mask))) { - /* - * Do device-specific initialization and registration for Motorola IceCube - */ - mpc5200_uart_psc_initialize(console_minor); /* /dev/tty0 */ - dev_name[8] = '0' + tty_num; - status = rtems_io_register_name (dev_name, major, console_minor); - assert(status == RTEMS_SUCCESSFUL); - - #ifdef MPC5200_PSC_INDEX_FOR_GPS_MODULE - if (console_minor == MPC5200_PSC_INDEX_FOR_GPS_MODULE) { - status = rtems_io_register_name("/dev/gps", major, console_minor); - assert(status == RTEMS_SUCCESSFUL); - } - #endif - - if (first) { - first = false; - - /* Now register the RTEMS console */ - status = rtems_io_register_name ("/dev/console", major, console_minor); - assert(status == RTEMS_SUCCESSFUL); - } - - tty_num++; - } - } - - console_initialized = true; - return RTEMS_SUCCESSFUL; -} - -/* - * Open the device - */ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_libio_open_close_args_t *args = arg; - rtems_status_code sc; - -#ifdef UARTS_USE_TERMIOS_INT - static const rtems_termios_callbacks intrCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - NULL, /* pollRead */ - mpc5200_uart_write, /* write */ - mpc5200_uart_setAttributes, /* setAttributes */ - NULL, - NULL, - 1 /* outputUsesInterrupts */ - }; -#else - static const rtems_termios_callbacks pollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - mpc5200_uart_pollRead, /* pollRead */ - mpc5200_uart_pollWrite, /* write */ - mpc5200_uart_setAttributes, /* setAttributes */ - NULL, - NULL, - 0 /* output don't use Interrupts */ - }; -#endif - - if(minor > NUM_PORTS - 1) - return RTEMS_INVALID_NUMBER; - -#ifdef UARTS_USE_TERMIOS_INT - sc = rtems_termios_open( major, minor, arg, &intrCallbacks ); -#else /* RTEMS polled I/O with termios */ - sc = rtems_termios_open( major, minor, arg, &pollCallbacks ); -#endif - - ttyp[minor] = args->iop->data1; /* Keep cookie returned by termios_open */ - - if ( !sc ) - rtems_termios_set_initial_baud( ttyp[minor], GEN5200_CONSOLE_BAUD ); - - return sc; -} - - -/* - * Close the device - */ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - if ( minor > NUM_PORTS-1 ) - return RTEMS_INVALID_NUMBER; - - ttyp[minor] = NULL; /* mark for int handler: tty no longer open */ - - return rtems_termios_close( arg ); -} - - -/* - * Read from the device - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - if(minor > NUM_PORTS-1) - return RTEMS_INVALID_NUMBER; - - return rtems_termios_read(arg); -} - -/* - * Write to the device - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - if ( minor > NUM_PORTS-1 ) - return RTEMS_INVALID_NUMBER; - return rtems_termios_write(arg); -} - -/* - * Handle ioctl request. - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - if ( minor > NUM_PORTS-1 ) - return RTEMS_INVALID_NUMBER; - - return rtems_termios_ioctl(arg); -} diff --git a/c/src/lib/libbsp/powerpc/gen83xx/Makefile.am b/c/src/lib/libbsp/powerpc/gen83xx/Makefile.am index da72a62062..25607537dc 100644 --- a/c/src/lib/libbsp/powerpc/gen83xx/Makefile.am +++ b/c/src/lib/libbsp/powerpc/gen83xx/Makefile.am @@ -51,9 +51,9 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c librtemsbsp_a_SOURCES += irq/irq.c # console -librtemsbsp_a_SOURCES += ../../shared/console-termios-init.c -librtemsbsp_a_SOURCES += ../../shared/console-termios.c -librtemsbsp_a_SOURCES += console/console-config.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios-init.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/gen83xx/console/console-config.c # bsp_i2c librtemsbsp_a_SOURCES += i2c/i2c_init.c diff --git a/c/src/lib/libbsp/powerpc/gen83xx/console/console-config.c b/c/src/lib/libbsp/powerpc/gen83xx/console/console-config.c deleted file mode 100644 index d0071cd220..0000000000 --- a/c/src/lib/libbsp/powerpc/gen83xx/console/console-config.c +++ /dev/null @@ -1,107 +0,0 @@ -/** - * @file - * - * @brief Console configuration. - */ - -/* - * Copyright (c) 2008-2014 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include - -#include - -#include -#include -#include - -#ifdef BSP_USE_UART_INTERRUPTS - #define DEVICE_FNS &ns16550_handler_interrupt -#else - #define DEVICE_FNS &ns16550_handler_polled -#endif - -static uint8_t gen83xx_console_get_register(uintptr_t addr, uint8_t i) -{ - volatile uint8_t *reg = (volatile uint8_t *) addr; - - return reg [i]; -} - -static void gen83xx_console_set_register(uintptr_t addr, uint8_t i, uint8_t val) -{ - volatile uint8_t *reg = (volatile uint8_t *) addr; - - reg [i] = val; -} - -static ns16550_context gen83xx_uart_context_0 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"), - .get_reg = gen83xx_console_get_register, - .set_reg = gen83xx_console_set_register, - .port = (uintptr_t) &mpc83xx.duart[0], -#if MPC83XX_CHIP_TYPE / 10 == 830 - .irq = BSP_IPIC_IRQ_UART, -#else - .irq = BSP_IPIC_IRQ_UART1, -#endif - .initial_baud = BSP_CONSOLE_BAUD -}; - -#ifdef BSP_USE_UART2 -static ns16550_context gen83xx_uart_context_1 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"), - .get_reg = gen83xx_console_get_register, - .set_reg = gen83xx_console_set_register, - .port = (uintptr_t) &mpc83xx.duart[1], -#if MPC83XX_CHIP_TYPE / 10 == 830 - .irq = BSP_IPIC_IRQ_UART, -#else - .irq = BSP_IPIC_IRQ_UART2, -#endif - .initial_baud = BSP_CONSOLE_BAUD -}; -#endif - -const console_device console_device_table[] = { - { - .device_file = "/dev/ttyS0", - .probe = ns16550_probe, - .handler = DEVICE_FNS, - .context = &gen83xx_uart_context_0.base - } -#ifdef BSP_USE_UART2 - , { - .device_file = "/dev/ttyS1", - .probe = ns16550_probe, - .handler = DEVICE_FNS, - .context = &gen83xx_uart_context_1.base - } -#endif -}; - -const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table); - -static void gen83xx_output_char(char c) -{ - rtems_termios_device_context *ctx = console_device_table[0].context; - - ns16550_polled_putchar(ctx, c); -} - -BSP_output_char_function_type BSP_output_char = gen83xx_output_char; - -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/powerpc/haleakala/Makefile.am b/c/src/lib/libbsp/powerpc/haleakala/Makefile.am index f4718f5e42..be8b8388ad 100644 --- a/c/src/lib/libbsp/powerpc/haleakala/Makefile.am +++ b/c/src/lib/libbsp/powerpc/haleakala/Makefile.am @@ -30,8 +30,8 @@ librtemsbsp_a_SOURCES += mmu/mmu_405asm.S librtemsbsp_a_SOURCES += dlentry/dlentry.S # console -librtemsbsp_a_SOURCES += ../shared/console/uart.c -librtemsbsp_a_SOURCES += ../shared/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/console/uart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/console/console.c # irq librtemsbsp_a_SOURCES += irq/irq_init.c diff --git a/c/src/lib/libbsp/powerpc/motorola_powerpc/Makefile.am b/c/src/lib/libbsp/powerpc/motorola_powerpc/Makefile.am index e459962c7e..3ed73e63c2 100644 --- a/c/src/lib/libbsp/powerpc/motorola_powerpc/Makefile.am +++ b/c/src/lib/libbsp/powerpc/motorola_powerpc/Makefile.am @@ -55,8 +55,8 @@ librtemsbsp_a_SOURCES +=../../../../../../bsps/powerpc/shared/clock/p_clock.c # console librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/motorola_powerpc/dev/polled_io.c -librtemsbsp_a_SOURCES += ../shared/console/uart.c -librtemsbsp_a_SOURCES += ../shared/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/console/uart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/console/console.c # irq librtemsbsp_a_SOURCES += ../shared/irq/irq_init.c diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/Makefile.am b/c/src/lib/libbsp/powerpc/mpc55xxevb/Makefile.am index a33b0c6c23..9f6798c1bb 100644 --- a/c/src/lib/libbsp/powerpc/mpc55xxevb/Makefile.am +++ b/c/src/lib/libbsp/powerpc/mpc55xxevb/Makefile.am @@ -72,10 +72,10 @@ librtemsbsp_a_SOURCES += startup/start-watchdog.c librtemsbsp_a_SOURCES +=../../../../../../bsps/powerpc/mpc55xxevb/clock/clock-config.c # console -librtemsbsp_a_SOURCES += console/console-config.c -librtemsbsp_a_SOURCES += console/console-esci.c -librtemsbsp_a_SOURCES += console/console-generic.c -librtemsbsp_a_SOURCES += console/console-linflex.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/mpc55xxevb/console/console-config.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/mpc55xxevb/console/console-esci.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/mpc55xxevb/console/console-generic.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/mpc55xxevb/console/console-linflex.c # irq_generic librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-config.c b/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-config.c deleted file mode 100644 index d0ea250917..0000000000 --- a/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-config.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2011-2012 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Obere Lagerstr. 30 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include - -CONSOLE_GENERIC_INFO_TABLE = { - #ifdef MPC55XX_HAS_ESCI - CONSOLE_GENERIC_INFO(mpc55xx_esci_devices + 0, &mpc55xx_esci_callbacks, "/dev/ttyS0") - #ifdef ESCI_B - , CONSOLE_GENERIC_INFO(mpc55xx_esci_devices + 1, &mpc55xx_esci_callbacks, "/dev/ttyS1") - #endif - #ifdef ESCI_C - , CONSOLE_GENERIC_INFO(mpc55xx_esci_devices + 2, &mpc55xx_esci_callbacks, "/dev/ttyS2") - #endif - #ifdef ESCI_D - , CONSOLE_GENERIC_INFO(mpc55xx_esci_devices + 3, &mpc55xx_esci_callbacks, "/dev/ttyS3") - #endif - #endif - #ifdef MPC55XX_HAS_LINFLEX - CONSOLE_GENERIC_INFO(mpc55xx_linflex_devices + 0, &mpc55xx_linflex_callbacks, "/dev/ttyS0"), - CONSOLE_GENERIC_INFO(mpc55xx_linflex_devices + 1, &mpc55xx_linflex_callbacks, "/dev/ttyS1") - #endif -}; - -CONSOLE_GENERIC_INFO_COUNT; - -CONSOLE_GENERIC_MINOR(MPC55XX_CONSOLE_MINOR); diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-esci.c b/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-esci.c deleted file mode 100644 index 9e6646fb65..0000000000 --- a/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-esci.c +++ /dev/null @@ -1,354 +0,0 @@ -/** - * @file - * - * @brief Console ESCI implementation. - */ - -/* - * Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Obere Lagerstr. 30 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include -#include - -#ifdef MPC55XX_HAS_ESCI - -mpc55xx_esci_context mpc55xx_esci_devices [] = { - { - .regs = &ESCI_A, - .irq = MPC55XX_IRQ_ESCI(0) - } - #ifdef ESCI_B - , { - .regs = &ESCI_B, - .irq = MPC55XX_IRQ_ESCI(1) - } - #endif - #ifdef ESCI_C - , { - .regs = &ESCI_C, - .irq = MPC55XX_IRQ_ESCI(2) - } - #endif - #ifdef ESCI_D - , { - .regs = &ESCI_D, - .irq = MPC55XX_IRQ_ESCI(3) - } - #endif -}; - -static void mpc55xx_esci_poll_write(int minor, char c) -{ - mpc55xx_esci_context *self = console_generic_get_context(minor); - const union ESCI_SR_tag clear_tdre = { .B = { .TDRE = 1 } }; - volatile struct ESCI_tag *regs = self->regs; - rtems_interrupt_level level; - bool done = false; - bool wait_for_transmit_done = false; - - rtems_interrupt_disable(level); - if (self->transmit_nest_level == 0) { - union ESCI_CR1_tag cr1 = { .R = regs->CR1.R }; - - if (cr1.B.TIE != 0) { - cr1.B.TIE = 0; - regs->CR1.R = cr1.R; - wait_for_transmit_done = !self->transmit_in_progress; - self->transmit_nest_level = 1; - } - } else { - ++self->transmit_nest_level; - } - rtems_interrupt_enable(level); - - while (!done) { - rtems_interrupt_disable(level); - bool tx = self->transmit_in_progress; - if (!tx || (tx && regs->SR.B.TDRE)) { - regs->SR.R = clear_tdre.R; - regs->DR.B.D = c; - self->transmit_in_progress = true; - done = true; - } - rtems_interrupt_enable(level); - } - - done = false; - while (!done) { - rtems_interrupt_disable(level); - if (wait_for_transmit_done) { - if (regs->SR.B.TDRE) { - regs->SR.R = clear_tdre.R; - self->transmit_in_progress = false; - done = true; - } - } else { - done = true; - } - - if (done && self->transmit_nest_level > 0) { - --self->transmit_nest_level; - - if (self->transmit_nest_level == 0) { - union ESCI_CR1_tag cr1 = { .R = regs->CR1.R }; - - cr1.B.TIE = 1; - regs->CR1.R = cr1.R; - } - } - rtems_interrupt_enable(level); - } -} - -static inline void mpc55xx_esci_interrupts_clear_and_enable( - mpc55xx_esci_context *self -) -{ - volatile struct ESCI_tag *regs = self->regs; - union ESCI_CR1_tag cr1 = MPC55XX_ZERO_FLAGS; - rtems_interrupt_level level; - - rtems_interrupt_disable(level); - cr1.R = regs->CR1.R; - cr1.B.RIE = 1; - cr1.B.TIE = 1; - regs->CR1.R = cr1.R; - regs->SR.R = regs->SR.R; - rtems_interrupt_enable(level); -} - -static inline void mpc55xx_esci_interrupts_disable(mpc55xx_esci_context *self) -{ - volatile struct ESCI_tag *regs = self->regs; - union ESCI_CR1_tag cr1 = MPC55XX_ZERO_FLAGS; - rtems_interrupt_level level; - - rtems_interrupt_disable(level); - cr1.R = regs->CR1.R; - cr1.B.RIE = 0; - cr1.B.TIE = 0; - regs->CR1.R = cr1.R; - rtems_interrupt_enable(level); -} - -static void mpc55xx_esci_interrupt_handler(void *arg) -{ - mpc55xx_esci_context *self = arg; - volatile struct ESCI_tag *regs = self->regs; - union ESCI_SR_tag sr = MPC55XX_ZERO_FLAGS; - union ESCI_SR_tag active = MPC55XX_ZERO_FLAGS; - rtems_interrupt_level level; - - /* Status */ - sr.R = regs->SR.R; - - /* Receive data register full? */ - if (sr.B.RDRF != 0) { - active.B.RDRF = 1; - } - - /* Transmit data register empty? */ - if (sr.B.TDRE != 0) { - active.B.TDRE = 1; - } - - /* Clear flags */ - rtems_interrupt_disable(level); - regs->SR.R = active.R; - self->transmit_in_progress = false; - rtems_interrupt_enable(level); - - /* Enqueue */ - if (active.B.RDRF != 0) { - char c = regs->DR.B.D; - rtems_termios_enqueue_raw_characters(self->tty, &c, 1); - } - - /* Dequeue */ - if (active.B.TDRE != 0) { - rtems_termios_dequeue_characters(self->tty, 1); - } -} - -static int mpc55xx_esci_set_attributes(int minor, const struct termios *t) -{ - mpc55xx_esci_context *self = console_generic_get_context(minor); - volatile struct ESCI_tag *regs = self->regs; - union ESCI_CR1_tag cr1 = { .R = regs->CR1.R }; - union ESCI_CR2_tag cr2 = MPC55XX_ZERO_FLAGS; - rtems_termios_baud_t br = rtems_termios_baud_to_number(t->c_ospeed); - - /* Enable module */ - cr2.B.MDIS = 0; - - /* Interrupts */ - cr1.B.TCIE = 0; - cr1.B.ILIE = 0; - cr2.B.IEBERR = 0; - cr2.B.ORIE = 0; - cr2.B.NFIE = 0; - cr2.B.FEIE = 0; - cr2.B.PFIE = 0; - - /* Disable receiver wake-up standby */ - cr1.B.RWU = 0; - - /* Disable DMA channels */ - cr2.B.RXDMA = 0; - cr2.B.TXDMA = 0; - - /* Idle line type */ - cr1.B.ILT = 0; - - /* Disable loops */ - cr1.B.LOOPS = 0; - - /* Enable or disable receiver */ - cr1.B.RE = (t->c_cflag & CREAD) ? 1 : 0; - - /* Enable transmitter */ - cr1.B.TE = 1; - - /* Baud rate */ - if (br > 0) { - br = bsp_clock_speed / (16 * br); - br = (br > 8191) ? 8191 : br; - } else { - br = 0; - } - cr1.B.SBR = br; - - /* Number of data bits */ - if ((t->c_cflag & CSIZE) != CS8) { - return -1; - } - cr1.B.M = 0; - - /* Parity */ - cr1.B.PE = (t->c_cflag & PARENB) ? 1 : 0; - cr1.B.PT = (t->c_cflag & PARODD) ? 1 : 0; - - /* Stop bits */ - if (t->c_cflag & CSTOPB ) { - /* Two stop bits */ - return -1; - } - - /* Disable LIN */ - regs->LCR.R = 0; - - /* Set control registers */ - regs->CR2.R = cr2.R; - regs->CR1.R = cr1.R; - - return 0; -} - -static int mpc55xx_esci_first_open(int major, int minor, void *arg) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - int rv = 0; - mpc55xx_esci_context *self = console_generic_get_context(minor); - struct rtems_termios_tty *tty = console_generic_get_tty_at_open(arg); - - self->tty = tty; - - rv = rtems_termios_set_initial_baud(tty, BSP_DEFAULT_BAUD_RATE); - if (rv != 0) { - bsp_fatal(MPC55XX_FATAL_CONSOLE_ESCI_BAUD); - } - - rv = mpc55xx_esci_set_attributes(minor, &tty->termios); - if (rv != 0) { - bsp_fatal(MPC55XX_FATAL_CONSOLE_ESCI_ATTRIBUTES); - } - - sc = mpc55xx_interrupt_handler_install( - self->irq, - "eSCI", - RTEMS_INTERRUPT_UNIQUE, - MPC55XX_INTC_DEFAULT_PRIORITY, - mpc55xx_esci_interrupt_handler, - self - ); - if (sc != RTEMS_SUCCESSFUL) { - bsp_fatal(MPC55XX_FATAL_CONSOLE_ESCI_IRQ_INSTALL); - } - - mpc55xx_esci_interrupts_clear_and_enable(self); - self->transmit_in_progress = false; - - return 0; -} - -static int mpc55xx_esci_last_close(int major, int minor, void* arg) -{ - mpc55xx_esci_context *self = console_generic_get_context(minor); - - mpc55xx_esci_interrupts_disable(self); - self->tty = NULL; - - return 0; -} - -static int mpc55xx_esci_poll_read(int minor) -{ - mpc55xx_esci_context *self = console_generic_get_context(minor); - volatile struct ESCI_tag *regs = self->regs; - union ESCI_SR_tag sr = MPC55XX_ZERO_FLAGS; - rtems_interrupt_level level; - int c = -1; - - rtems_interrupt_disable(level); - if (regs->SR.B.RDRF != 0) { - /* Clear flag */ - sr.B.RDRF = 1; - regs->SR.R = sr.R; - - /* Read */ - c = regs->DR.B.D; - } - rtems_interrupt_enable(level); - - return c; -} - -static int mpc55xx_esci_write(int minor, const char *out, size_t n) -{ - if (n > 0) { - mpc55xx_esci_context *self = console_generic_get_context(minor); - - self->regs->DR.B.D = out [0]; - self->transmit_in_progress = true; - } - - return 0; -} - -const console_generic_callbacks mpc55xx_esci_callbacks = { - .termios_callbacks = { - .firstOpen = mpc55xx_esci_first_open, - .lastClose = mpc55xx_esci_last_close, - .write = mpc55xx_esci_write, - .setAttributes = mpc55xx_esci_set_attributes, - .outputUsesInterrupts = TERMIOS_IRQ_DRIVEN - }, - .poll_read = mpc55xx_esci_poll_read, - .poll_write = mpc55xx_esci_poll_write -}; - -#endif /* MPC55XX_HAS_ESCI */ diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-generic.c b/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-generic.c deleted file mode 100644 index 71385adf2b..0000000000 --- a/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-generic.c +++ /dev/null @@ -1,168 +0,0 @@ -/** - * @file - * - * @brief Generic console driver implementation. - */ - -/* - * Copyright (c) 2011 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Obere Lagerstr. 30 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include -#include - -#include -#include - -static const struct termios console_generic_termios = { - .c_cflag = CS8 | CREAD | CLOCAL | __CONCAT(B, BSP_DEFAULT_BAUD_RATE) -}; - -static void console_generic_char_out(char c) -{ - int minor = (int) console_generic_minor; - const console_generic_callbacks *cb = - console_generic_info_table [minor].callbacks; - - (*cb->poll_write)(minor, c); -} - -static int console_generic_char_in(void) -{ - int minor = (int) console_generic_minor; - const console_generic_callbacks *cb = - console_generic_info_table [minor].callbacks; - - return (*cb->poll_read)(minor); -} - -static void console_generic_char_out_do_init(void) -{ - int minor = (int) console_generic_minor; - const console_generic_callbacks *cb = - console_generic_info_table [minor].callbacks; - const struct termios *term = &console_generic_termios; - - BSP_output_char = console_generic_char_out; - (*cb->termios_callbacks.setAttributes)(minor, term); -} - -static void console_generic_char_out_init(char c) -{ - console_generic_char_out_do_init(); - console_generic_char_out(c); -} - -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - const console_generic_info *info_table = console_generic_info_table; - rtems_device_minor_number count = console_generic_info_count; - rtems_device_minor_number console = console_generic_minor; - - if (count <= 0) { - bsp_fatal(MPC55XX_FATAL_CONSOLE_GENERIC_COUNT); - } - - rtems_termios_initialize(); - - for (minor = 0; minor < count; ++minor) { - const console_generic_info *info = info_table + minor; - - sc = rtems_io_register_name(info->device_path, major, minor); - if (sc != RTEMS_SUCCESSFUL) { - bsp_fatal(MPC55XX_FATAL_CONSOLE_GENERIC_REGISTER); - } - } - - sc = rtems_io_register_name(CONSOLE_DEVICE_NAME, major, console); - if (sc != RTEMS_SUCCESSFUL) { - bsp_fatal(MPC55XX_FATAL_CONSOLE_GENERIC_REGISTER_CONSOLE); - } - - console_generic_char_out_do_init(); - - return sc; -} - -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - rtems_device_minor_number count = console_generic_info_count; - - if (minor < count) { - const console_generic_info *info = &console_generic_info_table [minor]; - - sc = rtems_termios_open( - major, - minor, - arg, - &info->callbacks->termios_callbacks - ); - } else { - sc = RTEMS_INVALID_ID; - } - - return sc; -} - -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - return rtems_termios_close(arg); -} - -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - return rtems_termios_read(arg); -} - -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - return rtems_termios_write(arg); -} - -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - return rtems_termios_ioctl(arg); -} - -BSP_output_char_function_type BSP_output_char = console_generic_char_out_init; - -BSP_polling_getchar_function_type BSP_poll_char = console_generic_char_in; diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-linflex.c b/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-linflex.c deleted file mode 100644 index 02978be524..0000000000 --- a/c/src/lib/libbsp/powerpc/mpc55xxevb/console/console-linflex.c +++ /dev/null @@ -1,417 +0,0 @@ -/** - * @file - * - * @brief Console LINFlexD implementation. - */ - -/* - * Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include -#include - -#ifdef MPC55XX_HAS_LINFLEX - -mpc55xx_linflex_context mpc55xx_linflex_devices [] = { - { - .regs = &LINFLEX0, - .irq_rxi = MPC55XX_IRQ_LINFLEX_RXI(0), - .irq_txi = MPC55XX_IRQ_LINFLEX_TXI(0), - .irq_err = MPC55XX_IRQ_LINFLEX_ERR(0), - .tx_pcr_register = &((SIU_tag *) &SIUL)->PCR18, - .tx_pa_value = 1, - .rx_pcr_register = &((SIU_tag *) &SIUL)->PCR19, - .rx_psmi_register = &((SIU_tag *) &SIUL)->PSMI31, - .rx_padsel_value = 0 - }, { - .regs = &LINFLEX1, - .irq_rxi = MPC55XX_IRQ_LINFLEX_RXI(1), - .irq_txi = MPC55XX_IRQ_LINFLEX_TXI(1), - .irq_err = MPC55XX_IRQ_LINFLEX_ERR(1), - .tx_pcr_register = &((SIU_tag *) &SIUL)->PCR94, - .tx_pa_value = 1, - .rx_pcr_register = &((SIU_tag *) &SIUL)->PCR95, - .rx_psmi_register = &((SIU_tag *) &SIUL)->PSMI32, - .rx_padsel_value = 2 - } -}; - -static void enter_init_mode(volatile LINFLEX_tag *regs) -{ - LINFLEX_LINCR1_32B_tag cr1 = { .R = regs->LINCR1.R }; - cr1.B.SLEEP = 0; - cr1.B.INIT = 1; - regs->LINCR1.R = cr1.R; -} - -static void enter_active_mode(volatile LINFLEX_tag *regs) -{ - LINFLEX_LINCR1_32B_tag cr1 = { .R = regs->LINCR1.R }; - cr1.B.SLEEP = 0; - cr1.B.INIT = 0; - regs->LINCR1.R = cr1.R; -} - -static void enter_sleep_mode(volatile LINFLEX_tag *regs) -{ - LINFLEX_LINCR1_32B_tag cr1 = { .R = regs->LINCR1.R }; - cr1.B.SLEEP = 1; - cr1.B.INIT = 0; - regs->LINCR1.R = cr1.R; -} - -static void mpc55xx_linflex_poll_write(int minor, char c) -{ - mpc55xx_linflex_context *self = console_generic_get_context(minor); - volatile LINFLEX_tag *regs = self->regs; - const LINFLEX_UARTSR_32B_tag clear_dtf = { .B = { .DTF_TFF = 1 } }; - rtems_interrupt_level level; - bool done = false; - bool wait_for_transmit_done = false; - - rtems_interrupt_disable(level); - if (self->transmit_nest_level == 0) { - LINFLEX_LINIER_32B_tag ier = { .R = regs->LINIER.R }; - - if (ier.B.DTIE != 0) { - ier.B.DTIE = 0; - regs->LINIER.R = ier.R; - wait_for_transmit_done = !self->transmit_in_progress; - self->transmit_nest_level = 1; - } - } else { - ++self->transmit_nest_level; - } - rtems_interrupt_enable(level); - - while (!done) { - rtems_interrupt_disable(level); - bool tx = self->transmit_in_progress; - if (!tx || (tx && regs->UARTSR.B.DTF_TFF)) { - regs->UARTSR.R = clear_dtf.R; - regs->BDRL.B.DATA0 = c; - self->transmit_in_progress = true; - done = true; - } - rtems_interrupt_enable(level); - } - - done = false; - while (!done) { - rtems_interrupt_disable(level); - if (wait_for_transmit_done) { - if (regs->UARTSR.B.DTF_TFF) { - regs->UARTSR.R = clear_dtf.R; - self->transmit_in_progress = false; - done = true; - } - } else { - done = true; - } - - if (done && self->transmit_nest_level > 0) { - --self->transmit_nest_level; - - if (self->transmit_nest_level == 0) { - LINFLEX_LINIER_32B_tag ier = { .R = regs->LINIER.R }; - - ier.B.DTIE = 1; - regs->LINIER.R = ier.R; - } - } - rtems_interrupt_enable(level); - } -} - -static void mpc55xx_linflex_rx_interrupt_handler(void *arg) -{ - mpc55xx_linflex_context *self = arg; - volatile LINFLEX_tag *regs = self->regs; - char c = regs->BDRM.B.DATA4; - const LINFLEX_UARTSR_32B_tag clear_flags = { .B = { .RMB = 1, .DRF_RFE = 1 } }; - - regs->UARTSR.R = clear_flags.R; - - rtems_termios_enqueue_raw_characters(self->tty, &c, 1); -} - -static void mpc55xx_linflex_tx_interrupt_handler(void *arg) -{ - mpc55xx_linflex_context *self = arg; - volatile LINFLEX_tag *regs = self->regs; - - regs->UARTSR.B.DTF_TFF = 1; /* clear flag */ - self->transmit_in_progress = false; - - rtems_termios_dequeue_characters(self->tty, 1); -} - -/* -static void mpc55xx_linflex_err_interrupt_handler(void *arg) -{ - mpc55xx_linflex_context *self = arg; -} -*/ - -static int mpc55xx_linflex_set_attributes(int minor, const struct termios *t) -{ - mpc55xx_linflex_context *self = console_generic_get_context(minor); - volatile LINFLEX_tag *regs = self->regs; - LINFLEX_UARTCR_32B_tag uartcr = { .R = 0 }; - LINFLEX_GCR_32B_tag gcr = { .R = 0 }; - LINFLEX_LINIER_32B_tag ier = { .R = 0 }; - rtems_termios_baud_t br = rtems_termios_baud_to_number(t->c_ospeed); - LINFLEX_LINFBRR_32B_tag fbrr = { .R = 0 }; - LINFLEX_LINIBRR_32B_tag ibrr = { .R = 0 }; - - enter_init_mode(regs); - - /* Set to UART-mode */ - uartcr.B.UART = 1; - regs->UARTCR.R = uartcr.R; - - /* Set to buffer mode with size 1 */ - uartcr.B.TDFL_TFC = 0; - uartcr.B.RDFL_RFC0 = 0; - uartcr.B.RFBM = 0; - uartcr.B.TFBM = 0; - - /* Enable receiver and transmitter */ - uartcr.B.RXEN = 1; - uartcr.B.TXEN = 1; - - /* Number of data bits */ - uartcr.B.WL1 = 0; - if ((t->c_cflag & CSIZE) == CS8) { - uartcr.B.WL0 = 1; - } else if ((t->c_cflag & CSIZE) == CS7) { - uartcr.B.WL0 = 0; - } else { - return -1; - } - - /* Parity */ - uartcr.B.PCE = (t->c_cflag & PARENB) ? 1 : 0; - uartcr.B.PC1 = 0; - uartcr.B.PC0 = (t->c_cflag & PARODD) ? 1 : 0; - - /* Stop bits */ - gcr.B.STOP = (t->c_cflag & CSTOPB) ? 1 : 0; - - /* Set control registers */ - regs->UARTCR.R = uartcr.R; - regs->GCR.R = gcr.R; - - /* Interrupts */ - ier.B.DTIE = 1; - ier.B.DRIE = 1; - regs->LINIER.R = ier.R; - - /* Baud rate */ - if (br > 0) { - uint32_t lfdiv_mult_32 = bsp_clock_speed * 2 / br; - if((lfdiv_mult_32 & 0x1) != 0) { - ++lfdiv_mult_32; - } - fbrr.B.FBR = (lfdiv_mult_32 >> 1) & 0xF; - ibrr.B.IBR = lfdiv_mult_32 >> 5; - } else { - return -1; - } - regs->LINFBRR.R = fbrr.R; - regs->LINIBRR.R = ibrr.R; - - enter_active_mode(regs); - - return 0; -} - -static int mpc55xx_linflex_first_open(int major, int minor, void *arg) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - int rv = 0; - mpc55xx_linflex_context *self = console_generic_get_context(minor); - struct rtems_termios_tty *tty = console_generic_get_tty_at_open(arg); - SIU_PCR_tag pcr = { .R = 0 }; - SIUL_PSMI_8B_tag psmi = { .R = 0 }; - - self->tty = tty; - - pcr.B.IBE = 1; - self->rx_pcr_register->R = pcr.R; - psmi.B.PADSEL = self->rx_padsel_value; - self->rx_psmi_register->R = psmi.R; - pcr.R = 0; - pcr.B.OBE = 1; - pcr.B.PA = self->tx_pa_value; - self->tx_pcr_register->R = pcr.R; - - rv = rtems_termios_set_initial_baud(tty, BSP_DEFAULT_BAUD_RATE); - if (rv != 0) { - bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_BAUD); - } - - rv = mpc55xx_linflex_set_attributes(minor, &tty->termios); - if (rv != 0) { - bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_ATTRIBUTES); - } - - sc = mpc55xx_interrupt_handler_install( - self->irq_rxi, - "LINFlexD RXI", - RTEMS_INTERRUPT_UNIQUE, - MPC55XX_INTC_DEFAULT_PRIORITY, - mpc55xx_linflex_rx_interrupt_handler, - self - ); - if (sc != RTEMS_SUCCESSFUL) { - bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_RX_IRQ_INSTALL); - } - - sc = mpc55xx_interrupt_handler_install( - self->irq_txi, - "LINFlexD TXI", - RTEMS_INTERRUPT_UNIQUE, - MPC55XX_INTC_DEFAULT_PRIORITY, - mpc55xx_linflex_tx_interrupt_handler, - self - ); - if (sc != RTEMS_SUCCESSFUL) { - bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_TX_IRQ_INSTALL); - } - - /* - sc = mpc55xx_interrupt_handler_install( - self->irq_err, - "LINFlexD ERR", - RTEMS_INTERRUPT_UNIQUE, - MPC55XX_INTC_DEFAULT_PRIORITY, - mpc55xx_linflex_err_interrupt_handler, - self - ); - if (sc != RTEMS_SUCCESSFUL) { - bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_ERR_IRQ_INSTALL); - } - */ - - return 0; -} - -static int mpc55xx_linflex_last_close(int major, int minor, void* arg) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - mpc55xx_linflex_context *self = console_generic_get_context(minor); - volatile LINFLEX_tag *regs = self->regs; - SIU_PCR_tag pcr = { .R = 0 }; - SIUL_PSMI_8B_tag psmi = { .R = 0 }; - - /* enter initialization mode */ - enter_init_mode(regs); - - /* disable interrupts */ - regs->LINIER.R = 0; - - /* set module to sleep mode */ - enter_sleep_mode(regs); - - sc = rtems_interrupt_handler_remove( - self->irq_rxi, - mpc55xx_linflex_rx_interrupt_handler, - self - ); - if (sc != RTEMS_SUCCESSFUL) { - bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_RX_IRQ_REMOVE); - } - - sc = rtems_interrupt_handler_remove( - self->irq_txi, - mpc55xx_linflex_tx_interrupt_handler, - self - ); - if (sc != RTEMS_SUCCESSFUL) { - bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_TX_IRQ_REMOVE); - } - - /* - sc = rtems_interrupt_handler_remove( - self->irq_err, - mpc55xx_linflex_err_interrupt_handler, - self - ); - if (sc != RTEMS_SUCCESSFUL) { - bsp_fatal(MPC55XX_FATAL_CONSOLE_LINFLEX_ERR_IRQ_REMOVE); - } - */ - - pcr.B.IBE = 1; - self->rx_pcr_register->R = pcr.R; - self->tx_pcr_register->R = pcr.R; - psmi.R = 0; - self->rx_psmi_register->R = psmi.R; - - self->tty = NULL; - - return 0; -} - -static int mpc55xx_linflex_poll_read(int minor) -{ - mpc55xx_linflex_context *self = console_generic_get_context(minor); - volatile LINFLEX_tag *regs = self->regs; - rtems_interrupt_level level; - int c = -1; - - rtems_interrupt_disable(level); - if (regs->UARTSR.B.DRF_RFE != 0) { - /* Clear flag */ - regs->UARTSR.B.DRF_RFE = 1; - - /* Read */ - c = regs->BDRM.B.DATA4; - } - rtems_interrupt_enable(level); - - return c; -} - -static int mpc55xx_linflex_write(int minor, const char *out, size_t n) -{ - if (n > 0) { - mpc55xx_linflex_context *self = console_generic_get_context(minor); - volatile LINFLEX_tag *regs = self->regs; - - regs->BDRL.B.DATA0 = out [0]; - self->transmit_in_progress = true; - /* TODO: send more then one byte */ - } - - return 0; -} - -const console_generic_callbacks mpc55xx_linflex_callbacks = { - .termios_callbacks = { - .firstOpen = mpc55xx_linflex_first_open, - .lastClose = mpc55xx_linflex_last_close, - .write = mpc55xx_linflex_write, - .setAttributes = mpc55xx_linflex_set_attributes, - .outputUsesInterrupts = TERMIOS_IRQ_DRIVEN - }, - .poll_read = mpc55xx_linflex_poll_read, - .poll_write = mpc55xx_linflex_poll_write -}; - -#endif /* MPC55XX_HAS_LINFLEX */ diff --git a/c/src/lib/libbsp/powerpc/mpc8260ads/Makefile.am b/c/src/lib/libbsp/powerpc/mpc8260ads/Makefile.am index c7b537f8e4..621e61e350 100644 --- a/c/src/lib/libbsp/powerpc/mpc8260ads/Makefile.am +++ b/c/src/lib/libbsp/powerpc/mpc8260ads/Makefile.am @@ -25,7 +25,7 @@ librtemsbsp_a_SOURCES = librtemsbsp_a_SOURCES +=../../../../../../bsps/powerpc/shared/clock/clock.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/mpc8260ads/console/console.c # irq librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c diff --git a/c/src/lib/libbsp/powerpc/mpc8260ads/console/console.c b/c/src/lib/libbsp/powerpc/mpc8260ads/console/console.c deleted file mode 100644 index 873c38dc3e..0000000000 --- a/c/src/lib/libbsp/powerpc/mpc8260ads/console/console.c +++ /dev/null @@ -1,458 +0,0 @@ -/* - * This file contains the MBX8xx termios serial I/O package. - * Only asynchronous I/O is supported. - * - * The SCCs and SMCs are assigned as follows - * - * Channel Device Minor Note - * SMC1 /dev/tty0 0 - * SMC2 /dev/tty1 1 - * SCC1 2 N/A. Hardwired as ethernet port - * SCC2 /dev/tty2 3 - * SCC3 /dev/tty3 4 - * SCC4 /dev/tty4 5 - * - * The SCCs and SMCs on the eval board are assigned as follows - * - * Channel Device Minor Termios - * SMC1 /dev/tty3 4 no - * SMC2 /dev/tty4 5 no - * SCC1 /dev/tty0 0 no - * SCC2 /dev/console 1 yes - * SCC3 /dev/tty1 2 no * USED FOR NETWORK I/F - * SCC4 /dev/tty2 3 no * USED FOR NETWORK I/F - * - * All ports support termios. The use of termios is recommended for real-time - * applications. Termios provides buffering and input processing. When not - * using termios, processing is limited to the substitution of LF for CR on - * input, and the output of a CR following the output of a LF character. - * Note that the terminal should not send CR/LF pairs when the return key - * is pressed, and that output lines are terminated with LF/CR, not CR/LF - * (although that would be easy to change). - * - * I/O may be interrupt-driven (recommended for real-time applications) or - * polled. Polled I/O may be performed by this device driver entirely, or - * in part by EPPCBug. With EPPCBug 1.1, polled I/O is limited to the - * EPPCBug debug console. This is a limitation of the firmware. Later - * firmware may be able to do I/O through any port. This code assumes - * that the EPPCBug console is the default: SMC1. If the console and - * printk ports are set to anything else with EPPCBug polled I/O, the - * system will hang. Only port SMC1 is usable with EPPCBug polled I/O. - * - * LIMITATIONS: - * - * It is not possible to use different I/O modes on the different ports. The - * exception is with printk. The printk port can use a different mode from - * the other ports. If this is done, it is important not to open the printk - * port from an RTEMS application. - * - * Currently, the I/O modes are determined at build time. It would be much - * better to have the mode selected at boot time based on parameters in - * NVRAM. - * - * Interrupt-driven I/O requires termios. - * - * TESTS: - * - * TO RUN THE TESTS, USE POLLED I/O WITHOUT TERMIOS SUPPORT. Some tests - * play with the interrupt masks and turn off I/O. Those tests will hang - * when interrupt-driven I/O is used. Other tests, such as cdtest, do I/O - * from the static constructors before the console is open. This test - * will not work with interrupt-driven I/O. Because of the buffering - * performed in termios, test output may not be in sequence.The tests - * should all be fixed to work with interrupt-driven I/O and to - * produce output in the expected sequence. Obviously, the termios test - * requires termios support in the driver. - * - * Set CONSOLE_MINOR to the appropriate device minor number in the - * config file. This allows the RTEMS application console to be different - * from the EPPBug debug console or the GDB port. - * - * This driver handles all five available serial ports: it distinguishes - * the sub-devices using minor device numbers. It is not possible to have - * other protocols running on the other ports when this driver is used as - * currently written. - */ - -/* - * Based on code (alloc860.c in eth_comm port) by - * Jay Monkman (jmonkman@frasca.com), - * Copyright (C) 1998 by Frasca International, Inc. - * - * Modifications by Darlene Stewart - * and Charles-Antoine Gauthier . - * Copyright (c) 2000, National Research Council of Canada - * - * Modifications by Andy Dachs for MPC8260 - * support. - */ -#include -#include -#include - -#include -#include -#include -#include - -static void _BSP_output_char( char c ); -static rtems_status_code do_poll_read( rtems_device_major_number major, rtems_device_minor_number minor, void * arg); -static rtems_status_code do_poll_write( rtems_device_major_number major, rtems_device_minor_number minor, void * arg); - -BSP_output_char_function_type BSP_output_char = _BSP_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - -/* - * do_poll_read - * - * Input characters through polled I/O. Returns has soon as a character has - * been received. Otherwise, if we wait for the number of requested characters, - * we could be here forever! - * - * CR is converted to LF on input. The terminal should not send a CR/LF pair - * when the return or enter key is pressed. - * - * Input parameters: - * major - ignored. Should be the major number for this driver. - * minor - selected channel. - * arg->buffer - where to put the received characters. - * arg->count - number of characters to receive before returning--Ignored. - * - * Output parameters: - * arg->bytes_moved - the number of characters read. Always 1. - * - * Return value: RTEMS_SUCCESSFUL - * - * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! - */ -static rtems_status_code do_poll_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args = arg; - int c; - -#define BSP_READ m8xx_uart_pollRead - - while( (c = BSP_READ(minor)) == -1 ); - rw_args->buffer[0] = (uint8_t)c; - if( rw_args->buffer[0] == '\r' ) - rw_args->buffer[0] = '\n'; - rw_args->bytes_moved = 1; - return RTEMS_SUCCESSFUL; -} - -/* - * do_poll_write - * - * Output characters through polled I/O. Returns only once every character has - * been sent. - * - * CR is transmitted AFTER a LF on output. - * - * Input parameters: - * major - ignored. Should be the major number for this driver. - * minor - selected channel - * arg->buffer - where to get the characters to transmit. - * arg->count - the number of characters to transmit before returning. - * - * Output parameters: - * arg->bytes_moved - the number of characters read - * - * Return value: RTEMS_SUCCESSFUL - * - * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! - */ -static rtems_status_code do_poll_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args = arg; - uint32_t i; - char cr ='\r'; - -#define BSP_WRITE m8xx_uart_pollWrite - - for( i = 0; i < rw_args->count; i++ ) { - BSP_WRITE(minor, &(rw_args->buffer[i]), 1); - if ( rw_args->buffer[i] == '\n' ) - BSP_WRITE(minor, &cr, 1); - } - rw_args->bytes_moved = i; - return RTEMS_SUCCESSFUL; - -} - -/* - * Print functions prototyped in bspIo.h - */ - -static void _BSP_output_char( char c ) -{ - /* - * Can't rely on console_initialize having been called before this function - * is used, so it may fail unless output is done through EPPC-Bug. - */ -#define PRINTK_WRITE m8xx_uart_pollWrite - - PRINTK_WRITE( PRINTK_MINOR, &c, 1 ); -} - -/* - *************** - * BOILERPLATE * - *************** - * - * All these functions are prototyped in rtems/c/src/lib/include/console.h. - */ - -/* - * Initialize and register the device - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - rtems_device_minor_number console_minor; - - /* - * Set up TERMIOS if needed - */ - - console_minor = CONSOLE_MINOR; - -#if UARTS_USE_TERMIOS == 1 - - rtems_termios_initialize (); -#else - rtems_termios_initialize (); -#endif /* UARTS_USE_TERMIOS */ - - /* - * Do common initialization. - */ - m8xx_uart_initialize(); - - /* - * Do device-specific initialization - */ -#if 0 - m8xx_uart_smc_initialize(SMC1_MINOR); /* /dev/tty4 */ - m8xx_uart_smc_initialize(SMC2_MINOR); /* /dev/tty5 */ -#endif - - m8xx_uart_scc_initialize(SCC1_MINOR); /* /dev/tty0 */ - m8xx_uart_scc_initialize(SCC2_MINOR); /* /dev/tty1 */ - -#if 0 /* used as network connections */ - m8xx_uart_scc_initialize(SCC3_MINOR); /* /dev/tty2 */ - m8xx_uart_scc_initialize(SCC4_MINOR); /* /dev/tty3 */ -#endif - - /* - * Set up interrupts - */ - m8xx_uart_interrupts_initialize(); - - status = rtems_io_register_name ("/dev/tty0", major, SCC1_MINOR); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - chmod("/dev/tty0",0660); - chown("/dev/tty0",2,0); - - status = rtems_io_register_name ("/dev/tty1", major, SCC2_MINOR); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - chmod("/dev/tty1",0660); - chown("/dev/tty1",2,0); - -#if 0 - status = rtems_io_register_name ("/dev/tty2", major, SCC3_MINOR); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - status = rtems_io_register_name ("/dev/tty3", major, SCC4_MINOR); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - status = rtems_io_register_name ("/dev/tty4", major, SMC1_MINOR); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - status = rtems_io_register_name ("/dev/tty5", major, SMC2_MINOR); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); -#endif - /* Now register the RTEMS console */ - status = rtems_io_register_name ("/dev/console", major, console_minor); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - chmod("/dev/console",0666); - chown("/dev/console",2,0); - - return RTEMS_SUCCESSFUL; -} - -/* - * Open the device - */ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ -#if UARTS_IO_MODE == 1 /* RTEMS interrupt-driven I/O with termios */ - /* Used to track termios private data for callbacks */ - extern struct rtems_termios_tty *ttyp[]; - rtems_libio_open_close_args_t *args = arg; - - static const rtems_termios_callbacks intrCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - NULL, /* pollRead */ - m8xx_uart_write, /* write */ - m8xx_uart_setAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - 1 /* outputUsesInterrupts */ - }; -#else -#if (UARTS_USE_TERMIOS == 1) && (UARTS_IO_MODE != 1) - static const rtems_termios_callbacks pollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - m8xx_uart_pollRead, /* pollRead */ - m8xx_uart_pollWrite, /* write */ - m8xx_uart_setAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - 0 /* outputUsesInterrupts */ - }; -#endif - -#endif - - rtems_status_code sc; - - if ( minor > NUM_PORTS-1 ) - return RTEMS_INVALID_NUMBER; - -#if UARTS_USE_TERMIOS == 1 - -#if UARTS_IO_MODE == 1 /* RTEMS interrupt-driven I/O with termios */ - sc = rtems_termios_open( major, minor, arg, &intrCallbacks ); - ttyp[minor] = args->iop->data1; /* Keep cookie returned by termios_open */ -#else /* RTEMS polled I/O with termios */ - sc = rtems_termios_open( major, minor, arg, &pollCallbacks ); -#endif - -#else /* UARTS_USE_TERMIOS != 1 */ - /* no termios -- default to polled I/O */ - sc = RTEMS_SUCCESSFUL; -#endif /* UARTS_USE_TERMIOS != 1 */ - - return sc; - -} - -/* - * Close the device - */ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - if ( minor > NUM_PORTS-1 ) - return RTEMS_INVALID_NUMBER; - -#if UARTS_USE_TERMIOS == 1 - return rtems_termios_close( arg ); -#else - return RTEMS_SUCCESSFUL; -#endif - -} - -/* - * Read from the device - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - if ( minor > NUM_PORTS-1 ) - return RTEMS_INVALID_NUMBER; - -#if UARTS_USE_TERMIOS == 1 - return rtems_termios_read( arg ); -#else - return do_poll_read( major, minor, arg ); -#endif - -} - -/* - * Write to the device - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - if ( minor > NUM_PORTS-1 ) - return RTEMS_INVALID_NUMBER; - -#if UARTS_USE_TERMIOS == 1 - return rtems_termios_write( arg ); -#else - /* no termios -- default to polled */ - return do_poll_write( major, minor, arg ); -#endif - -} - -/* - * Handle ioctl request. - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - if ( minor > NUM_PORTS-1 ) - return RTEMS_INVALID_NUMBER; - -#if UARTS_USE_TERMIOS == 1 - return rtems_termios_ioctl( arg ); -#else - return RTEMS_SUCCESSFUL; -#endif - -} - -/* - * Support routine for console-generic - */ -int mbx8xx_console_get_configuration(void) -{ -#if UARTS_IO_MODE == 1 - return 0x02; -#else - return 0; -#endif - -} diff --git a/c/src/lib/libbsp/powerpc/mvme3100/Makefile.am b/c/src/lib/libbsp/powerpc/mvme3100/Makefile.am index 38d0197fc8..6491639c3f 100644 --- a/c/src/lib/libbsp/powerpc/mvme3100/Makefile.am +++ b/c/src/lib/libbsp/powerpc/mvme3100/Makefile.am @@ -52,8 +52,8 @@ librtemsbsp_a_SOURCES += tod/todcfg.c librtemsbsp_a_SOURCES +=../../../../../../bsps/powerpc/shared/clock/p_clock.c # console -librtemsbsp_a_SOURCES += ../shared/console/uart.c -librtemsbsp_a_SOURCES += ../shared/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/console/uart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/console/console.c # irq librtemsbsp_a_SOURCES += irq/irq_init.c diff --git a/c/src/lib/libbsp/powerpc/mvme5500/Makefile.am b/c/src/lib/libbsp/powerpc/mvme5500/Makefile.am index 3c24c3aa9d..6873db182f 100644 --- a/c/src/lib/libbsp/powerpc/mvme5500/Makefile.am +++ b/c/src/lib/libbsp/powerpc/mvme5500/Makefile.am @@ -29,8 +29,8 @@ librtemsbsp_a_SOURCES += ../shared/startup/probeMemEnd.c librtemsbsp_a_SOURCES +=../../../../../../bsps/powerpc/shared/clock/p_clock.c # console -librtemsbsp_a_SOURCES += ../shared/console/uart.c -librtemsbsp_a_SOURCES += ../shared/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/console/uart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/console/console.c # pci librtemsbsp_a_SOURCES += pci/pci.c diff --git a/c/src/lib/libbsp/powerpc/psim/Makefile.am b/c/src/lib/libbsp/powerpc/psim/Makefile.am index 0c7702a5af..5b7e65463e 100644 --- a/c/src/lib/libbsp/powerpc/psim/Makefile.am +++ b/c/src/lib/libbsp/powerpc/psim/Makefile.am @@ -32,10 +32,10 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c # pclock librtemsbsp_a_SOURCES +=../../../../../../bsps/powerpc/shared/clock/p_clock.c # console -librtemsbsp_a_SOURCES += ../../shared/console-polled.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-polled.c # debugio -librtemsbsp_a_SOURCES += console/console-io.c -librtemsbsp_a_SOURCES += console/consupp.S +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/psim/console/console-io.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/psim/console/consupp.S # irq librtemsbsp_a_SOURCES += irq/irq_init.c diff --git a/c/src/lib/libbsp/powerpc/psim/console/console-io.c b/c/src/lib/libbsp/powerpc/psim/console/console-io.c deleted file mode 100644 index 512b90dde2..0000000000 --- a/c/src/lib/libbsp/powerpc/psim/console/console-io.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This file contains the hardware specific portions of the TTY driver - * for the simulated serial port on the PowerPC simulator. - */ - -/* - * COPYRIGHT (c) 1989-2004. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include - -/* - * console_initialize_hardware - * - * This routine initializes the console hardware. - * - */ - -void console_initialize_hardware(void) -{ -} - -/* external prototypes for monitor interface routines */ - -void outbyte( char ); -char inbyte( void ); - -/* - * console_outbyte_polled - * - * This routine transmits a character using polling. - */ - -void console_outbyte_polled( - int port, - char ch -) -{ - outbyte( ch ); -} - -/* - * console_inbyte_nonblocking - * - * This routine polls for a character. - */ - -int console_inbyte_nonblocking( - int port -) -{ - char c; - - c = inbyte(); - if (!c) - return -1; - return c; -} - -/* - * To support printk - */ - -#include - -static void PSIM_output_char(char c) { console_outbyte_polled( 0, c ); } - -BSP_output_char_function_type BSP_output_char = PSIM_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/powerpc/psim/console/consupp.S b/c/src/lib/libbsp/powerpc/psim/console/consupp.S deleted file mode 100644 index bb9e834fc6..0000000000 --- a/c/src/lib/libbsp/powerpc/psim/console/consupp.S +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Adapted from the mvme-inbyte.S and mvme-outbyte.S files in libgloss. - * These should work on all targets using the ppcbug monitor. - * - * Copyright (c) 1995 Cygnus Support - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ - -#include "ppc-asm.h" - - .file "support.s" - .text -FUNC_START(outbyte) - li r10,0x20 - sc - blr -FUNC_END(outbyte) - - .text -FUNC_START(inbyte) - li r10,0x0 - sc - blr -FUNC_END(inbyte) diff --git a/c/src/lib/libbsp/powerpc/qemuppc/Makefile.am b/c/src/lib/libbsp/powerpc/qemuppc/Makefile.am index 8c58ab79b6..9a3099377a 100644 --- a/c/src/lib/libbsp/powerpc/qemuppc/Makefile.am +++ b/c/src/lib/libbsp/powerpc/qemuppc/Makefile.am @@ -31,8 +31,8 @@ librtemsbsp_a_SOURCES += startup/bspstart.c # pclock librtemsbsp_a_SOURCES +=../../../../../../bsps/powerpc/shared/clock/clock.c # console -librtemsbsp_a_SOURCES += ../../shared/console-polled.c -librtemsbsp_a_SOURCES += console/console-io.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-polled.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/qemuppc/console/console-io.c # irq librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c diff --git a/c/src/lib/libbsp/powerpc/qemuppc/console/console-io.c b/c/src/lib/libbsp/powerpc/qemuppc/console/console-io.c deleted file mode 100644 index 738bd27966..0000000000 --- a/c/src/lib/libbsp/powerpc/qemuppc/console/console-io.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file contains the hardware specific portions of the TTY driver - * for the serial ports on the qemuppc. - */ - -/* - * COPYRIGHT (c) 1989-2008. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include - -static void -__outb(int port, unsigned char v) -{ - *((volatile unsigned char *)(0x80000000 + port)) = v; -} - -static unsigned char -__inb(int port) -{ - return *((volatile unsigned char *)(0x80000000 + port)); -} - -/* - * console_initialize_hardware - * - * This routine initializes the console hardware. - * - */ -void console_initialize_hardware(void) -{ - return; -} - -/* - * console_outbyte_polled - * - * This routine transmits a character using polling. - */ -void console_outbyte_polled( - int port, - char ch -) -{ - __outb(0x3f8 + 0x00, ch); -} - -/* - * console_inbyte_nonblocking - * - * This routine polls for a character. - */ -int console_inbyte_nonblocking( - int port -) -{ - - if ( __inb(0x3f8 + 0x05) & 0x01 ) - return __inb(0x3f8 + 0x00); - return -1; -} - -#include - -static void simBSP_output_char(char c) { console_outbyte_polled( 0, c ); } - -BSP_output_char_function_type BSP_output_char = simBSP_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/powerpc/qoriq/Makefile.am b/c/src/lib/libbsp/powerpc/qoriq/Makefile.am index e0c1ce87fc..770df931c6 100644 --- a/c/src/lib/libbsp/powerpc/qoriq/Makefile.am +++ b/c/src/lib/libbsp/powerpc/qoriq/Makefile.am @@ -65,11 +65,11 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c librtemsbsp_a_SOURCES += irq/irq.c # Console -librtemsbsp_a_SOURCES += ../../shared/console-termios-init.c -librtemsbsp_a_SOURCES += ../../shared/console-termios.c -librtemsbsp_a_SOURCES += console/uart-bridge-master.c -librtemsbsp_a_SOURCES += console/uart-bridge-slave.c -librtemsbsp_a_SOURCES += console/console-config.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios-init.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/qoriq/console/uart-bridge-master.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/qoriq/console/uart-bridge-slave.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/qoriq/console/console-config.c # RTC librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/rtc/rtc-support.c diff --git a/c/src/lib/libbsp/powerpc/qoriq/console/console-config.c b/c/src/lib/libbsp/powerpc/qoriq/console/console-config.c deleted file mode 100644 index 4c1ca1d3f6..0000000000 --- a/c/src/lib/libbsp/powerpc/qoriq/console/console-config.c +++ /dev/null @@ -1,330 +0,0 @@ -/** - * @file - * - * @ingroup QorIQ - * - * @brief Console configuration. - */ - -/* - * Copyright (c) 2010, 2017 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include - -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -static void output_char(char c); - -#ifdef QORIQ_IS_HYPERVISOR_GUEST -typedef struct { - rtems_termios_device_context base; - uint32_t handle; -} qoriq_bc_context; - -static bool qoriq_bc_probe(rtems_termios_device_context *base) -{ - qoriq_bc_context *ctx; - const void *fdt; - int node; - const uint32_t *handle; - int len; - - fdt = bsp_fdt_get(); - - node = fdt_node_offset_by_compatible(fdt, -1, "epapr,hv-byte-channel"); - if (node < 0) { - return false; - } - - handle = fdt_getprop(fdt, node, "hv-handle", &len); - if (handle == NULL || len != 4) { - return false; - } - - ctx = (qoriq_bc_context *) base; - ctx->handle = fdt32_to_cpu(*handle); - - BSP_output_char = output_char; - return true; -} - -static int qoriq_bc_read_polled(rtems_termios_device_context *base) -{ - qoriq_bc_context *ctx; - char buf[EV_BYTE_CHANNEL_MAX_BYTES]; - unsigned int count; - unsigned int status; - - ctx = (qoriq_bc_context *) base; - count = 1; - status = ev_byte_channel_receive(ctx->handle, &count, buf); - - if (status != EV_SUCCESS || count == 0) { - return -1; - } - - return (unsigned char) buf[0]; -} - -static void qoriq_bc_write_polled( - rtems_termios_device_context *base, - const char *buf, - size_t len -) -{ - qoriq_bc_context *ctx; - uint32_t handle; - - ctx = (qoriq_bc_context *) base; - handle = ctx->handle; - - while (len > 0) { - unsigned int count; - unsigned int status; - char buf2[EV_BYTE_CHANNEL_MAX_BYTES]; - const char *out; - - if (len < EV_BYTE_CHANNEL_MAX_BYTES) { - count = len; - out = memcpy(buf2, buf, len); - } else { - count = EV_BYTE_CHANNEL_MAX_BYTES; - out = buf; - } - - status = ev_byte_channel_send(handle, &count, out); - - if (status == EV_SUCCESS) { - len -= count; - buf += count; - } - } -} - -static const rtems_termios_device_handler qoriq_bc_handler_polled = { - .poll_read = qoriq_bc_read_polled, - .write = qoriq_bc_write_polled, - .mode = TERMIOS_POLLED -}; - -static qoriq_bc_context qoriq_bc_context_0 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("BC 0"), -}; -#endif /* QORIQ_IS_HYPERVISOR_GUEST */ - -#if (QORIQ_UART_0_ENABLE + QORIQ_UART_BRIDGE_0_ENABLE == 2) \ - || (QORIQ_UART_1_ENABLE + QORIQ_UART_BRIDGE_1_ENABLE == 2) - #define BRIDGE_MASTER -#elif QORIQ_UART_BRIDGE_0_ENABLE || QORIQ_UART_BRIDGE_1_ENABLE - #define BRIDGE_SLAVE -#endif - -#ifdef BSP_USE_UART_INTERRUPTS - #define DEVICE_FNS &ns16550_handler_interrupt -#else - #define DEVICE_FNS &ns16550_handler_polled -#endif - -#if QORIQ_UART_0_ENABLE || QORIQ_UART_1_ENABLE - static bool uart_probe(rtems_termios_device_context *base) - { - ns16550_context *ctx = (ns16550_context *) base; - - ctx->clock = BSP_bus_frequency; - - return ns16550_probe(base); - } - - static uint8_t get_register(uintptr_t addr, uint8_t i) - { - volatile uint8_t *reg = (uint8_t *) addr; - - return reg [i]; - } - - static void set_register(uintptr_t addr, uint8_t i, uint8_t val) - { - volatile uint8_t *reg = (uint8_t *) addr; - - reg [i] = val; - } -#endif - -#if QORIQ_UART_0_ENABLE -static ns16550_context qoriq_uart_context_0 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"), - .get_reg = get_register, - .set_reg = set_register, - .port = (uintptr_t) &qoriq.uart_0, - .irq = QORIQ_IRQ_DUART_1, - .initial_baud = BSP_CONSOLE_BAUD -}; -#endif - -#if QORIQ_UART_1_ENABLE -static ns16550_context qoriq_uart_context_1 = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"), - .get_reg = get_register, - .set_reg = set_register, - .port = (uintptr_t) &qoriq.uart_1, - .irq = QORIQ_IRQ_DUART_1, - .initial_baud = BSP_CONSOLE_BAUD -}; -#endif - -#ifdef BRIDGE_MASTER - #define BRIDGE_PROBE qoriq_uart_bridge_master_probe - #define BRIDGE_FNS &qoriq_uart_bridge_master - #if QORIQ_UART_BRIDGE_0_ENABLE - static uart_bridge_master_context bridge_0_context = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 0"), - .device_path = "/dev/ttyS0", - .type = INTERCOM_TYPE_UART_0, - .transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY( - bridge_0_context.transmit_fifo - ) - }; - #define BRIDGE_0_CONTEXT &bridge_0_context.base - #endif - #if QORIQ_UART_BRIDGE_1_ENABLE - static uart_bridge_master_context bridge_1_context = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 1"), - .device_path = "/dev/ttyS1", - .type = INTERCOM_TYPE_UART_1, - .transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY( - bridge_1_context.transmit_fifo - ) - }; - #define BRIDGE_1_CONTEXT &bridge_1_context.base - #endif -#endif - -#ifdef BRIDGE_SLAVE - #define BRIDGE_PROBE console_device_probe_default - #define BRIDGE_FNS &qoriq_uart_bridge_slave - #if QORIQ_UART_BRIDGE_0_ENABLE - static uart_bridge_slave_context bridge_0_context = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 0"), - .type = INTERCOM_TYPE_UART_0, - .transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY( - bridge_0_context.transmit_fifo - ) - }; - #define BRIDGE_0_CONTEXT &bridge_0_context.base - #endif - #if QORIQ_UART_BRIDGE_1_ENABLE - static uart_bridge_slave_context bridge_1_context = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 1"), - .type = INTERCOM_TYPE_UART_1, - .transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY( - bridge_1_context.transmit_fifo - ) - }; - #define BRIDGE_1_CONTEXT &bridge_1_context.base - #endif -#endif - -const console_device console_device_table[] = { - #ifdef QORIQ_IS_HYPERVISOR_GUEST - { - .device_file = "/dev/ttyBC0", - .probe = qoriq_bc_probe, - .handler = &qoriq_bc_handler_polled, - .context = &qoriq_bc_context_0.base - }, - #endif - #if QORIQ_UART_0_ENABLE - { - .device_file = "/dev/ttyS0", - .probe = uart_probe, - .handler = DEVICE_FNS, - .context = &qoriq_uart_context_0.base - }, - #endif - #if QORIQ_UART_1_ENABLE - { - .device_file = "/dev/ttyS1", - .probe = uart_probe, - .handler = DEVICE_FNS, - .context = &qoriq_uart_context_1.base - }, - #endif - #if QORIQ_UART_BRIDGE_0_ENABLE - { - #if QORIQ_UART_1_ENABLE - .device_file = "/dev/ttyB0", - #else - .device_file = "/dev/ttyS0", - #endif - .probe = BRIDGE_PROBE, - .handler = BRIDGE_FNS, - .context = BRIDGE_0_CONTEXT - }, - #endif - #if QORIQ_UART_BRIDGE_1_ENABLE - { - #if QORIQ_UART_1_ENABLE - .device_file = "/dev/ttyB1", - #else - .device_file = "/dev/ttyS1", - #endif - .probe = BRIDGE_PROBE, - .handler = BRIDGE_FNS, - .context = BRIDGE_1_CONTEXT - } - #endif -}; - -const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table); - -static void output_char(char c) -{ - rtems_termios_device_context *base = console_device_table[0].context; - -#ifdef QORIQ_IS_HYPERVISOR_GUEST - qoriq_bc_write_polled(base, &c, 1); -#else - ns16550_polled_putchar(base, c); -#endif -} - -#ifdef QORIQ_IS_HYPERVISOR_GUEST -static void qoriq_bc_output_char_init(char c) -{ - rtems_termios_device_context *base = console_device_table[0].context; - - qoriq_bc_probe(base); - output_char(c); -} - -BSP_output_char_function_type BSP_output_char = qoriq_bc_output_char_init; -#else -BSP_output_char_function_type BSP_output_char = output_char; -#endif - -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/powerpc/qoriq/console/uart-bridge-master.c b/c/src/lib/libbsp/powerpc/qoriq/console/uart-bridge-master.c deleted file mode 100644 index 588e0a42ad..0000000000 --- a/c/src/lib/libbsp/powerpc/qoriq/console/uart-bridge-master.c +++ /dev/null @@ -1,181 +0,0 @@ -/** - * @file - * - * @ingroup QorIQUartBridge - * - * @brief UART bridge master implementation. - */ - -/* - * Copyright (c) 2011-2015 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include - -#include -#include - -#define TRANSMIT_EVENT RTEMS_EVENT_13 - -static void serial_settings(int fd) -{ - struct termios term; - int rv = tcgetattr(fd, &term); - assert(rv == 0); - - term.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); - term.c_oflag &= ~OPOST; - term.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); - term.c_cflag &= ~(CSIZE | PARENB); - term.c_cflag |= CS8; - - term.c_cc [VMIN] = 1; - term.c_cc [VTIME] = 1; - - rv = tcsetattr(fd, TCSANOW, &term); - assert(rv == 0); -} - -static void uart_bridge_master_service(intercom_packet *packet, void *arg) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - uart_bridge_master_context *ctx = arg; - - sc = rtems_chain_append_with_notification( - &ctx->transmit_fifo, - &packet->glue.node, - ctx->transmit_task, - TRANSMIT_EVENT - ); - assert(sc == RTEMS_SUCCESSFUL); -} - -static void receive_task(rtems_task_argument arg) -{ - uart_bridge_master_context *ctx = (uart_bridge_master_context *) arg; - intercom_type type = ctx->type; - - int fd = open(ctx->device_path, O_RDONLY); - assert(fd >= 0); - - serial_settings(fd); - - while (true) { - intercom_packet *packet = qoriq_intercom_allocate_packet( - type, - INTERCOM_SIZE_64 - ); - ssize_t in = read(fd, packet->data, packet->size - 1); - if (in > 0) { - packet->size = (size_t) in; - qoriq_intercom_send_packet(QORIQ_UART_BRIDGE_SLAVE_CORE, packet); - } else { - qoriq_intercom_free_packet(packet); - } - } -} - -static void transmit_task(rtems_task_argument arg) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - uart_bridge_master_context *ctx = (uart_bridge_master_context *) arg; - rtems_chain_control *fifo = &ctx->transmit_fifo; - - int fd = open(ctx->device_path, O_WRONLY); - assert(fd >= 0); - - serial_settings(fd); - - while (true) { - intercom_packet *packet = NULL; - sc = rtems_chain_get_with_wait( - fifo, - TRANSMIT_EVENT, - RTEMS_NO_TIMEOUT, - (rtems_chain_node **) &packet - ); - assert(sc == RTEMS_SUCCESSFUL); - write(fd, packet->data, packet->size); - qoriq_intercom_free_packet(packet); - } -} - -static rtems_id create_task( - char name, - rtems_task_entry entry, - uart_bridge_master_context *ctx -) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - rtems_id task = RTEMS_ID_NONE; - char index = (char) ('0' + ctx->type - INTERCOM_TYPE_UART_0); - - sc = rtems_task_create( - rtems_build_name('U', 'B', name, index), - QORIQ_UART_BRIDGE_TASK_PRIORITY, - 0, - RTEMS_DEFAULT_MODES, - RTEMS_DEFAULT_ATTRIBUTES, - &task - ); - assert(sc == RTEMS_SUCCESSFUL); - - sc = rtems_task_start( - task, - entry, - (rtems_task_argument) ctx - ); - assert(sc == RTEMS_SUCCESSFUL); - - return task; -} - -bool qoriq_uart_bridge_master_probe(rtems_termios_device_context *base) -{ - uart_bridge_master_context *ctx = (uart_bridge_master_context *) base; - intercom_type type = ctx->type; - - qoriq_intercom_service_install(type, uart_bridge_master_service, ctx); - create_task('R', receive_task, ctx); - ctx->transmit_task = create_task('T', transmit_task, ctx); - - return true; -} - -static bool first_open( - struct rtems_termios_tty *tty, - rtems_termios_device_context *base, - struct termios *term, - rtems_libio_open_close_args_t *args -) -{ - return false; -} - -static bool set_attributes( - rtems_termios_device_context *base, - const struct termios *term -) -{ - return false; -} - -const rtems_termios_device_handler qoriq_uart_bridge_master = { - .first_open = first_open, - .set_attributes = set_attributes, - .mode = TERMIOS_POLLED -}; diff --git a/c/src/lib/libbsp/powerpc/qoriq/console/uart-bridge-slave.c b/c/src/lib/libbsp/powerpc/qoriq/console/uart-bridge-slave.c deleted file mode 100644 index 44d4cfb712..0000000000 --- a/c/src/lib/libbsp/powerpc/qoriq/console/uart-bridge-slave.c +++ /dev/null @@ -1,195 +0,0 @@ -/** - * @file - * - * @ingroup QorIQUartBridge - * - * @brief UART bridge slave implementation. - */ - -/* - * Copyright (c) 2011 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Obere Lagerstr. 30 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include - -#include -#include - -#define TRANSMIT_EVENT RTEMS_EVENT_13 - -static rtems_mode disable_preemption(void) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - rtems_mode prev_mode = 0; - - sc = rtems_task_mode (RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &prev_mode); - assert(sc == RTEMS_SUCCESSFUL); - - return prev_mode; -} - -static void restore_preemption(rtems_mode prev_mode) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - - sc = rtems_task_mode (prev_mode, RTEMS_PREEMPT_MASK, &prev_mode); - assert(sc == RTEMS_SUCCESSFUL); -} - -static void uart_bridge_slave_service(intercom_packet *packet, void *arg) -{ - uart_bridge_slave_context *ctx = arg; - struct rtems_termios_tty *tty = ctx->tty; - - /* Workaround for https://www.rtems.org/bugzilla/show_bug.cgi?id=1736 */ - rtems_mode prev_mode = disable_preemption(); - - rtems_termios_enqueue_raw_characters(tty, packet->data, (int) packet->size); - qoriq_intercom_free_packet(packet); - - restore_preemption(prev_mode); -} - -static void transmit_task(rtems_task_argument arg) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - uart_bridge_slave_context *ctx = (uart_bridge_slave_context *) arg; - rtems_chain_control *fifo = &ctx->transmit_fifo; - struct rtems_termios_tty *tty = ctx->tty; - - while (true) { - intercom_packet *packet = NULL; - sc = rtems_chain_get_with_wait( - fifo, - TRANSMIT_EVENT, - RTEMS_NO_TIMEOUT, - (rtems_chain_node **) &packet - ); - assert(sc == RTEMS_SUCCESSFUL); - - /* Workaround for https://www.rtems.org/bugzilla/show_bug.cgi?id=1736 */ - rtems_mode prev_mode = disable_preemption(); - - size_t size = packet->size; - qoriq_intercom_send_packet(QORIQ_UART_BRIDGE_MASTER_CORE, packet); - rtems_termios_dequeue_characters(tty, (int) size); - - restore_preemption(prev_mode); - } -} - -static void create_transmit_task( - uart_bridge_slave_context *ctx -) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - rtems_id task = RTEMS_ID_NONE; - char index = (char) ('0' + ctx->type - INTERCOM_TYPE_UART_0); - - sc = rtems_task_create( - rtems_build_name('U', 'B', 'T', index), - QORIQ_UART_BRIDGE_TASK_PRIORITY, - 0, - RTEMS_DEFAULT_MODES, - RTEMS_DEFAULT_ATTRIBUTES, - &task - ); - assert(sc == RTEMS_SUCCESSFUL); - - sc = rtems_task_start( - task, - transmit_task, - (rtems_task_argument) ctx - ); - assert(sc == RTEMS_SUCCESSFUL); - - ctx->transmit_task = task; -} - -static bool first_open( - struct rtems_termios_tty *tty, - rtems_termios_device_context *base, - struct termios *term, - rtems_libio_open_close_args_t *args -) -{ - uart_bridge_slave_context *ctx = (uart_bridge_slave_context *) base; - intercom_type type = ctx->type; - - ctx->tty = tty; - rtems_termios_set_initial_baud(tty, 115200); - create_transmit_task(ctx); - qoriq_intercom_service_install(type, uart_bridge_slave_service, ctx); - - return true; -} - -static void last_close( - struct rtems_termios_tty *tty, - rtems_termios_device_context *base, - rtems_libio_open_close_args_t *args -) -{ - uart_bridge_slave_context *ctx = (uart_bridge_slave_context *) base; - - qoriq_intercom_service_remove(ctx->type); -} - -static void write_with_interrupts( - rtems_termios_device_context *base, - const char *buf, - size_t len -) -{ - if (len > 0) { - rtems_status_code sc = RTEMS_SUCCESSFUL; - uart_bridge_slave_context *ctx = (uart_bridge_slave_context *) base; - intercom_packet *packet = qoriq_intercom_allocate_packet( - ctx->type, - INTERCOM_SIZE_64 - ); - - packet->size = len; - memcpy(packet->data, buf, len); - - /* - * Due to the lovely Termios implementation we have to hand this over to - * another context. - */ - sc = rtems_chain_append_with_notification( - &ctx->transmit_fifo, - &packet->glue.node, - ctx->transmit_task, - TRANSMIT_EVENT - ); - assert(sc == RTEMS_SUCCESSFUL); - } -} - -static bool set_attributes( - rtems_termios_device_context *base, - const struct termios *term -) -{ - return false; -} - -const rtems_termios_device_handler qoriq_uart_bridge_slave = { - .first_open = first_open, - .last_close = last_close, - .write = write_with_interrupts, - .set_attributes = set_attributes, - .mode = TERMIOS_IRQ_DRIVEN -}; diff --git a/c/src/lib/libbsp/powerpc/shared/console/console.c b/c/src/lib/libbsp/powerpc/shared/console/console.c deleted file mode 100644 index f275683cc2..0000000000 --- a/c/src/lib/libbsp/powerpc/shared/console/console.c +++ /dev/null @@ -1,314 +0,0 @@ -/* - * console.c -- console I/O package - * - * Copyright (C) 1999 Eric Valette. valette@crf.canon.fr - * - * This code is based on the pc386 BSP console.c so the following - * copyright also applies : - * - * (C) Copyright 1997 - - * - NavIST Group - Real-Time Distributed Systems and Industrial Automation - * - * Till Straumann, , 12/20/2001 - * separate BSP specific stuff from generics... - * - * http://pandora.ist.utl.pt - * - * Instituto Superior Tecnico * Lisboa * PORTUGAL - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include /* printk */ - -/* Definitions for BSPConsolePort */ -/* - * Possible value for console input/output : - * BSP_CONSOLE_PORT_CONSOLE - * BSP_UART_COM1 - * BSP_UART_COM2 - */ -int BSPConsolePort = BSP_CONSOLE_PORT; - -int BSPBaseBaud = BSP_UART_BAUD_BASE; - -/* - * TERMIOS_OUTPUT_MODE should be a 'bspopts.h/configure'-able option; - * we could even make it a link-time option (but that would require - * small changes)... - */ -#if defined(USE_POLLED_IO) - #define TERMIOS_OUTPUT_MODE TERMIOS_POLLED -#elif defined(USE_TASK_DRIVEN_IO) - #define TERMIOS_OUTPUT_MODE TERMIOS_TASK_DRIVEN -#else - #define TERMIOS_OUTPUT_MODE TERMIOS_IRQ_DRIVEN -#endif - -/*-------------------------------------------------------------------------+ -| External Prototypes -+--------------------------------------------------------------------------*/ - -static int conSetAttr(int minor, const struct termios *); - -typedef struct TtySTblRec_ { - char *name; - rtems_irq_hdl isr; -} TtySTblRec, *TtySTbl; - -static TtySTblRec ttyS[]={ - { "/dev/ttyS0", -#ifdef BSP_UART_IOBASE_COM1 - BSP_uart_termios_isr_com1 -#else - 0 -#endif - }, - { "/dev/ttyS1", -#ifdef BSP_UART_IOBASE_COM2 - BSP_uart_termios_isr_com2 -#else - 0 -#endif - }, -}; - -/*-------------------------------------------------------------------------+ -| Console device driver INITIALIZE entry point. -+--------------------------------------------------------------------------+ -| Initilizes the I/O console (keyboard + VGA display) driver. -+--------------------------------------------------------------------------*/ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - - /* - * The video was initialized in the start.s code and does not need - * to be reinitialized. - */ - - /* - * Set up TERMIOS - */ - rtems_termios_initialize(); - - /* - * Do device-specific initialization - */ - - /* RTEMS calls this routine once with 'minor'==0; loop through - * all known instances... - */ - - for (minor=0; minor < sizeof(ttyS)/sizeof(ttyS[0]); minor++) { - char *nm; - /* - * Skip ports (possibly not supported by BSP...) we have no ISR for - */ - if ( ! ttyS[minor].isr ) - continue; - /* - * Register the device - */ - status = rtems_io_register_name ((nm=ttyS[minor].name), major, minor); - if ( RTEMS_SUCCESSFUL==status && BSPConsolePort == minor) { - printk("Registering /dev/console as minor %" PRIu32 " (==%s)\n", - minor, - ttyS[minor].name); - /* also register an alias */ - status = rtems_io_register_name ( (nm="/dev/console"), major, minor); - } - - if (status != RTEMS_SUCCESSFUL) { - printk("Error registering %s!\n",nm); - rtems_fatal_error_occurred (status); - } - } - - return RTEMS_SUCCESSFUL; -} /* console_initialize */ - -#if !defined(USE_POLLED_IO) -static int console_first_open(int major, int minor, void *arg) -{ - rtems_status_code status; - - /* must not open a minor device we have no ISR for */ - assert( minor>=0 && minor < sizeof(ttyS)/sizeof(ttyS[0]) && ttyS[minor].isr ); - - /* 9600-8-N-1 */ - BSP_uart_init(minor, 9600, 0); - status = BSP_uart_install_isr(minor, ttyS[minor].isr); - if (!status) { - printk("Error installing serial console interrupt handler for '%s'!\n", - ttyS[minor].name); - rtems_fatal_error_occurred(status); - } - - /* - * Pass data area info down to driver - */ - BSP_uart_termios_set(minor, ((rtems_libio_open_close_args_t *)arg)->iop->data1); - - /* Enable interrupts on channel */ - BSP_uart_intr_ctrl(minor, BSP_UART_INTR_CTRL_TERMIOS); - - return 0; -} -#endif - -#if !defined(USE_POLLED_IO) -static int console_last_close(int major, int minor, void *arg) -{ - BSP_uart_remove_isr(minor, ttyS[minor].isr); - return 0; -} -#endif - -/*-------------------------------------------------------------------------+ -| Console device driver OPEN entry point -+--------------------------------------------------------------------------*/ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - static rtems_termios_callbacks cb = -#if defined(USE_POLLED_IO) - { - NULL, /* firstOpen */ - NULL, /* lastClose */ - NULL, /* pollRead */ - BSP_uart_termios_write_polled, /* write */ - conSetAttr, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_POLLED /* outputUsesInterrupts */ - }; -#else - { - console_first_open, /* firstOpen */ - console_last_close, /* lastClose */ -#ifdef USE_TASK_DRIVEN_IO - BSP_uart_termios_read_com, /* pollRead */ -#else - NULL, /* pollRead */ -#endif - BSP_uart_termios_write_com, /* write */ - conSetAttr, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_OUTPUT_MODE /* outputUsesInterrupts */ - }; -#endif - - status = rtems_termios_open (major, minor, arg, &cb); - - if (status != RTEMS_SUCCESSFUL) { - printk("Error opening console device\n"); - return status; - } - - return RTEMS_SUCCESSFUL; -} - -/*-------------------------------------------------------------------------+ -| Console device driver CLOSE entry point -+--------------------------------------------------------------------------*/ -rtems_device_driver -console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_device_driver res = RTEMS_SUCCESSFUL; - - res = rtems_termios_close (arg); - - return res; -} /* console_close */ - -/*-------------------------------------------------------------------------+ -| Console device driver READ entry point. -+--------------------------------------------------------------------------+ -| Read characters from the I/O console. We only have stdin. -+--------------------------------------------------------------------------*/ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - return rtems_termios_read (arg); -} /* console_read */ - -/*-------------------------------------------------------------------------+ -| Console device driver WRITE entry point. -+--------------------------------------------------------------------------+ -| Write characters to the I/O console. Stderr and stdout are the same. -+--------------------------------------------------------------------------*/ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - return rtems_termios_write (arg); -} /* console_write */ - -/* - * Handle ioctl request. - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ -/* does the BSP support break callbacks ? */ -#if defined(BIOCSETBREAKCB) && defined(BIOCGETBREAKCB) - rtems_libio_ioctl_args_t *ioa=arg; - switch (ioa->command) { - case BIOCSETBREAKCB: return BSP_uart_set_break_cb(minor, ioa); - case BIOCGETBREAKCB: return BSP_uart_get_break_cb(minor, ioa); - default: break; - } -#endif - return rtems_termios_ioctl (arg); -} - -static int conSetAttr( - int minor, - const struct termios *t -) -{ - rtems_termios_baud_t baud; - - baud = rtems_termios_baud_to_number(t->c_ospeed); - if ( baud > 115200 ) - rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR); - - BSP_uart_set_baud(minor, baud); - - return 0; -} diff --git a/c/src/lib/libbsp/powerpc/shared/console/uart.c b/c/src/lib/libbsp/powerpc/shared/console/uart.c deleted file mode 100644 index 62212b98db..0000000000 --- a/c/src/lib/libbsp/powerpc/shared/console/uart.c +++ /dev/null @@ -1,781 +0,0 @@ -/* - * This software is Copyright (C) 1998 by T.sqware - all rights limited - * It is provided in to the public domain "as is", can be freely modified - * as far as this copyight notice is kept unchanged, but does not imply - * an endorsement by T.sqware of the product in which it is included. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Basic 16552 driver - */ - -struct uart_data -{ - unsigned long ioBase; - int irq; - int hwFlow; - int baud; - BSP_UartBreakCbRec breakCallback; - int ioMode; -}; - -/* - * Initialization of BSP specific data. - * The constants are pulled in from a BSP - * specific file, whereas all of the code - * in this file is generic and makes no - * assumptions about addresses, irq vectors - * etc... - */ - -#define UART_UNSUPP ((unsigned long)(-1)) - -static struct uart_data uart_data[2] = { - { -#ifdef BSP_UART_IOBASE_COM1 - BSP_UART_IOBASE_COM1, - BSP_UART_COM1_IRQ, -#else - UART_UNSUPP, - -1, -#endif - }, - { -#ifdef BSP_UART_IOBASE_COM2 - BSP_UART_IOBASE_COM2, - BSP_UART_COM2_IRQ, -#else - UART_UNSUPP, - -1, -#endif - }, -}; - -#define MAX_UARTS (sizeof(uart_data)/sizeof(uart_data[0])) -#define SANITY_CHECK(uart) \ - assert( MAX_UARTS > (unsigned)(uart) && uart_data[(uart)].ioBase != UART_UNSUPP ) -/* - * Macros to read/write register of uart, if configuration is - * different just rewrite these macros - */ - -static inline unsigned char -uread(int uart, unsigned int reg) -{ - return in_8((uint8_t*)(uart_data[uart].ioBase + reg)); -} - -static inline void -uwrite(int uart, int reg, unsigned int val) -{ - out_8((uint8_t*)(uart_data[uart].ioBase + reg), val); -} - - -static void -uartError(int uart, void *termiosPrivate) -{ - unsigned char uartStatus, dummy; - BSP_UartBreakCbProc h; - - uartStatus = uread(uart, LSR); - dummy = uread(uart, RBR); - -#ifdef UARTDEBUG - if (uartStatus & OE) - printk("********* Over run Error **********\n"); - if (uartStatus & PE) - printk("********* Parity Error **********\n"); - if (uartStatus & FE) - printk("********* Framing Error **********\n"); - if (uartStatus & BI) { - printk("********* BREAK INTERRUPT *********\n"); -#endif - if ((h=uart_data[uart].breakCallback.handler)) { - h(uart, - (dummy<<8)|uartStatus, - termiosPrivate, - uart_data[uart].breakCallback.private); - } -#ifdef UARTDEBUG - if (uartStatus & ERFIFO) - printk("********* Error receive Fifo **********\n"); -#endif -} - -/* - * Uart initialization, it is hardcoded to 8 bit, no parity, - * one stop bit, FIFO, things to be changed - * are baud rate and nad hw flow control, - * and longest rx fifo setting - */ -void -BSP_uart_init(int uart, int baud, int hwFlow) -{ - unsigned char tmp; - - /* Sanity check */ - SANITY_CHECK(uart); - - /* Make sure any printk activity drains before - * re-initializing. - */ - while ( ! (uread(uart, LSR) & TEMT) ) - ; - - switch(baud) - { - case 50: - case 75: - case 110: - case 134: - case 300: - case 600: - case 1200: - case 2400: - case 9600: - case 19200: - case 38400: - case 57600: - case 115200: - break; - default: - assert(0); - return; - } - - /* Set DLAB bit to 1 */ - uwrite(uart, LCR, DLAB); - - if ( (int)BSPBaseBaud <= 0 ) { - /* Use current divisor assuming BSPBaseBaud gives us the current speed */ - BSPBaseBaud = BSPBaseBaud ? -BSPBaseBaud : 9600; - BSPBaseBaud *= ((uread(uart, DLM) << 8) | uread(uart, DLL)); - } - - /* Set baud rate */ - uwrite(uart, DLL, (BSPBaseBaud/baud) & 0xff); - uwrite(uart, DLM, ((BSPBaseBaud/baud) >> 8) & 0xff); - - /* 8-bit, no parity , 1 stop */ - uwrite(uart, LCR, CHR_8_BITS); - - /* Set DTR, RTS and OUT2 high */ - uwrite(uart, MCR, DTR | RTS | OUT_2); - - /* Enable FIFO */ - uwrite(uart, FCR, FIFO_EN | XMIT_RESET | RCV_RESET | RECEIVE_FIFO_TRIGGER12); - - /* Disable Interrupts */ - uwrite(uart, IER, 0); - - /* Read status to clear them */ - tmp = uread(uart, LSR); - tmp = uread(uart, RBR); - tmp = uread(uart, MSR); - (void) tmp; /* avoid set but not used warning */ - - /* Remember state */ - uart_data[uart].hwFlow = hwFlow; - uart_data[uart].baud = baud; - return; -} - -/* - * Set baud - */ -void -BSP_uart_set_baud(int uart, int baud) -{ - unsigned char mcr, ier; - - /* Sanity check */ - SANITY_CHECK(uart); - - /* - * This function may be called whenever TERMIOS parameters - * are changed, so we have to make sure that baud change is - * indeed required. - */ - - if(baud == uart_data[uart].baud) - { - return; - } - - mcr = uread(uart, MCR); - ier = uread(uart, IER); - - BSP_uart_init(uart, baud, uart_data[uart].hwFlow); - - uwrite(uart, MCR, mcr); - uwrite(uart, IER, ier); - - return; -} - -/* - * Enable/disable interrupts - */ -void -BSP_uart_intr_ctrl(int uart, int cmd) -{ - - SANITY_CHECK(uart); - - switch(cmd) - { - case BSP_UART_INTR_CTRL_DISABLE: - uwrite(uart, IER, INTERRUPT_DISABLE); - break; - case BSP_UART_INTR_CTRL_ENABLE: - if(uart_data[uart].hwFlow) - { - uwrite(uart, IER, - (RECEIVE_ENABLE | - TRANSMIT_ENABLE | - RECEIVER_LINE_ST_ENABLE | - MODEM_ENABLE - ) - ); - } - else - { - uwrite(uart, IER, - (RECEIVE_ENABLE | - TRANSMIT_ENABLE | - RECEIVER_LINE_ST_ENABLE - ) - ); - } - break; - case BSP_UART_INTR_CTRL_TERMIOS: - if(uart_data[uart].hwFlow) - { - uwrite(uart, IER, - (RECEIVE_ENABLE | - RECEIVER_LINE_ST_ENABLE | - MODEM_ENABLE - ) - ); - } - else - { - uwrite(uart, IER, - (RECEIVE_ENABLE | - RECEIVER_LINE_ST_ENABLE - ) - ); - } - break; - case BSP_UART_INTR_CTRL_GDB: - uwrite(uart, IER, RECEIVE_ENABLE); - break; - default: - assert(0); - break; - } - - return; -} - -void -BSP_uart_throttle(int uart) -{ - unsigned int mcr; - - SANITY_CHECK(uart); - - if(!uart_data[uart].hwFlow) - { - /* Should not happen */ - assert(0); - return; - } - mcr = uread (uart, MCR); - /* RTS down */ - mcr &= ~RTS; - uwrite(uart, MCR, mcr); - - return; -} - -void -BSP_uart_unthrottle(int uart) -{ - unsigned int mcr; - - SANITY_CHECK(uart); - - if(!uart_data[uart].hwFlow) - { - /* Should not happen */ - assert(0); - return; - } - mcr = uread (uart, MCR); - /* RTS up */ - mcr |= RTS; - uwrite(uart, MCR, mcr); - - return; -} - -/* - * Status function, -1 if error - * detected, 0 if no received chars available, - * 1 if received char available, 2 if break - * is detected, it will eat break and error - * chars. It ignores overruns - we cannot do - * anything about - it execpt count statistics - * and we are not counting it. - */ -int -BSP_uart_polled_status(int uart) -{ - unsigned char val; - - SANITY_CHECK(uart); - - val = uread(uart, LSR); - - if(val & BI) - { - /* BREAK found, eat character */ - uread(uart, RBR); - return BSP_UART_STATUS_BREAK; - } - - if((val & (DR | OE | FE)) == 1) - { - /* No error, character present */ - return BSP_UART_STATUS_CHAR; - } - - if((val & (DR | OE | FE)) == 0) - { - /* Nothing */ - return BSP_UART_STATUS_NOCHAR; - } - - /* - * Framing or parity error - * eat character - */ - uread(uart, RBR); - - return BSP_UART_STATUS_ERROR; -} - -/* - * Polled mode write function - */ -void -BSP_uart_polled_write(int uart, int val) -{ - unsigned char val1; - - /* Sanity check */ - SANITY_CHECK(uart); - - for(;;) - { - if((val1=uread(uart, LSR)) & THRE) - { - break; - } - } - - if(uart_data[uart].hwFlow) - { - for(;;) - { - if(uread(uart, MSR) & CTS) - { - break; - } - } - } - - uwrite(uart, THR, val & 0xff); - - return; -} - -void -BSP_output_char_via_serial(const char val) -{ - BSP_uart_polled_write(BSPConsolePort, val); -} - -/* - * Polled mode read function - */ -int -BSP_uart_polled_read(int uart) -{ - unsigned char val; - - SANITY_CHECK(uart); - - for(;;) - { - if(uread(uart, LSR) & DR) - { - break; - } - } - - val = uread(uart, RBR); - - return (int)(val & 0xff); -} - -unsigned -BSP_poll_char_via_serial() -{ - return BSP_uart_polled_read(BSPConsolePort); -} - -static void -uart_noop(const rtems_irq_connect_data *unused) -{ - return; -} - -/* note that the IRQ names contain _ISA_ for legacy - * reasons. They can be any interrupt, depending - * on the particular BSP... - */ - -static int -uart_isr_is_on(const rtems_irq_connect_data *irq) -{ - int uart; - - uart = (irq->name == BSP_UART_COM1_IRQ) ? - BSP_UART_COM1 : BSP_UART_COM2; - - return uread(uart,IER); -} - -static int -doit(int uart, rtems_irq_hdl handler, int (*p)(const rtems_irq_connect_data*)) -{ - rtems_irq_connect_data d={0}; - d.name = uart_data[uart].irq; - d.off = d.on = uart_noop; - d.isOn = uart_isr_is_on; - d.hdl = handler; - return p(&d); -} - -int -BSP_uart_install_isr(int uart, rtems_irq_hdl handler) -{ -/* Using shared interrupts by default might break things.. the - * shared IRQ installer uses malloc() and if a BSP had called this - * during early init it might not work... - */ -#ifdef BSP_UART_USE_SHARED_IRQS - return doit(uart, handler, BSP_install_rtems_shared_irq_handler); -#else - return doit(uart, handler, BSP_install_rtems_irq_handler); -#endif -} - -int -BSP_uart_remove_isr(int uart, rtems_irq_hdl handler) -{ - return doit(uart, handler, BSP_remove_rtems_irq_handler); -} - -/* ================ Termios support =================*/ - -static volatile int termios_stopped_com[2] = {0,0}; -static volatile int termios_tx_active_com[2] = {0,0}; -static void* termios_ttyp_com[2] = {NULL,NULL}; -static char termios_tx_hold_com[2] = {0,0}; -static volatile char termios_tx_hold_valid_com[2] = {0,0}; - -/* - * Set channel parameters - */ -void -BSP_uart_termios_set(int uart, void *p) -{ - struct rtems_termios_tty *ttyp = p; - unsigned char val; - SANITY_CHECK(uart); - - if(uart_data[uart].hwFlow) - { - val = uread(uart, MSR); - - termios_stopped_com[uart] = (val & CTS) ? 0 : 1; - } - else - { - termios_stopped_com[uart] = 0; - } - termios_tx_active_com[uart] = 0; - termios_ttyp_com[uart] = ttyp; - termios_tx_hold_com[uart] = 0; - termios_tx_hold_valid_com[uart] = 0; - - uart_data[uart].ioMode = ttyp->device.outputUsesInterrupts; - - return; -} - -ssize_t -BSP_uart_termios_write_polled(int minor, const char *buf, size_t len) -{ - int uart=minor; /* could differ, theoretically */ - int nwrite; - const char *b = buf; - - for (nwrite=0 ; nwrite < len ; nwrite++) { - BSP_uart_polled_write(uart, *b++); - } - return nwrite; -} - -ssize_t -BSP_uart_termios_write_com(int minor, const char *buf, size_t len) -{ - int uart=minor; /* could differ, theoretically */ - - if(len <= 0) - { - return 0; - } - - /* If the TX buffer is busy - something is royally screwed up */ - /* assert((uread(BSP_UART_COM1, LSR) & THRE) != 0); */ - - if(termios_stopped_com[uart]) - { - /* CTS low */ - termios_tx_hold_com[uart] = *buf; - termios_tx_hold_valid_com[uart] = 1; - return 0; - } - - /* Write character */ - uwrite(uart, THR, *buf & 0xff); - - /* Enable interrupts if necessary */ - if(!termios_tx_active_com[uart] && uart_data[uart].hwFlow) - { - termios_tx_active_com[uart] = 1; - uwrite(uart, IER, - (RECEIVE_ENABLE | - TRANSMIT_ENABLE | - RECEIVER_LINE_ST_ENABLE | - MODEM_ENABLE - ) - ); - } - else if(!termios_tx_active_com[uart]) - { - termios_tx_active_com[uart] = 1; - uwrite(uart, IER, - (RECEIVE_ENABLE | - TRANSMIT_ENABLE | - RECEIVER_LINE_ST_ENABLE - ) - ); - } - - return 0; -} - -int -BSP_uart_termios_read_com(int uart) -{ - int off = (int)0; - char buf[40]; - rtems_interrupt_level l; - - /* read bytes */ - while (( off < sizeof(buf) ) && ( uread(uart, LSR) & DR )) { - buf[off++] = uread(uart, RBR); - } - - /* write out data */ - if ( off > 0 ) { - rtems_termios_enqueue_raw_characters(termios_ttyp_com[uart], buf, off); - } - - /* enable receive interrupts */ - rtems_interrupt_disable(l); - uwrite(uart, IER, uread(uart, IER) | (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE)); - rtems_interrupt_enable(l); - - return ( EOF ); -} - -static void -BSP_uart_termios_isr_com(int uart) -{ - unsigned char buf[40]; - unsigned char val, ier; - int off, ret, vect; - - off = 0; - - for(;;) - { - vect = uread(uart, IIR) & 0xf; - - switch(vect) - { - case MODEM_STATUS : - val = uread(uart, MSR); - if(uart_data[uart].hwFlow) - { - if(val & CTS) - { - /* CTS high */ - termios_stopped_com[uart] = 0; - if(termios_tx_hold_valid_com[uart]) - { - termios_tx_hold_valid_com[uart] = 0; - BSP_uart_termios_write_com(uart, &termios_tx_hold_com[uart], - 1); - } - } - else - { - /* CTS low */ - termios_stopped_com[uart] = 1; - } - } - break; - case NO_MORE_INTR : - /* No more interrupts */ - if(off != 0) - { - /* Update rx buffer */ - rtems_termios_enqueue_raw_characters(termios_ttyp_com[uart], - (char *)buf, - off); - } - return; - case TRANSMITTER_HODING_REGISTER_EMPTY : - /* - * TX holding empty: we have to disable these interrupts - * if there is nothing more to send. - */ - - ret = rtems_termios_dequeue_characters(termios_ttyp_com[uart], 1); - - /* If nothing else to send disable interrupts */ - if(ret == 0 && uart_data[uart].hwFlow) - { - uwrite(uart, IER, - (RECEIVE_ENABLE | - RECEIVER_LINE_ST_ENABLE | - MODEM_ENABLE - ) - ); - termios_tx_active_com[uart] = 0; - } - else if(ret == 0) - { - uwrite(uart, IER, - (RECEIVE_ENABLE | - RECEIVER_LINE_ST_ENABLE - ) - ); - termios_tx_active_com[uart] = 0; - } - break; - case RECEIVER_DATA_AVAIL : - case CHARACTER_TIMEOUT_INDICATION: - if ( uart_data[uart].ioMode == TERMIOS_TASK_DRIVEN ) - { - /* ensure interrupts are enabled */ - if ( (ier = uread(uart,IER)) & RECEIVE_ENABLE ) - { - /* disable interrupts and notify termios */ - ier &= ~(RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE); - uwrite(uart, IER, ier); - rtems_termios_rxirq_occured(termios_ttyp_com[uart]); - } - } - else - { - /* RX data ready */ - assert(off < sizeof(buf)); - while ( off < sizeof(buf) && ( DR & uread(uart, LSR) ) ) - buf[off++] = uread(uart, RBR); - } - break; - case RECEIVER_ERROR: - /* RX error: eat character */ - uartError(uart, termios_ttyp_com[uart]); - break; - default: - /* Should not happen */ - assert(0); - return; - } - } -} - -/* - * XXX - Note that this can now be one isr with the uart - * passed as the parameter. - */ -void -BSP_uart_termios_isr_com1(void *unused) -{ - BSP_uart_termios_isr_com(BSP_UART_COM1); -} - -void -BSP_uart_termios_isr_com2(void *unused) -{ - BSP_uart_termios_isr_com(BSP_UART_COM2); -} - -/* retrieve 'break' handler info */ -int -BSP_uart_get_break_cb(int uart, rtems_libio_ioctl_args_t *arg) -{ -BSP_UartBreakCb cb=arg->buffer; -unsigned long flags; - SANITY_CHECK(uart); - rtems_interrupt_disable(flags); - *cb = uart_data[uart].breakCallback; - rtems_interrupt_enable(flags); - arg->ioctl_return=0; - return RTEMS_SUCCESSFUL; -} - -/* install 'break' handler */ -int -BSP_uart_set_break_cb(int uart, rtems_libio_ioctl_args_t *arg) -{ -BSP_UartBreakCb cb=arg->buffer; -unsigned long flags; - SANITY_CHECK(uart); - rtems_interrupt_disable(flags); - uart_data[uart].breakCallback = *cb; - rtems_interrupt_enable(flags); - arg->ioctl_return=0; - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/lib/libbsp/powerpc/ss555/Makefile.am b/c/src/lib/libbsp/powerpc/ss555/Makefile.am index 1c5142c263..a9b5397c9f 100644 --- a/c/src/lib/libbsp/powerpc/ss555/Makefile.am +++ b/c/src/lib/libbsp/powerpc/ss555/Makefile.am @@ -19,7 +19,7 @@ librtemsbsp_a_SOURCES = # pclock librtemsbsp_a_SOURCES +=../../../../../../bsps/powerpc/ss555/clock/p_clock.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/ss555/console/console.c # startup librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspfatal-default.c librtemsbsp_a_SOURCES += startup/bspstart.c diff --git a/c/src/lib/libbsp/powerpc/ss555/console/console.c b/c/src/lib/libbsp/powerpc/ss555/console/console.c deleted file mode 100644 index e13e4734ea..0000000000 --- a/c/src/lib/libbsp/powerpc/ss555/console/console.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * console.c - * - * This file contains the Intec SS555 termios serial I/O package. - * - * The SCI channels are assigned as follows - * - * Channel Device Minor - * SCI1 /dev/tty0 0 - * SCI2 /dev/tty1 1 - * - * All ports support termios. The use of termios is recommended for real-time - * applications. Termios provides buffering and input processing. When not - * using termios, processing is limited to the substitution of LF for CR on - * input, and the output of a CR following the output of a LF character. - * Note that the terminal should not send CR/LF pairs when the return key - * is pressed, and that output lines are terminated with LF/CR, not CR/LF - * (although that would be easy to change). - * - * I/O may be interrupt-driven (recommended for real-time applications) or - * polled. - * - * LIMITATIONS: - * - * It is not possible to use different I/O modes on the different ports. The - * exception is with printk. The printk port can use a different mode from - * the other ports. If this is done, it is important not to open the printk - * port from an RTEMS application. - * - * Currently, the I/O modes are determined at build time. It would be much - * better to have the mode selected at boot time based on parameters in - * NVRAM. - * - * Interrupt-driven I/O requires termios. - * - * TESTS: - * - * TO RUN THE TESTS, USE POLLED I/O WITHOUT TERMIOS SUPPORT. Some tests - * play with the interrupt masks and turn off I/O. Those tests will hang - * when interrupt-driven I/O is used. Other tests, such as cdtest, do I/O - * from the static constructors before the console is open. This test - * will not work with interrupt-driven I/O. Because of the buffering - * performed in termios, test output may not be in sequence.The tests - * should all be fixed to work with interrupt-driven I/O and to - * produce output in the expected sequence. Obviously, the termios test - * requires termios support in the driver. - * - * Set CONSOLE_MINOR to the appropriate device minor number in the - * config file. This allows the RTEMS application console to be different - * from the GDB port. - * - * This driver handles both available serial ports: it distinguishes - * the sub-devices using minor device numbers. It is not possible to have - * other protocols running on the other ports when this driver is used as - * currently written. - * - * - * SS555 port sponsored by Defence Research and Development Canada - Suffield - * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca) - * - * Derived from c/src/lib/libbsp/powerpc/mbx8xx/console/console.c: - * - * Based on code (alloc860.c in eth_comm port) by - * Jay Monkman (jmonkman@frasca.com), - * Copyright (C) 1998 by Frasca International, Inc. - * - * Modifications by Darlene Stewart - * and Charles-Antoine Gauthier . - * Copyright (c) 2000, National Research Council of Canada - * - */ -#include -#include -#include - -#include -#include -#include -#include /* Must be before libio.h */ - -static void _BSP_output_char( char c ); -static rtems_status_code do_poll_read( rtems_device_major_number major, rtems_device_minor_number minor, void * arg); -static rtems_status_code do_poll_write( rtems_device_major_number major, rtems_device_minor_number minor, void * arg); - -static void _BSP_null_char( char c ) {return;} - -BSP_output_char_function_type BSP_output_char = _BSP_null_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - -/* - * do_poll_read - * - * Input characters through polled I/O. Returns as soon as a character has - * been received. Otherwise, if we wait for the number of requested - * characters, we could be here forever! - * - * CR is converted to LF on input. The terminal should not send a CR/LF pair - * when the return or enter key is pressed. - * - * Input parameters: - * major - ignored. Should be the major number for this driver. - * minor - selected channel. - * arg->buffer - where to put the received characters. - * arg->count - number of characters to receive before returning--Ignored. - * - * Output parameters: - * arg->bytes_moved - the number of characters read. Always 1. - * - * Return value: RTEMS_SUCCESSFUL - * - * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! - */ -static rtems_status_code do_poll_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args = arg; - int c; - - while( (c = m5xx_uart_pollRead(minor)) == -1 ); - rw_args->buffer[0] = (uint8_t)c; - if( rw_args->buffer[0] == '\r' ) - rw_args->buffer[0] = '\n'; - rw_args->bytes_moved = 1; - - return RTEMS_SUCCESSFUL; -} - -/* - * do_poll_write - * - * Output characters through polled I/O. Returns only once every character has - * been sent. - * - * CR is transmitted AFTER a LF on output. - * - * Input parameters: - * major - ignored. Should be the major number for this driver. - * minor - selected channel - * arg->buffer - where to get the characters to transmit. - * arg->count - the number of characters to transmit before returning. - * - * Output parameters: - * arg->bytes_moved - the number of characters read - * - * Return value: RTEMS_SUCCESSFUL - * - * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! - */ -static rtems_status_code do_poll_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args = arg; - uint32_t i; - char cr ='\r'; - - for( i = 0; i < rw_args->count; i++ ) { - m5xx_uart_pollWrite(minor, &(rw_args->buffer[i]), 1); - if ( rw_args->buffer[i] == '\n' ) - m5xx_uart_pollWrite(minor, &cr, 1); - } - rw_args->bytes_moved = i; - - return RTEMS_SUCCESSFUL; -} - -/* - * Print functions prototyped in bspIo.h - */ - -static void _BSP_output_char( char c ) -{ - char cr = '\r'; - - /* - * Can't rely on console_initialize having been called before this - * function is used, so it may fail. - */ - - m5xx_uart_pollWrite( PRINTK_MINOR, &c, 1 ); - if( c == '\n' ) - m5xx_uart_pollWrite( PRINTK_MINOR, &cr, 1 ); -} - -/* - *************** - * BOILERPLATE * - *************** - * - * All these functions are prototyped in rtems/c/src/lib/include/console.h. - */ - -/* - * Initialize and register the device - */ -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - - /* - * Set up TERMIOS if needed - */ - #if UARTS_USE_TERMIOS == 1 - rtems_termios_initialize (); - #endif /* UARTS_USE_TERMIOS */ - - /* - * Do device-specific initialization - */ - BSP_output_char = _BSP_output_char; - - m5xx_uart_initialize(SCI1_MINOR); - status = rtems_io_register_name ("/dev/tty0", major, SCI1_MINOR); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - m5xx_uart_initialize(SCI2_MINOR); - status = rtems_io_register_name ("/dev/tty1", major, SCI2_MINOR); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - /* Now register the RTEMS console */ - status = rtems_io_register_name ("/dev/console", major, CONSOLE_MINOR); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - return RTEMS_SUCCESSFUL; -} - -/* - * Open the device - */ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code sc; - - if ( minor > NUM_PORTS - 1 ) - return RTEMS_INVALID_NUMBER; - - #if (UARTS_USE_TERMIOS == 1) - { - #if (UARTS_IO_MODE == 1) /* RTEMS interrupt-driven I/O with termios */ - - static const rtems_termios_callbacks callbacks = { - m5xx_uart_firstOpen, /* firstOpen */ - m5xx_uart_lastClose, /* lastClose */ - NULL, /* pollRead */ - m5xx_uart_write, /* write */ - m5xx_uart_setAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_IRQ_DRIVEN /* outputUsesInterrupts */ - }; - sc = rtems_termios_open( major, minor, arg, &callbacks ); - - #else /* UARTS_IO_MODE != 1 */ /* RTEMS polled I/O with termios */ - - static const rtems_termios_callbacks callbacks = { - m5xx_uart_firstOpen, /* firstOpen */ - m5xx_uart_lastClose, /* lastClose */ - m5xx_uart_pollRead, /* pollRead */ - m5xx_uart_pollWrite, /* write */ - m5xx_uart_setAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_POLLED /* outputUsesInterrupts */ - }; - sc = rtems_termios_open( major, minor, arg, &callbacks ); - - #endif - - return sc; - } - - #else /* no termios -- default to polled I/O */ - { - sc = RTEMS_SUCCESSFUL; - } - #endif - - return sc; -} - -/* - * Close the device - */ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - if ( minor > NUM_PORTS-1 ) - return RTEMS_INVALID_NUMBER; - - #if UARTS_USE_TERMIOS == 1 - return rtems_termios_close( arg ); - #else - return RTEMS_SUCCESSFUL; - #endif -} - -/* - * Read from the device - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - if ( minor > NUM_PORTS-1 ) - return RTEMS_INVALID_NUMBER; - - #if UARTS_USE_TERMIOS == 1 - return rtems_termios_read( arg ); - #else - return do_poll_read( major, minor, arg ); - #endif -} - -/* - * Write to the device - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - if ( minor > NUM_PORTS-1 ) - return RTEMS_INVALID_NUMBER; - - #if UARTS_USE_TERMIOS == 1 - return rtems_termios_write( arg ); - #else - return do_poll_write( major, minor, arg ); - #endif -} - -/* - * Handle ioctl request. - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - if ( minor > NUM_PORTS-1 ) - return RTEMS_INVALID_NUMBER; - - #if UARTS_USE_TERMIOS == 1 - return rtems_termios_ioctl( arg ); - #else - return RTEMS_SUCCESSFUL; - #endif -} diff --git a/c/src/lib/libbsp/powerpc/t32mppc/Makefile.am b/c/src/lib/libbsp/powerpc/t32mppc/Makefile.am index 3815ecce79..5590cf9fcf 100644 --- a/c/src/lib/libbsp/powerpc/t32mppc/Makefile.am +++ b/c/src/lib/libbsp/powerpc/t32mppc/Makefile.am @@ -47,8 +47,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c librtemsbsp_a_SOURCES += irq/irq.c # Console -librtemsbsp_a_SOURCES += ../../shared/console-termios.c -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/t32mppc/console/console.c librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/cache/cache.c diff --git a/c/src/lib/libbsp/powerpc/t32mppc/console/console.c b/c/src/lib/libbsp/powerpc/t32mppc/console/console.c deleted file mode 100644 index 5fbd648765..0000000000 --- a/c/src/lib/libbsp/powerpc/t32mppc/console/console.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2012, 2015 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -/* - * Console driver for Lauterbach Trace32 Simulator. The implementation is - * based on the example in "demo/powerpc/etc/terminal/terminal_mpc85xx.cmm" in - * the Trace32 system directory. - */ - -#include -#include -#include - -volatile unsigned char messagebufferin[256]; - -volatile unsigned char messagebufferout[256]; - -typedef struct { - rtems_termios_device_context base; - int input_size; - int input_index; -} t32_console_context; - -static t32_console_context t32_console_instance; - -static bool t32_console_first_open( - rtems_termios_tty *tty, - rtems_termios_device_context *base, - struct termios *term, - rtems_libio_open_close_args_t *args -) -{ - rtems_termios_set_initial_baud(tty, 115200); - - return true; -} - -static int t32_console_read_polled(rtems_termios_device_context *base) -{ - t32_console_context *ctx = (t32_console_context *) base; - int c; - - if (ctx->input_size == 0) { - int new_bufsize = messagebufferin[0]; - - if (new_bufsize != 0) { - ctx->input_size = new_bufsize; - ctx->input_index = 0; - } else { - return -1; - } - } - - c = messagebufferin[4 + ctx->input_index]; - - ++ctx->input_index; - if (ctx->input_index >= ctx->input_size) { - messagebufferin[0] = 0; - ctx->input_size = 0; - } - - return c; -} - -static void t32_console_write_char_polled(char c) -{ - while (messagebufferout[0] != 0) { - /* Wait for ready */ - } - - messagebufferout[4] = (unsigned char) c; - messagebufferout[0] = 1; -} - -static void t32_console_write_polled( - rtems_termios_device_context *base, - const char *s, - size_t n -) -{ - size_t i; - - for (i = 0; i < n; ++i) { - t32_console_write_char_polled(s[i]); - } -} - -const rtems_termios_device_handler t32_console_handler = { - .first_open = t32_console_first_open, - .poll_read = t32_console_read_polled, - .write = t32_console_write_polled, - .mode = TERMIOS_POLLED -}; - -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - t32_console_context *ctx = &t32_console_instance; - - rtems_termios_initialize(); - rtems_termios_device_context_initialize(&ctx->base, "T32 Console"); - rtems_termios_device_install( - CONSOLE_DEVICE_NAME, - &t32_console_handler, - NULL, - &ctx->base - ); - - return RTEMS_SUCCESSFUL; -} - -BSP_output_char_function_type BSP_output_char = t32_console_write_char_polled; - -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/powerpc/tqm8xx/Makefile.am b/c/src/lib/libbsp/powerpc/tqm8xx/Makefile.am index 9589d38e8d..1c0dfe5da3 100644 --- a/c/src/lib/libbsp/powerpc/tqm8xx/Makefile.am +++ b/c/src/lib/libbsp/powerpc/tqm8xx/Makefile.am @@ -32,7 +32,7 @@ librtemsbsp_a_SOURCES +=../../../../../../bsps/powerpc/shared/clock/clock.c librtemsbsp_a_SOURCES +=../../../../../../bsps/powerpc/tqm8xx/clock/p_clock.c # console -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/tqm8xx/console/console.c # spi librtemsbsp_a_SOURCES += spi/spi.c # timer diff --git a/c/src/lib/libbsp/powerpc/tqm8xx/console/console.c b/c/src/lib/libbsp/powerpc/tqm8xx/console/console.c deleted file mode 100644 index 5a681b19fb..0000000000 --- a/c/src/lib/libbsp/powerpc/tqm8xx/console/console.c +++ /dev/null @@ -1,1115 +0,0 @@ -/*===============================================================*\ -| Project: RTEMS TQM8xx BSP | -+-----------------------------------------------------------------+ -| This file has been adapted to MPC8xx by | -| Thomas Doerfler | -| Copyright (c) 2008 | -| Embedded Brains GmbH | -| Obere Lagerstr. 30 | -| D-82178 Puchheim | -| Germany | -| rtems@embedded-brains.de | -| | -| See the other copyright notice below for the original parts. | -+-----------------------------------------------------------------+ -| The license and distribution terms for this file may be | -| found in the file LICENSE in this distribution or at | -| | -| http://www.rtems.org/license/LICENSE. | -| | -+-----------------------------------------------------------------+ -| this file contains the console driver | -\*===============================================================*/ -/* derived from: */ -/* - * SMC1/2 SCC1..4 raw console serial I/O. - * adapted to work with up to 4 SCC and 2 SMC - * - * This driver is an example of `TASK DRIVEN' `POLLING' or `INTERRUPT' I/O. - * - * To run with interrupt-driven I/O, ensure m8xx_smc1_interrupt - * is set before calling the initialization routine. - * - * Author: - * W. Eric Norum - * Saskatchewan Accelerator Laboratory - * University of Saskatchewan - * Saskatoon, Saskatchewan, CANADA - * eric@skatter.usask.ca - * - * COPYRIGHT (c) 1989-1998. - * On-Line Applications Research Corporation (OAR). - * Copyright assigned to U.S. Government, 1994. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* - * Interrupt-driven input buffer - */ -#define RXBUFSIZE 16 - -#define M8xx_SICR_BRG1 (0) -#define M8xx_SICR_BRG2 (1) -#define M8xx_SICR_BRG3 (2) -#define M8xx_SICR_BRG4 (3) - -#define M8xx_SICR_SCCRX_MSK(scc) (( 7) << (((scc))*8+3)) -#define M8xx_SICR_SCCRX(scc,clk) ((clk) << (((scc))*8+3)) - -#define M8xx_SICR_SCCTX_MSK(scc) (( 7) << (((scc))*8+0)) -#define M8xx_SICR_SCCTX(scc,clk) ((clk) << (((scc))*8+0)) - -#define M8xx_SIMODE_SMCCS(smc,clk) ((clk) << ((smc)*16+12)) -#define M8xx_SIMODE_SMCCS_MSK(smc) M8xx_SIMODE_SMCCS(smc,7) - -#define CONS_CHN_CNT 6 -#define CONS_CHN_SCC1 0 -#define CONS_CHN_SCC2 1 -#define CONS_CHN_SCC3 2 -#define CONS_CHN_SCC4 3 -#define CONS_CHN_SMC1 4 -#define CONS_CHN_SMC2 5 -#define CONS_CHN_NONE -1 - -/* - * possible identifiers for bspopts.h: CONS_SxCy_MODE - */ -#define CONS_MODE_UNUSED -1 -#define CONS_MODE_POLLED TERMIOS_POLLED -#define CONS_MODE_IRQ TERMIOS_IRQ_DRIVEN - -#define CHN_IS_SCC(chan) ((chan) < CONS_CHN_SMC1) - -#define BRG_CNT 4 - -#define MAX_IDL_DEFAULT 10 -#define DEVICEPREFIX "tty" - -/* - * Interrupt-driven callback - */ -static int m8xx_scc_mode[CONS_CHN_CNT]; -static void *sccttyp[CONS_CHN_CNT]; -typedef struct m8xx_console_chan_desc_s { - bool is_scc; /* true for SCC */ - struct { - volatile m8xxSCCparms_t *sccp; - volatile m8xxSMCparms_t *smcp; - } parms; - struct { - volatile m8xxSCCRegisters_t *sccr; - volatile m8xxSMCRegisters_t *smcr; - } regs; - int ivec_src; - int cr_chan_code; - int brg_used; -} m8xx_console_chan_desc_t; - -m8xx_console_chan_desc_t m8xx_console_chan_desc[CONS_CHN_CNT] = { - /* SCC1 */ - {TRUE, - {(m8xxSCCparms_t *)&(m8xx.scc1p),NULL}, - {&(m8xx.scc1),NULL}, - BSP_CPM_IRQ_SCC1, - M8xx_CR_CHAN_SCC1, - -1}, - /* SCC2 */ - {TRUE, - {&(m8xx.scc2p),NULL}, - {&(m8xx.scc2),NULL}, - BSP_CPM_IRQ_SCC2, - M8xx_CR_CHAN_SCC2, - -1}, - /* SCC3 */ - {TRUE, - {&(m8xx.scc3p),NULL}, - {&(m8xx.scc3),NULL}, - BSP_CPM_IRQ_SCC3, - M8xx_CR_CHAN_SCC3, - -1}, - /* SCC4 */ - {TRUE, - {&(m8xx.scc4p),NULL}, - {&(m8xx.scc4),NULL}, - BSP_CPM_IRQ_SCC4, - M8xx_CR_CHAN_SCC4, - -1}, - /* SMC1 */ - {FALSE, - {NULL,&(m8xx.smc1p)}, - {NULL,&(m8xx.smc1)}, - BSP_CPM_IRQ_SMC1, - M8xx_CR_CHAN_SMC1, - -1}, - /* SMC2 */ - {FALSE, - {NULL,&(m8xx.smc2p)}, - {NULL,&(m8xx.smc2)}, - BSP_CPM_IRQ_SMC2_OR_PIP, - M8xx_CR_CHAN_SMC2, - -1}}; - -#define CHN_PARAM_GET(chan,param) \ - (m8xx_console_chan_desc[chan].is_scc \ - ? m8xx_console_chan_desc[chan].parms.sccp->param \ - : m8xx_console_chan_desc[chan].parms.smcp->param) - -#define CHN_PARAM_SET(chan,param,value) \ - do {if (m8xx_console_chan_desc[chan].is_scc) \ - m8xx_console_chan_desc[chan].parms.sccp->param = value; \ - else \ - m8xx_console_chan_desc[chan].parms.smcp->param = value; \ - } while (0) - -#define CHN_EVENT_GET(chan) \ - (m8xx_console_chan_desc[chan].is_scc \ - ? m8xx_console_chan_desc[chan].regs.sccr->scce \ - : m8xx_console_chan_desc[chan].regs.smcr->smce) - -#define CHN_EVENT_CLR(chan,mask) \ - do { \ - if (m8xx_console_chan_desc[chan].is_scc) \ - m8xx_console_chan_desc[chan].regs.sccr->scce = (mask); \ - else \ - m8xx_console_chan_desc[chan].regs.smcr->smce = (mask); \ - }while (0) - -#define CHN_MASK_GET(chan) \ - (m8xx_console_chan_desc[chan].is_scc \ - ? m8xx_console_chan_desc[chan].regs.sccr->sccm \ - : m8xx_console_chan_desc[chan].regs.smcr->smcm) - -#define CHN_MASK_SET(chan,mask) \ - do { \ - if (m8xx_console_chan_desc[chan].is_scc) \ - m8xx_console_chan_desc[chan].regs.sccr->sccm = (mask); \ - else \ - m8xx_console_chan_desc[chan].regs.smcr->smcm = (mask); \ - }while (0) - - -/* - * I/O buffers and pointers to buffer descriptors - */ -#define SCC_RXBD_CNT 4 -#define SCC_TXBD_CNT 4 -typedef volatile char sccRxBuf_t[SCC_RXBD_CNT][RXBUFSIZE]; -static sccRxBuf_t *rxBuf[CONS_CHN_CNT]; - -static volatile m8xxBufferDescriptor_t *sccFrstRxBd[CONS_CHN_CNT]; -static volatile m8xxBufferDescriptor_t *sccCurrRxBd[CONS_CHN_CNT]; -static volatile m8xxBufferDescriptor_t *sccFrstTxBd[CONS_CHN_CNT]; -static volatile m8xxBufferDescriptor_t *sccPrepTxBd[CONS_CHN_CNT]; -static volatile m8xxBufferDescriptor_t *sccDequTxBd[CONS_CHN_CNT]; - -/* - * Compute baud-rate-generator configuration register value - */ -static uint32_t -sccBRGval (int baud) -{ - int divisor; - int div16 = 0; - - divisor = ((BSP_bus_frequency / 16) + (baud / 2)) / baud; - if (divisor > 4096) { - div16 = 1; - divisor = (divisor + 8) / 16; - } - return M8xx_BRG_EN | M8xx_BRG_EXTC_BRGCLK | ((divisor - 1) << 1) | div16; -} - -typedef struct { - uint32_t reg_content; - int link_cnt; -}brg_state_t; -brg_state_t scc_brg_state[BRG_CNT]; - -/* - * initialize brg_state - */ -static void sccBRGinit(void) -{ - int brg_idx; - - for (brg_idx = 0;brg_idx < BRG_CNT;brg_idx++) { - scc_brg_state[brg_idx].reg_content = 0; - scc_brg_state[brg_idx].link_cnt = 0; - } -#ifndef MDE360 - /* - * on ZEM40, init CLK4/5 inputs - */ - m8xx.papar |= ((1 << 11) | (1 << 12)); - m8xx.padir &= ~((1 << 11) | (1 << 12)); -#endif -} - -#if CONS_USE_EXT_CLK -/* - * input clock frq for CPM clock inputs - */ -static uint32_t clkin_frq[2][4] = { -#ifdef MDE360 - {0,0,0,0}, - {0,0,0,0} -#else - {0,0,0,1843000}, - {1843000,0,0,0} -#endif -}; -#endif - -/* - * allocate, set and connect baud rate generators - * FIXME: or clock input - * FIXME: set pin to be clock input - */ - -static int sccBRGalloc(int chan,int baud) -{ - rtems_interrupt_level level; - m8xx_console_chan_desc_t *chan_desc = &(m8xx_console_chan_desc[chan]); - uint32_t reg_val; - int old_brg; - int new_brg = -1; - int brg_idx; -#if CONS_USE_EXT_CLK - int clk_group; - int clk_sel; -#endif - - old_brg = chan_desc->brg_used; - /* compute brg register contents needed */ - reg_val = sccBRGval(baud); - -#if CONS_EXT_CLK - /* search for clock input with this frq */ - clk_group = ((chan == CONS_CHN_SCC3) || - (chan == CONS_CHN_SCC4) || - (chan == CONS_CHN_SMC2)) ? 1 : 0; - - for (clk_sel = 0, new_brg = -1; - (clk_sel < 4) && (new_brg < 0); - clk_sel++) { - if (baud == (clkin_frq[clk_group][clk_sel] / 16)) { - new_brg = clk_sel + 4; - } - } -#endif - - rtems_interrupt_disable(level); - - if (new_brg < 0) { - /* search for brg with this settings */ - for (brg_idx = 0; - (new_brg < 0) && (brg_idx < BRG_CNT); - brg_idx++) { - if (scc_brg_state[brg_idx].reg_content == reg_val) { - new_brg = brg_idx; - } - } - /* - * if not found: check, whether brg currently in use - * is linked only from our channel - */ - if ((new_brg < 0) && - (old_brg >= 0) && - (scc_brg_state[old_brg].link_cnt == 1)) { - new_brg = old_brg; - } - /* if not found: search for unused brg, set it */ - for (brg_idx = 0; - (new_brg < 0) && (brg_idx < BRG_CNT); - brg_idx++) { - if (scc_brg_state[brg_idx].link_cnt == 0) { - new_brg = brg_idx; - } - } - } - - /* decrease old link count */ - if ((old_brg >= 0) && - (old_brg < 4)) { - scc_brg_state[old_brg].link_cnt--; - } - /* increase new brg link count, set brg */ - if ((new_brg >= 0) && - (new_brg < 4)) { - scc_brg_state[new_brg].link_cnt++; - scc_brg_state[new_brg].reg_content = reg_val; - (&m8xx.brgc1)[new_brg] = reg_val; - } - rtems_interrupt_enable(level); - - /* connect to scc/smc */ - if (new_brg >= 0) { - m8xx_console_chan_desc[chan].brg_used = new_brg; - /* - * Put SCC in NMSI mode, connect SCC to BRG or CLKx - */ - if (m8xx_console_chan_desc[chan].is_scc) { - m8xx.sicr = ((m8xx.sicr & ~(M8xx_SICR_SCCRX_MSK(chan) | - M8xx_SICR_SCCTX_MSK(chan))) | - M8xx_SICR_SCCRX(chan,new_brg)| - M8xx_SICR_SCCTX(chan,new_brg)); - } - else { - /* connect SMC to BRGx or CLKx... */ - m8xx.simode = ((m8xx.simode & ~(M8xx_SIMODE_SMCCS_MSK(chan - CONS_CHN_SMC1)))| - M8xx_SIMODE_SMCCS(chan - CONS_CHN_SMC1,new_brg)); - } - } - return (new_brg < 0); -} - - -/* - * Hardware-dependent portion of tcsetattr(). - */ -static int -sccSetAttributes (int minor, const struct termios *t) -{ - int baud; - - switch (t->c_ospeed) { - default: baud = -1; break; - case B50: baud = 50; break; - case B75: baud = 75; break; - case B110: baud = 110; break; - case B134: baud = 134; break; - case B150: baud = 150; break; - case B200: baud = 200; break; - case B300: baud = 300; break; - case B600: baud = 600; break; - case B1200: baud = 1200; break; - case B1800: baud = 1800; break; - case B2400: baud = 2400; break; - case B4800: baud = 4800; break; - case B9600: baud = 9600; break; - case B19200: baud = 19200; break; - case B38400: baud = 38400; break; - case B57600: baud = 57600; break; - case B115200: baud = 115200; break; - case B230400: baud = 230400; break; - case B460800: baud = 460800; break; - } - return sccBRGalloc(minor,baud); - return 0; -} - -/* - * Interrupt handler - */ -static rtems_isr -sccInterruptHandler (void *arg) -{ - int chan = (int)arg; - - /* - * Buffer received? - */ - if (CHN_EVENT_GET(chan) & 0x1) { - /* - * clear SCC event flag - */ - CHN_EVENT_CLR(chan,0x01); - /* - * process event - */ - while ((sccCurrRxBd[chan]->status & M8xx_BD_EMPTY) == 0) { - if (sccttyp[chan] != NULL) { - rtems_cache_invalidate_multiple_data_lines((void *)sccCurrRxBd[chan]->buffer, - sccCurrRxBd[chan]->length); - rtems_termios_enqueue_raw_characters (sccttyp[chan], - (char *)sccCurrRxBd[chan]->buffer, - sccCurrRxBd[chan]->length); - } - /* - * clear status - */ - sccCurrRxBd[chan]->status = - (sccCurrRxBd[chan]->status - & (M8xx_BD_WRAP | M8xx_BD_INTERRUPT)) - | M8xx_BD_EMPTY; - /* - * advance to next BD - */ - if ((sccCurrRxBd[chan]->status & M8xx_BD_WRAP) != 0) { - sccCurrRxBd[chan] = sccFrstRxBd[chan]; - } - else { - sccCurrRxBd[chan]++; - } - } - } - /* - * Buffer transmitted? - */ - if (CHN_EVENT_GET(chan) & 0x2) { - /* - * then clear interrupt event bit - */ - CHN_EVENT_CLR(chan,0x2); - /* - * and signal successful transmit to termios - */ - /* - * FIXME: multiple dequeue calls for multiple buffers - */ - while((sccDequTxBd[chan] != sccPrepTxBd[chan]) && - ((sccDequTxBd[chan]->status & M8xx_BD_READY) == 0)) { - if (sccttyp[chan] != NULL) { - rtems_termios_dequeue_characters (sccttyp[chan], - sccDequTxBd[chan]->length); - } - /* - * advance to next BD - */ - if ((sccDequTxBd[chan]->status & M8xx_BD_WRAP) != 0) { - sccDequTxBd[chan] = sccFrstTxBd[chan]; - } - else { - sccDequTxBd[chan]++; - } - } - } -} - -static void -mpc8xx_console_irq_on(const rtems_irq_connect_data *irq) -{ - CHN_MASK_SET(irq->name - BSP_CPM_IRQ_LOWEST_OFFSET, - 3); /* Enable TX and RX interrupts */ -} - -static void -mpc8xx_console_irq_off(const rtems_irq_connect_data *irq) -{ - CHN_MASK_SET(irq->name - BSP_CPM_IRQ_LOWEST_OFFSET, - 0); /* Disable TX and RX interrupts */ -} - -static int -mpc8xx_console_irq_isOn(const rtems_irq_connect_data *irq) -{ - return (0 != CHN_MASK_GET(irq->name - BSP_CPM_IRQ_LOWEST_OFFSET)); /* Check TX and RX interrupts */ -} - -static void -sccInitialize (int chan) -{ - int i; - /* - * allocate buffers - * FIXME: use a cache-line size boundary alloc here - */ - rxBuf[chan] = malloc(sizeof(*rxBuf[chan]) + 2*PPC_CACHE_ALIGNMENT); - if (rxBuf[chan] == NULL) { - rtems_panic("Cannot allocate console rx buffer\n"); - } - else { - /* - * round up rxBuf[chan] to start at a cache line size - */ - rxBuf[chan] = (sccRxBuf_t *) - (((uint32_t)rxBuf[chan]) + - (PPC_CACHE_ALIGNMENT - - ((uint32_t)rxBuf[chan]) % PPC_CACHE_ALIGNMENT)); - } - /* - * Allocate buffer descriptors - */ - sccCurrRxBd[chan] = - sccFrstRxBd[chan] = m8xx_bd_allocate(SCC_RXBD_CNT); - sccPrepTxBd[chan] = - sccDequTxBd[chan] = - sccFrstTxBd[chan] = m8xx_bd_allocate(SCC_TXBD_CNT); - switch(chan) { - case CONS_CHN_SCC1: - /* - * Configure port A pins to enable TXD1 and RXD1 pins - * FIXME: add setup for modem control lines.... - */ - m8xx.papar |= 0x03; - m8xx.padir &= ~0x03; - - /* - * Configure port C pins to enable RTS1 pins (static active low) - */ - m8xx.pcpar &= ~0x01; - m8xx.pcso &= ~0x01; - m8xx.pcdir |= 0x01; - m8xx.pcdat &= ~0x01; - break; - case CONS_CHN_SCC2: - /* - * Configure port A pins to enable TXD2 and RXD2 pins - * FIXME: add setup for modem control lines.... - */ - m8xx.papar |= 0x0C; - m8xx.padir &= ~0x0C; - - /* - * Configure port C pins to enable RTS2 pins (static active low) - */ - m8xx.pcpar &= ~0x02; - m8xx.pcso &= ~0x02; - m8xx.pcdir |= 0x02; - m8xx.pcdat &= ~0x02; - break; - case CONS_CHN_SCC3: - /* - * Configure port A pins to enable TXD3 and RXD3 pins - * FIXME: add setup for modem control lines.... - */ - m8xx.papar |= 0x30; - m8xx.padir &= ~0x30; - - /* - * Configure port C pins to enable RTS3 (static active low) - */ - m8xx.pcpar &= ~0x04; - m8xx.pcso &= ~0x04; - m8xx.pcdir |= 0x04; - m8xx.pcdat &= ~0x04; - break; - case CONS_CHN_SCC4: - /* - * Configure port A pins to enable TXD4 and RXD4 pins - * FIXME: add setup for modem control lines.... - */ - m8xx.papar |= 0xC0; - m8xx.padir &= ~0xC0; - - /* - * Configure port C pins to enable RTS4 pins (static active low) - */ - m8xx.pcpar &= ~0x08; - m8xx.pcso &= ~0x08; - m8xx.pcdir |= 0x08; - m8xx.pcdat &= ~0x08; - break; - case CONS_CHN_SMC1: - /* - * Configure port B pins to enable SMTXD1 and SMRXD1 pins - */ - m8xx.pbpar |= 0xC0; - m8xx.pbdir &= ~0xC0; - break; - case CONS_CHN_SMC2: - /* - * Configure port B pins to enable SMTXD2 and SMRXD2 pins - */ - m8xx.pbpar |= 0xC00; - m8xx.pbdir &= ~0xC00; - break; - } - /* - * allocate and connect BRG - */ - sccBRGalloc(chan,9600); - - - /* - * Set up SCCx parameter RAM common to all protocols - */ - CHN_PARAM_SET(chan,rbase,(char *)sccFrstRxBd[chan] - (char *)&m8xx); - CHN_PARAM_SET(chan,tbase,(char *)sccFrstTxBd[chan] - (char *)&m8xx); - CHN_PARAM_SET(chan,rfcr ,M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0)); - CHN_PARAM_SET(chan,tfcr ,M8xx_TFCR_MOT | M8xx_TFCR_DMA_SPACE(0)); - if (m8xx_scc_mode[chan] != TERMIOS_POLLED) - CHN_PARAM_SET(chan,mrblr,RXBUFSIZE); - else - CHN_PARAM_SET(chan,mrblr,1); - - /* - * Set up SCCx parameter RAM UART-specific parameters - */ - CHN_PARAM_SET(chan,un.uart.max_idl ,MAX_IDL_DEFAULT); - CHN_PARAM_SET(chan,un.uart.brkln ,0); - CHN_PARAM_SET(chan,un.uart.brkec ,0); - CHN_PARAM_SET(chan,un.uart.brkcr ,0); - if (m8xx_console_chan_desc[chan].is_scc) { - m8xx_console_chan_desc[chan].parms.sccp->un.uart.character[0]=0x8000; /* no char filter */ - m8xx_console_chan_desc[chan].parms.sccp->un.uart.rccm=0x80FF; /* control character mask */ - } - - /* - * Set up the Receive Buffer Descriptors - */ - for (i = 0;i < SCC_RXBD_CNT;i++) { - sccFrstRxBd[chan][i].status = M8xx_BD_EMPTY | M8xx_BD_INTERRUPT; - if (i == SCC_RXBD_CNT-1) { - sccFrstRxBd[chan][i].status |= M8xx_BD_WRAP; - } - sccFrstRxBd[chan][i].length = 0; - sccFrstRxBd[chan][i].buffer = (*rxBuf[chan])[i]; - } - /* - * Setup the Transmit Buffer Descriptor - */ - for (i = 0;i < SCC_TXBD_CNT;i++) { - sccFrstTxBd[chan][i].status = M8xx_BD_INTERRUPT; - if (i == SCC_TXBD_CNT-1) { - sccFrstTxBd[chan][i].status |= M8xx_BD_WRAP; - } - sccFrstTxBd[chan][i].length = 0; - sccFrstTxBd[chan][i].buffer = NULL; - } - - /* - * Set up SCC general and protocol-specific mode registers - */ - CHN_EVENT_CLR(chan,~0); /* Clear any pending events */ - CHN_MASK_SET(chan,0); /* Mask all interrupt/event sources */ - - if (m8xx_console_chan_desc[chan].is_scc) { - m8xx_console_chan_desc[chan].regs.sccr->psmr = 0xb000; /* 8N1, CTS flow control */ - m8xx_console_chan_desc[chan].regs.sccr->gsmr_h = 0x00000000; - m8xx_console_chan_desc[chan].regs.sccr->gsmr_l = 0x00028004; /* UART mode */ - } - else { - m8xx_console_chan_desc[chan].regs.smcr->smcmr = 0x4820; - } - /* - * Send "Init parameters" command - */ - m8xx_cp_execute_cmd(M8xx_CR_OP_INIT_RX_TX - | m8xx_console_chan_desc[chan].cr_chan_code); - - /* - * Enable receiver and transmitter - */ - if (m8xx_console_chan_desc[chan].is_scc) { - m8xx_console_chan_desc[chan].regs.sccr->gsmr_l |= 0x00000030; - } - else { - m8xx_console_chan_desc[chan].regs.smcr->smcmr |= 0x0003; - } - - if (m8xx_scc_mode[chan] != TERMIOS_POLLED) { - - rtems_irq_connect_data irq_conn_data = { - m8xx_console_chan_desc[chan].ivec_src, - sccInterruptHandler, /* rtems_irq_hdl */ - (rtems_irq_hdl_param)chan, /* (rtems_irq_hdl_param) */ - mpc8xx_console_irq_on, /* (rtems_irq_enable) */ - mpc8xx_console_irq_off, /* (rtems_irq_disable) */ - mpc8xx_console_irq_isOn /* (rtems_irq_is_enabled) */ - }; - if (!BSP_install_rtems_irq_handler (&irq_conn_data)) { - rtems_panic("console: cannot install IRQ handler"); - } - } -} - -/* - * polled scc read function - */ -static int -sccPollRead (int minor) -{ - int c = -1; - int chan = minor; - - while(1) { - if ((sccCurrRxBd[chan]->status & M8xx_BD_EMPTY) != 0) { - return -1; - } - - if (0 == (sccCurrRxBd[chan]->status & (M8xx_BD_OVERRUN - | M8xx_BD_PARITY_ERROR - | M8xx_BD_FRAMING_ERROR - | M8xx_BD_BREAK - | M8xx_BD_IDLE))) { - /* character received and no error detected */ - rtems_cache_invalidate_multiple_data_lines((void *)sccCurrRxBd[chan]->buffer, - sccCurrRxBd[chan]->length); - c = (unsigned)*((char *)sccCurrRxBd[chan]->buffer); - /* - * clear status - */ - } - sccCurrRxBd[chan]->status = - (sccCurrRxBd[chan]->status - & (M8xx_BD_WRAP | M8xx_BD_INTERRUPT)) - | M8xx_BD_EMPTY; - /* - * advance to next BD - */ - if ((sccCurrRxBd[chan]->status & M8xx_BD_WRAP) != 0) { - sccCurrRxBd[chan] = sccFrstRxBd[chan]; - } - else { - sccCurrRxBd[chan]++; - } - if (c >= 0) { - return c; - } - } -} - - -/* - * Device-dependent write routine - * Interrupt-driven devices: - * Begin transmission of as many characters as possible (minimum is 1). - * Polling devices: - * Transmit all characters. - */ -static ssize_t -sccInterruptWrite (int minor, const char *buf, size_t len) -{ - if (len > 0) { - int chan = minor; - - if ((sccPrepTxBd[chan]->status & M8xx_BD_READY) == 0) { - sccPrepTxBd[chan]->buffer = (char *)buf; - sccPrepTxBd[chan]->length = len; - rtems_cache_flush_multiple_data_lines((const void *)buf,len); - /* - * clear status, set ready bit - */ - sccPrepTxBd[chan]->status = - (sccPrepTxBd[chan]->status - & M8xx_BD_WRAP) - | M8xx_BD_READY | M8xx_BD_INTERRUPT; - if ((sccPrepTxBd[chan]->status & M8xx_BD_WRAP) != 0) { - sccPrepTxBd[chan] = sccFrstTxBd[chan]; - } - else { - sccPrepTxBd[chan]++; - } - } - } - - return 0; -} - -static ssize_t -sccPollWrite (int minor, const char *buf, size_t len) -{ - static char txBuf[CONS_CHN_CNT][SCC_TXBD_CNT]; - int chan = minor; - int bd_used; - size_t retval = len; - - while (len--) { - while (sccPrepTxBd[chan]->status & M8xx_BD_READY) - continue; - bd_used = sccPrepTxBd[chan]-sccFrstTxBd[chan]; - txBuf[chan][bd_used] = *buf++; - rtems_cache_flush_multiple_data_lines((const void *)&txBuf[chan][bd_used], - sizeof(txBuf[chan][bd_used])); - sccPrepTxBd[chan]->buffer = &(txBuf[chan][bd_used]); - sccPrepTxBd[chan]->length = 1; - sccPrepTxBd[chan]->status = - (sccPrepTxBd[chan]->status - & M8xx_BD_WRAP) - | M8xx_BD_READY; - if ((sccPrepTxBd[chan]->status & M8xx_BD_WRAP) != 0) { - sccPrepTxBd[chan] = sccFrstTxBd[chan]; - } - else { - sccPrepTxBd[chan]++; - } - } - return retval; -} - -/* - * printk basic support - */ -int BSP_output_chan = CONS_CHN_NONE; /* channel used for printk operation */ - -static void console_debug_putc_onlcr(const char c) -{ - rtems_interrupt_level irq_level; - - if (BSP_output_chan != CONS_CHN_NONE) { - rtems_interrupt_disable(irq_level); - - sccPollWrite (BSP_output_chan,&c,1); - rtems_interrupt_enable(irq_level); - } -} - -BSP_output_char_function_type BSP_output_char = console_debug_putc_onlcr; -BSP_polling_getchar_function_type BSP_poll_char = NULL; - - -/* -*************** -* BOILERPLATE * -*************** -*/ - -struct { - rtems_device_minor_number minor; - int driver_mode; -} channel_list[] = { - {CONS_CHN_SMC1,CONS_SMC1_MODE}, - {CONS_CHN_SMC2,CONS_SMC2_MODE}, - {CONS_CHN_SCC1,CONS_SCC1_MODE}, - {CONS_CHN_SCC2,CONS_SCC2_MODE}, - {CONS_CHN_SCC3,CONS_SCC3_MODE}, - {CONS_CHN_SCC4,CONS_SCC4_MODE} -}; - - -/* - * Initialize and register the device - */ -rtems_device_driver console_initialize(rtems_device_major_number major, - rtems_device_minor_number minor,/* ignored */ - void *arg - ) -{ - rtems_status_code status = RTEMS_SUCCESSFUL; - int chan,entry,ttynum; - char tty_name[] = "/dev/tty00"; - - /* - * Set up TERMIOS - */ - rtems_termios_initialize (); - /* - * init BRG allocataion - */ - sccBRGinit(); - ttynum = 0; - for (entry = 0; - (entry < sizeof(channel_list)/sizeof(channel_list[0])) - && (status == RTEMS_SUCCESSFUL); - entry++) { - if (channel_list[entry].driver_mode != CONS_MODE_UNUSED) { - /* - * Do device-specific initialization - */ - chan = channel_list[entry].minor; - m8xx_scc_mode[chan] = channel_list[entry].driver_mode; - sccInitialize (chan); - - /* - * build device name - */ - tty_name[sizeof(tty_name)-2] = '0'+ttynum; - ttynum++; - /* - * Register the device - */ - status = rtems_io_register_name (tty_name, - major, - channel_list[entry].minor); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred (status); - } - } - } - /* - * register /dev/console - */ - status = rtems_io_register_name ("/dev/console", - major, - CONSOLE_CHN); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred (status); - } - /* - * enable printk support - */ - BSP_output_chan = PRINTK_CHN; - - return RTEMS_SUCCESSFUL; -} - -/* - * Open the device - */ -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg - ) -{ - rtems_status_code status; - int chan = minor; - rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *)arg; - static const rtems_termios_callbacks interruptCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - NULL, /* pollRead */ - sccInterruptWrite, /* write */ - sccSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_IRQ_DRIVEN /* outputUsesInterrupts */ - }; - static const rtems_termios_callbacks pollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - sccPollRead, /* pollRead */ - sccPollWrite, /* write */ - sccSetAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - 0 /* outputUsesInterrupts */ - }; - - if (m8xx_scc_mode[chan] == TERMIOS_IRQ_DRIVEN) { - status = rtems_termios_open (major, minor, arg, &interruptCallbacks); - sccttyp[chan] = args->iop->data1; - } - else { - status = rtems_termios_open (major, minor, arg, &pollCallbacks); - sccttyp[chan] = args->iop->data1; - } - return status; -} - -/* - * Close the device - */ -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg - ) -{ - rtems_status_code rc; - - rc = rtems_termios_close (arg); - sccttyp[minor] = NULL; - - return rc; - -} - -/* - * Read from the device - */ -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg - ) -{ - return rtems_termios_read (arg); -} - -/* - * Write to the device - */ -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg - ) -{ - return rtems_termios_write (arg); -} - -#if 0 -static int scc_io_set_trm_char(rtems_device_minor_number minor, - rtems_libio_ioctl_args_t *ioa) -{ - rtems_status_code rc = RTEMS_SUCCESSFUL; - con360_io_trm_char_t *trm_char_info = ioa->buffer; - - /* - * check, that parameter is non-NULL - */ - if ((rc == RTEMS_SUCCESSFUL) && - (trm_char_info == NULL)) { - rc = RTEMS_INVALID_ADDRESS; - } - /* - * transfer max_idl - */ - if (rc == RTEMS_SUCCESSFUL) { - if (trm_char_info->max_idl >= 0x10000) { - rc = RTEMS_INVALID_NUMBER; - } - else if (trm_char_info->max_idl > 0) { - CHN_PARAM_SET(minor,un.uart.max_idl ,trm_char_info->max_idl); - } - else if (trm_char_info->max_idl == 0) { - CHN_PARAM_SET(minor,un.uart.max_idl ,MAX_IDL_DEFAULT); - } - } - /* - * transfer characters - */ - if (rc == RTEMS_SUCCESSFUL) { - if (trm_char_info->char_cnt > CON8XX_TRM_CHAR_CNT) { - rc = RTEMS_TOO_MANY; - } - else if (trm_char_info->char_cnt >= 0) { - /* - * check, whether device is a SCC - */ - if ((rc == RTEMS_SUCCESSFUL) && - !m8xx_console_chan_desc[minor].is_scc) { - rc = RTEMS_UNSATISFIED; - } - else { - int idx = 0; - for(idx = 0;idx < trm_char_info->char_cnt;idx++) { - m8xx_console_chan_desc[minor].parms.sccp->un.uart.character[idx] = - trm_char_info->character[idx] & 0x00ff; - } - if (trm_char_info->char_cnt < CON8XX_TRM_CHAR_CNT) { - m8xx_console_chan_desc[minor].parms.sccp - ->un.uart.character[trm_char_info->char_cnt] = 0x8000; - } - } - } - } - - return rc; -} -#endif - -/* - * Handle ioctl request. - */ -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg - ) -{ - rtems_libio_ioctl_args_t *ioa=arg; - - switch (ioa->command) { -#if 0 - case CON8XX_IO_SET_TRM_CHAR: - return scc_io_set_trm_char(minor, ioa); -#endif - default: - return rtems_termios_ioctl (arg); - break; - } -} - diff --git a/c/src/lib/libbsp/powerpc/virtex/Makefile.am b/c/src/lib/libbsp/powerpc/virtex/Makefile.am index 41e0e095c4..f9c98b5ec4 100644 --- a/c/src/lib/libbsp/powerpc/virtex/Makefile.am +++ b/c/src/lib/libbsp/powerpc/virtex/Makefile.am @@ -41,7 +41,7 @@ librtemsbsp_a_SOURCES += ../shared/src/bsp-start-zero.S librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c -librtemsbsp_a_SOURCES += console/consolelite.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/virtex/console/consolelite.c # irq librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c diff --git a/c/src/lib/libbsp/powerpc/virtex/console/consolelite.c b/c/src/lib/libbsp/powerpc/virtex/console/consolelite.c deleted file mode 100644 index 4d0b2db17f..0000000000 --- a/c/src/lib/libbsp/powerpc/virtex/console/consolelite.c +++ /dev/null @@ -1,425 +0,0 @@ -/* - * This file contains the console driver for the xilinx uart lite. - * - * Author: Keith Robertson - * COPYRIGHT (c) 2005 by Linn Products Ltd, Scotland. - * - * Derived from libbsp/no_cpu/no_bsp/console.c and therefore also: - * - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - */ - -#include - -#include -#include -#include - -#include -#include -#include - -#include RTEMS_XPARAMETERS_H - -/* Status Register Masks */ -#define PARITY_ERROR 0x80 /* Parity Error */ -#define FRAME_ERROR 0x40 /* Frame Error */ -#define OVERRUN_ERROR 0x20 /* Overrun Error */ -#define STATUS_REG_ERROR_MASK ( PARITY_ERROR | FRAME_ERROR | OVERRUN_ERROR ) - -#define INTR_ENABLED 0x10 /* Interrupts are enabled */ -#define TX_FIFO_FULL 0x08 /* Transmit FIFO is full */ -#define TX_FIFO_EMPTY 0x04 /* Transmit FIFO is empty */ -#define RX_FIFO_FULL 0x02 /* Receive FIFO is full */ -#define RX_FIFO_VALID_DATA 0x01 /* Receive FIFO has valid data */ -/* Control Register Masks*/ -#define ENABLE_INTR 0x10 /* Enable interrupts */ -#define RST_RX_FIFO 0x02 /* Reset and clear RX FIFO */ -#define RST_TX_FIFO 0x01 /* Reset and clear TX FIFO */ - -/* General Defines */ -#define TX_FIFO_SIZE 16 -#define RX_FIFO_SIZE 16 - - - - -#define RECV_REG 0 -#define TRAN_REG 4 -#define STAT_REG 8 -#define CTRL_REG 12 - - - -RTEMS_INLINE_ROUTINE uint32_t xlite_uart_control(uint32_t base) -{ - uint32_t c = *((volatile uint32_t*)(base+CTRL_REG)); - return c; -} - - -RTEMS_INLINE_ROUTINE uint32_t xlite_uart_status(uint32_t base) -{ - uint32_t c = *((volatile uint32_t*)(base+STAT_REG)); - return c; -} - - -RTEMS_INLINE_ROUTINE uint32_t xlite_uart_read(uint32_t base) -{ - uint32_t c = *((volatile uint32_t*)(base+RECV_REG)); - return c; -} - - -RTEMS_INLINE_ROUTINE void xlite_uart_write(uint32_t base, char ch) -{ - *(volatile uint32_t*)(base+TRAN_REG) = (uint32_t)ch; - return; -} - - - -static int xlite_write_char(uint32_t base, char ch) -{ - uint32_t retrycount= 0, idler, status; - - while( ((status = xlite_uart_status(base)) & TX_FIFO_FULL) != 0 ) - { - ++retrycount; - - /* uart tx is busy */ - if( retrycount == 0x4000 ) - { - /* retrycount is arbitrary- just make it big enough so the uart is sure to be timed out before it trips */ - return -1; - } - - /* spin for a bit so we can sample the register rather than - * continually reading it */ - for( idler= 0; idler < 0x2000; idler++); - } - - xlite_uart_write(base, ch); - - return 1; -} - -static void xlite_init(int minor ) -{ - /* Nothing to do */ -} - -#if VIRTEX_CONSOLE_USE_INTERRUPTS -static void xlite_interrupt_handler(void *arg) -{ - int minor = (int) arg; - const console_tbl *ct = Console_Port_Tbl[minor]; - console_data *cd = &Console_Port_Data[minor]; - uint32_t base = ct->ulCtrlPort1; - uint32_t status = xlite_uart_status(base); - - while ((status & RX_FIFO_VALID_DATA) != 0) { - char c = (char) xlite_uart_read(base); - - rtems_termios_enqueue_raw_characters(cd->termios_data, &c, 1); - - status = xlite_uart_status(base); - } - - if (cd->bActive) { - rtems_termios_dequeue_characters(cd->termios_data, 1); - } -} -#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */ - -static int xlite_open( - int major, - int minor, - void *arg -) -{ - const console_tbl *ct = Console_Port_Tbl[minor]; - uint32_t base = ct->ulCtrlPort1; -#if VIRTEX_CONSOLE_USE_INTERRUPTS - rtems_status_code sc; -#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */ - - /* clear status register */ - *((volatile uint32_t*)(base+STAT_REG)) = 0; - - /* clear control register; reset fifos */ - *((volatile uint32_t*)(base+CTRL_REG)) = RST_RX_FIFO | RST_TX_FIFO; - -#if VIRTEX_CONSOLE_USE_INTERRUPTS - *((volatile uint32_t*)(base+CTRL_REG)) = ENABLE_INTR; - - sc = rtems_interrupt_handler_install( - ct->ulIntVector, - "xlite", - RTEMS_INTERRUPT_UNIQUE, - xlite_interrupt_handler, - (void *) minor - ); - assert(sc == RTEMS_SUCCESSFUL); -#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */ - - return 0; -} - -static int xlite_close( - int major, - int minor, - void *arg -) -{ - const console_tbl *ct = Console_Port_Tbl[minor]; - uint32_t base = ct->ulCtrlPort1; -#if VIRTEX_CONSOLE_USE_INTERRUPTS - rtems_status_code sc; -#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */ - - *((volatile uint32_t*)(base+CTRL_REG)) = 0; - -#if VIRTEX_CONSOLE_USE_INTERRUPTS - sc = rtems_interrupt_handler_remove( - ct->ulIntVector, - xlite_interrupt_handler, - (void *) minor - ); - assert(sc == RTEMS_SUCCESSFUL); -#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */ - - return 0; -} - - - -static int xlite_read_polled (int minor ) -{ - uint32_t base = Console_Port_Tbl[minor]->ulCtrlPort1; - - unsigned int status = xlite_uart_status(base); - - if(status & RX_FIFO_VALID_DATA) - return (int)xlite_uart_read(base); - else - return -1; -} - -#if VIRTEX_CONSOLE_USE_INTERRUPTS - -static ssize_t xlite_write_interrupt_driven( - int minor, - const char *buf, - size_t len -) -{ - console_data *cd = &Console_Port_Data[minor]; - - if (len > 0) { - const console_tbl *ct = Console_Port_Tbl[minor]; - uint32_t base = ct->ulCtrlPort1; - - xlite_uart_write(base, buf[0]); - - cd->bActive = true; - } else { - cd->bActive = false; - } - - return 0; -} - -#else /* VIRTEX_CONSOLE_USE_INTERRUPTS */ - -static ssize_t xlite_write_buffer_polled( - int minor, - const char *buf, - size_t len -) -{ - uint32_t base = Console_Port_Tbl[minor]->ulCtrlPort1; - int nwrite = 0; - - /* - * poll each byte in the string out of the port. - */ - while (nwrite < len) - { - if( xlite_write_char(base, *buf++) < 0 ) break; - nwrite++; - } - - /* - * return the number of bytes written. - */ - return nwrite; -} - -#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */ - -static void xlite_write_char_polled( - int minor, - char c -) -{ - uint32_t base = Console_Port_Tbl[minor]->ulCtrlPort1; - xlite_write_char(base, c); - return; -} - -static int xlite_set_attributes(int minor, const struct termios *t) -{ - return RTEMS_SUCCESSFUL; -} - - - - - - - -static const console_fns xlite_fns_polled = -{ - .deviceProbe = libchip_serial_default_probe, - .deviceFirstOpen = xlite_open, - .deviceLastClose = xlite_close, - .deviceRead = xlite_read_polled, - .deviceInitialize = xlite_init, - .deviceWritePolled = xlite_write_char_polled, - .deviceSetAttributes = xlite_set_attributes, -#if VIRTEX_CONSOLE_USE_INTERRUPTS - .deviceWrite = xlite_write_interrupt_driven, - .deviceOutputUsesInterrupts = true -#else /* VIRTEX_CONSOLE_USE_INTERRUPTS */ - .deviceWrite = xlite_write_buffer_polled, - .deviceOutputUsesInterrupts = false -#endif /* VIRTEX_CONSOLE_USE_INTERRUPTS */ -}; - - - - - - -/* -** Set ulCtrlPort1 to the base address of each UART Lite instance. Set in vhdl model. -*/ - - -console_tbl Console_Configuration_Ports[] = { -{ - "/dev/ttyS0", /* sDeviceName */ - SERIAL_CUSTOM, /* deviceType */ - &xlite_fns_polled, /* pDeviceFns */ - NULL, /* deviceProbe, assume it is there */ - NULL, /* pDeviceFlow */ - 16, /* ulMargin */ - 8, /* ulHysteresis */ - (void *) NULL, /* NULL */ /* pDeviceParams */ - STDIN_BASEADDRESS, /* ulCtrlPort1 */ - 0, /* ulCtrlPort2 */ - 0, /* ulDataPort */ - NULL, /* getRegister */ - NULL, /* setRegister */ - NULL, /* unused */ /* getData */ - NULL, /* unused */ /* setData */ - 0, /* ulClock */ - #ifdef XPAR_XPS_INTC_0_RS232_UART_INTERRUPT_INTR - .ulIntVector = XPAR_XPS_INTC_0_RS232_UART_INTERRUPT_INTR - #else - .ulIntVector = 0 - #endif -}, -#ifdef XPAR_UARTLITE_1_BASEADDR -{ - "/dev/ttyS1", /* sDeviceName */ - SERIAL_CUSTOM, /* deviceType */ - &xlite_fns_polled, /* pDeviceFns */ - NULL, /* deviceProbe, assume it is there */ - NULL, /* pDeviceFlow */ - 16, /* ulMargin */ - 8, /* ulHysteresis */ - (void *) NULL, /* NULL */ /* pDeviceParams */ - XPAR_UARTLITE_1_BASEADDR, /* ulCtrlPort1 */ - 0, /* ulCtrlPort2 */ - 0, /* ulDataPort */ - NULL, /* getRegister */ - NULL, /* setRegister */ - NULL, /* unused */ /* getData */ - NULL, /* unused */ /* setData */ - 0, /* ulClock */ - 0 /* ulIntVector -- base for port */ -}, -#endif -#ifdef XPAR_UARTLITE_2_BASEADDR -{ - "/dev/ttyS2", /* sDeviceName */ - SERIAL_CUSTOM, /* deviceType */ - &xlite_fns_polled, /* pDeviceFns */ - NULL, /* deviceProbe, assume it is there */ - NULL, /* pDeviceFlow */ - 16, /* ulMargin */ - 8, /* ulHysteresis */ - (void *) NULL, /* NULL */ /* pDeviceParams */ - XPAR_UARTLITE_2_BASEADDR, /* ulCtrlPort1 */ - 0, /* ulCtrlPort2 */ - 0, /* ulDataPort */ - NULL, /* getRegister */ - NULL, /* setRegister */ - NULL, /* unused */ /* getData */ - NULL, /* unused */ /* setData */ - 0, /* ulClock */ - 0 /* ulIntVector -- base for port */ -}, -#endif -#ifdef XPAR_UARTLITE_2_BASEADDR -{ - "/dev/ttyS3", /* sDeviceName */ - SERIAL_CUSTOM, /* deviceType */ - &xlite_fns_polled, /* pDeviceFns */ - NULL, /* deviceProbe, assume it is there */ - NULL, /* pDeviceFlow */ - 16, /* ulMargin */ - 8, /* ulHysteresis */ - (void *) NULL, /* NULL */ /* pDeviceParams */ - XPAR_UARTLITE_3_BASEADDR, /* ulCtrlPort1 */ - 0, /* ulCtrlPort2 */ - 0, /* ulDataPort */ - NULL, /* getRegister */ - NULL, /* setRegister */ - NULL, /* unused */ /* getData */ - NULL, /* unused */ /* setData */ - 0, /* ulClock */ - 0 /* ulIntVector -- base for port */ -} -#endif -}; - -unsigned long Console_Configuration_Count = - RTEMS_ARRAY_SIZE(Console_Configuration_Ports); - - -#include - -static void outputChar(char ch) -{ - xlite_write_char_polled( 0, ch ); -} - -static int inputChar(void) -{ - return xlite_read_polled(0); -} - -BSP_output_char_function_type BSP_output_char = outputChar; -BSP_polling_getchar_function_type BSP_poll_char = inputChar; - - diff --git a/c/src/lib/libbsp/powerpc/virtex4/Makefile.am b/c/src/lib/libbsp/powerpc/virtex4/Makefile.am index c15d2b39c8..e8584ac178 100644 --- a/c/src/lib/libbsp/powerpc/virtex4/Makefile.am +++ b/c/src/lib/libbsp/powerpc/virtex4/Makefile.am @@ -32,7 +32,7 @@ librtemsbsp_a_SOURCES += start/start.S # console librtemsbsp_a_SOURCES += startup/dummy_console.c -librtemsbsp_a_SOURCES += ../../shared/dummy_printk_support.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/printk-dummy.c # irq librtemsbsp_a_SOURCES += irq/irq_init.c diff --git a/c/src/lib/libbsp/powerpc/virtex5/Makefile.am b/c/src/lib/libbsp/powerpc/virtex5/Makefile.am index 5c5931943a..45a5da547d 100644 --- a/c/src/lib/libbsp/powerpc/virtex5/Makefile.am +++ b/c/src/lib/libbsp/powerpc/virtex5/Makefile.am @@ -34,7 +34,7 @@ librtemsbsp_a_SOURCES +=../../../../../../bsps/powerpc/shared/clock/p_clock.c # console librtemsbsp_a_SOURCES += startup/dummy_console.c -librtemsbsp_a_SOURCES += ../../shared/dummy_printk_support.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/printk-dummy.c # irq librtemsbsp_a_SOURCES += irq/irq_init.c diff --git a/c/src/lib/libbsp/riscv/riscv_generic/Makefile.am b/c/src/lib/libbsp/riscv/riscv_generic/Makefile.am index 356b56064a..48b6634192 100644 --- a/c/src/lib/libbsp/riscv/riscv_generic/Makefile.am +++ b/c/src/lib/libbsp/riscv/riscv_generic/Makefile.am @@ -48,7 +48,7 @@ librtemsbsp_a_SOURCES +=../../../../../../bsps/riscv/riscv_generic/clock/clockdr librtemsbsp_a_SOURCES += timer/timer.c # console -librtemsbsp_a_SOURCES += ../../shared/console-polled.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-polled.c # IRQ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c @@ -58,7 +58,7 @@ librtemsbsp_a_SOURCES += irq/irq.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/cache/nocache.c # debugio -librtemsbsp_a_SOURCES += console/console-io.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/riscv/riscv_generic/console/console-io.c include $(top_srcdir)/../../../../automake/local.am diff --git a/c/src/lib/libbsp/riscv/riscv_generic/console/console-io.c b/c/src/lib/libbsp/riscv/riscv_generic/console/console-io.c deleted file mode 100644 index ded68ef7d2..0000000000 --- a/c/src/lib/libbsp/riscv/riscv_generic/console/console-io.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2015 University of York. - * Hesham Almatary - * - * Copyright (c) 2013, The Regents of the University of California (Regents). - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include - -/* Most of the code below is copied from riscv-pk project */ -# define TOHOST_CMD(dev, cmd, payload) \ - (((uint64_t)(dev) << 56) | ((uint64_t)(cmd) << 48) | (uint64_t)(payload)) - -#define FROMHOST_DEV(fromhost_value) ((uint64_t)(fromhost_value) >> 56) -#define FROMHOST_CMD(fromhost_value) ((uint64_t)(fromhost_value) << 8 >> 56) -#define FROMHOST_DATA(fromhost_value) ((uint64_t)(fromhost_value) << 16 >> 16) - -volatile uint64_t tohost __attribute__((section(".htif"))); -volatile uint64_t fromhost __attribute__((section(".htif"))); -volatile int htif_console_buf; - -static void __check_fromhost() -{ - uint64_t fh = fromhost; - if (!fh) { - return; - } - fromhost = 0; - - // this should be from the console - assert(FROMHOST_DEV(fh) == 1); - switch (FROMHOST_CMD(fh)) { - case 0: - htif_console_buf = 1 + (uint8_t)FROMHOST_DATA(fh); - break; - case 1: - break; - default: - assert(0); - } -} - -static void __set_tohost(uintptr_t dev, uintptr_t cmd, uintptr_t data) -{ - while (tohost) { - __check_fromhost(); - } - tohost = TOHOST_CMD(dev, cmd, data); -} - -int htif_console_getchar() -{ - __check_fromhost(); - int ch = htif_console_buf; - if (ch >= 0) { - htif_console_buf = -1; - __set_tohost(1, 0, 0); - } - - return ch - 1; -} - -static void do_tohost_fromhost(uintptr_t dev, uintptr_t cmd, uintptr_t data) -{ - __set_tohost(dev, cmd, data); - - while (1) { - uint64_t fh = fromhost; - if (fh) { - if (FROMHOST_DEV(fh) == dev && FROMHOST_CMD(fh) == cmd) { - fromhost = 0; - break; - } - __check_fromhost(); - } - } -} - -void htif_console_putchar(uint8_t ch) -{ - __set_tohost(1, 1, ch); -} - -void htif_poweroff() -{ - while (1) { - fromhost = 0; - tohost = 1; - } -} - -void console_initialize_hardware(void) -{ - /* Do nothing */ -} - -static void outbyte_console(char ch) -{ - htif_console_putchar(ch); -} - -static char inbyte_console(void) -{ - return htif_console_getchar(); -} - -/* - * console_outbyte_polled - * - * This routine transmits a character using polling. - */ -void console_outbyte_polled( - int port, - char ch -) -{ - outbyte_console( ch ); -} - -/* - * console_inbyte_nonblocking - * - * This routine polls for a character. - */ - -int console_inbyte_nonblocking(int port) -{ - char c; - - c = inbyte_console(); - if (!c) { - return -1; - } - return (int) c; -} - -/* - * To support printk - */ - -#include - -static void RISCV_output_char(char c) -{ - console_outbyte_polled( 0, c ); -} - -BSP_output_char_function_type BSP_output_char = RISCV_output_char; -BSP_polling_getchar_function_type BSP_poll_char = - (void *)console_inbyte_nonblocking; diff --git a/c/src/lib/libbsp/sh/gensh1/Makefile.am b/c/src/lib/libbsp/sh/gensh1/Makefile.am index d258a65c6e..f128180cbb 100644 --- a/c/src/lib/libbsp/sh/gensh1/Makefile.am +++ b/c/src/lib/libbsp/sh/gensh1/Makefile.am @@ -40,9 +40,9 @@ librtemsbsp_a_SOURCES += timer/timer.c librtemsbsp_a_SOURCES += scitab.c # console librtemsbsp_a_SOURCES += ../shared/console.c -librtemsbsp_a_SOURCES += console/sci.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sh/gensh1/console/sci.c # debugio -librtemsbsp_a_SOURCES += ../../shared/dummy_printk_support.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/printk-dummy.c # Cache librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/cache/nocache.c diff --git a/c/src/lib/libbsp/sh/gensh1/console/sci.c b/c/src/lib/libbsp/sh/gensh1/console/sci.c deleted file mode 100644 index 04d9ca5c70..0000000000 --- a/c/src/lib/libbsp/sh/gensh1/console/sci.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * /dev/sci[0|1] for Hitachi SH 703X - * - * Author: Ralf Corsepius (corsepiu@faw.uni-ulm.de) - * - * COPYRIGHT (c) 1997-1999, Ralf Corsepius, Ulm, Germany - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * - * COPYRIGHT (c) 1998. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * NOTE: Some SH variants have 3 sci devices - */ - -#define SCI_MINOR_DEVICES 2 - -#define SH_SCI_BASE_0 SCI0_SMR -#define SH_SCI_BASE_1 SCI1_SMR - -struct scidev_t { - char * name ; - uint32_t addr ; - rtems_device_minor_number minor ; - unsigned short opened ; - tcflag_t cflags ; - speed_t spd ; -} sci_device[SCI_MINOR_DEVICES] = -{ - { "/dev/sci0", SH_SCI_BASE_0, 0, 0, CS8, B9600 }, - { "/dev/sci1", SH_SCI_BASE_1, 1, 0, CS8, B9600 } -} ; - -/* imported from scitab.rel */ -extern int _sci_get_brparms( - speed_t spd, - unsigned char *smr, - unsigned char *brr ); - -/* Translate termios' tcflag_t into sci settings */ -static int _sci_set_cflags( - struct scidev_t *sci_dev, - tcflag_t c_cflag, - speed_t spd ) -{ - uint8_t smr ; - uint8_t brr ; - - if ( spd ) - { - if ( _sci_get_brparms( spd, &smr, &brr ) != 0 ) - return -1 ; - } - - if ( c_cflag & CSIZE ) - { - if ( c_cflag & CS8 ) - smr &= ~SCI_SEVEN_BIT_DATA; - else if ( c_cflag & CS7 ) - smr |= SCI_SEVEN_BIT_DATA; - else - return -1 ; - } - - if ( c_cflag & CSTOPB ) - smr |= SCI_STOP_BITS_2; - else - smr &= ~SCI_STOP_BITS_2; - - if ( c_cflag & PARENB ) - smr |= SCI_PARITY_ON ; - else - smr &= ~SCI_PARITY_ON ; - - if ( c_cflag & PARODD ) - smr |= SCI_ODD_PARITY ; - else - smr &= ~SCI_ODD_PARITY; - - write8( smr, sci_dev->addr + SCI_SMR ); - write8( brr, sci_dev->addr + SCI_BRR ); - - return 0 ; -} - -static void _sci_init( - rtems_device_minor_number minor ) -{ - uint16_t temp16 ; - - /* Pin function controller initialisation for asynchronous mode */ - if( minor == 0) - { - temp16 = read16( PFC_PBCR1); - temp16 &= ~( PB8MD | PB9MD ); - temp16 |= (PB_TXD0 | PB_RXD0); - write16( temp16, PFC_PBCR1); - } - else - { - temp16 = read16( PFC_PBCR1); - temp16 &= ~( PB10MD | PB11MD); - temp16 |= (PB_TXD1 | PB_RXD1); - write16( temp16, PFC_PBCR1); - } - - /* disable sck-pin */ - if( minor == 0) - { - temp16 = read16( PFC_PBCR1); - temp16 &= ~(PB12MD); - write16( temp16, PFC_PBCR1); - } - else - { - temp16 = read16( PFC_PBCR1); - temp16 &= ~(PB13MD); - write16( temp16, PFC_PBCR1); - } -} - -static void _sci_tx_polled( - int minor, - const char buf ) -{ - struct scidev_t *scidev = &sci_device[minor] ; - int8_t ssr ; - - while ( !inb((scidev->addr + SCI_SSR) & SCI_TDRE )) - ; - write8(buf,scidev->addr+SCI_TDR); - - ssr = inb(scidev->addr+SCI_SSR); - ssr &= ~SCI_TDRE ; - write8(ssr,scidev->addr+SCI_SSR); -} - -static int _sci_rx_polled ( - int minor) -{ - struct scidev_t *scidev = &sci_device[minor] ; - - unsigned char c; - char ssr ; - ssr = read8(scidev->addr + SCI_SSR) ; - - if (ssr & (SCI_PER | SCI_FER | SCI_ORER)) - write8(ssr & ~(SCI_PER | SCI_FER | SCI_ORER), scidev->addr+SCI_SSR); - - if ( !(ssr & SCI_RDRF) ) - return -1; - - c = read8(scidev->addr + SCI_RDR) ; - - write8(ssr & ~SCI_RDRF,scidev->addr + SCI_SSR); - return c; -} - -/* - * sci_initialize - */ - -rtems_device_driver sh_sci_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg ) -{ - rtems_device_driver status ; - rtems_device_minor_number i; - - /* - * register all possible devices. - * the initialization of the hardware is done by sci_open - */ - - for ( i = 0 ; i < SCI_MINOR_DEVICES ; i++ ) - { - status = rtems_io_register_name( - sci_device[i].name, - major, - sci_device[i].minor ); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - } - - /* default hardware setup */ - - return RTEMS_SUCCESSFUL; -} - - -/* - * Open entry point - */ - -rtems_device_driver sh_sci_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg ) -{ - uint8_t temp8; - - /* check for valid minor number */ - if(( minor > ( SCI_MINOR_DEVICES -1 )) || ( minor < 0 )) - { - return RTEMS_INVALID_NUMBER; - } - - /* device already opened */ - if ( sci_device[minor].opened > 0 ) - { - sci_device[minor].opened++ ; - return RTEMS_SUCCESSFUL ; - } - - _sci_init( minor ); - - if (minor == 0) { - temp8 = read8(sci_device[minor].addr + SCI_SCR); - temp8 &= ~(SCI_TE | SCI_RE) ; - write8(temp8, sci_device[minor].addr + SCI_SCR); /* Clear SCR */ - _sci_set_cflags( &sci_device[minor], sci_device[minor].cflags, sci_device[minor].spd ); - -/* FIXME: Should be one bit delay */ - CPU_delay(50000); /* microseconds */ - - temp8 |= SCI_RE | SCI_TE; - write8(temp8, sci_device[minor].addr + SCI_SCR); /* Enable clock output */ - } else { - temp8 = read8(sci_device[minor].addr + SCI_SCR); - temp8 &= ~(SCI_TE | SCI_RE) ; - write8(temp8, sci_device[minor].addr + SCI_SCR); /* Clear SCR */ - _sci_set_cflags( &sci_device[minor], sci_device[minor].cflags, sci_device[minor].spd ); - -/* FIXME: Should be one bit delay */ - CPU_delay(50000); /* microseconds */ - - temp8 |= SCI_RE | SCI_TE; - write8(temp8, sci_device[minor].addr + SCI_SCR); /* Enable clock output */ - } - - sci_device[minor].opened++ ; - - return RTEMS_SUCCESSFUL ; -} - -/* - * Close entry point - */ - -rtems_device_driver sh_sci_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - if( sci_device[minor].opened == 0 ) - { - return RTEMS_INVALID_NUMBER; - } - - sci_device[minor].opened-- ; - - return RTEMS_SUCCESSFUL ; -} - -/* - * read bytes from the serial port. - */ - -rtems_device_driver sh_sci_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - int count = 0; - - rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg; - char * buffer = rw_args->buffer; - int maximum = rw_args->count; - - for (count = 0; count < maximum; count++) { - buffer[ count ] = _sci_rx_polled(minor); - if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { - buffer[ count++ ] = '\n'; - break; - } - } - - rw_args->bytes_moved = count; - return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; -} - -/* - * write bytes to the serial port. - */ - -rtems_device_driver sh_sci_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - int count; - - rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg; - char *buffer = rw_args->buffer; - int maximum = rw_args->count; - - for (count = 0; count < maximum; count++) { -#if 0 - if ( buffer[ count ] == '\n') { - outbyte(minor, '\r'); - } -#endif - _sci_tx_polled( minor, buffer[ count ] ); - } - - rw_args->bytes_moved = maximum; - return 0; -} - -/* - * IO Control entry point - */ - -rtems_device_driver sh_sci_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - /* Not yet supported */ - return RTEMS_SUCCESSFUL ; -} diff --git a/c/src/lib/libbsp/sh/gensh2/Makefile.am b/c/src/lib/libbsp/sh/gensh2/Makefile.am index 205e13ca8c..9a67271b6d 100644 --- a/c/src/lib/libbsp/sh/gensh2/Makefile.am +++ b/c/src/lib/libbsp/sh/gensh2/Makefile.am @@ -42,11 +42,11 @@ librtemsbsp_a_SOURCES += timer/timer.c librtemsbsp_a_SOURCES += scitab.c # console librtemsbsp_a_SOURCES += ../shared/console.c -librtemsbsp_a_SOURCES += console/config.c -librtemsbsp_a_SOURCES += console/sci.c -librtemsbsp_a_SOURCES += console/sci_termios.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sh/gensh2/console/config.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sh/gensh2/console/sci.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sh/gensh2/console/sci_termios.c # debugio -librtemsbsp_a_SOURCES += ../../shared/dummy_printk_support.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/printk-dummy.c # Cache librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/cache/nocache.c diff --git a/c/src/lib/libbsp/sh/gensh2/console/config.c b/c/src/lib/libbsp/sh/gensh2/console/config.c deleted file mode 100644 index a2f25742dd..0000000000 --- a/c/src/lib/libbsp/sh/gensh2/console/config.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * This file contains the TTY driver table. The implementation is - * based on libchip/serial drivers, but it uses internal SHx SCI so - * the implementation of the driver is placed in - * lib/libcpu/sh/sh7045/sci instead of libchip/serial. - * - * COPYRIGHT (c) 1989-2001. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Function set for interrupt enabled termios console - */ -const console_fns sh_sci_fns = -{ - libchip_serial_default_probe, /* deviceProbe */ - sh_sci_first_open, /* deviceFirstOpen */ - NULL, /* deviceLastClose */ - NULL, /* deviceRead */ - sh_sci_write_support_int, /* deviceWrite */ - sh_sci_initialize_interrupts, /* deviceInitialize */ - sh_sci_write_polled, /* deviceWritePolled */ - sh_sci_set_attributes, /* deviceSetAttributes */ - TERMIOS_IRQ_DRIVEN /* deviceOutputUsesInterrupts */ -}; - -/* - * Function set for polled termios console - */ -const console_fns sh_sci_fns_polled = -{ - libchip_serial_default_probe, /* deviceProbe */ - sh_sci_first_open, /* deviceFirstOpen */ - sh_sci_last_close, /* deviceLastClose */ - sh_sci_inbyte_nonblocking_polled, /* deviceRead */ - sh_sci_write_support_polled, /* deviceWrite */ - sh_sci_init, /* deviceInitialize */ - sh_sci_write_polled, /* deviceWritePolled */ - sh_sci_set_attributes, /* deviceSetAttributes */ - TERMIOS_POLLED /* deviceOutputUsesInterrupts */ -}; - -#if 1 /* (CONSOLE_USE_INTERRUPTS) */ -#define SCI_FUNCTIONS &sh_sci_fns -#else -#define SCI_FUNCTIONS &sh_sci_fns_polled -#endif - -static const struct termios term1 = { - 0, - 0, - 0, - 0, - {0}, - B9600 | CS8, - B9600 | CS8 -}; - -static const struct termios term2 = { - 0, - 0, - 0, - 0, - {0}, - B115200 | CS8, - B115200 | CS8 -}; - -console_tbl Console_Configuration_Ports[] = { - { - "/dev/sci0", /* sDeviceName */ - SERIAL_CUSTOM, /* deviceType */ - SCI_FUNCTIONS, /* pDeviceFns */ - NULL, /* deviceProbe */ - NULL, /* pDeviceFlow */ - 16, /* ulMargin */ - 8, /* ulHysteresis */ - (void *)&term1, /* baud rate */ /* pDeviceParams */ - SCI_SMR0, /* ulCtrlPort1 */ - 3, /* ulCtrlPort2 as IRQ priority level*/ - TXI0_ISP_V, /* ulDataPort as TX end vector number*/ - NULL, /* unused */ /* getRegister */ - NULL, /* unused */ /* setRegister */ - NULL, /* unused */ /* getData */ - NULL, /* unused */ /* setData */ - 0, /* ulClock */ - RXI0_ISP_V, /* ulIntVector as RX end vector number*/ - }, - { - "/dev/sci1", /* sDeviceName */ - SERIAL_CUSTOM, /* deviceType */ - SCI_FUNCTIONS, /* pDeviceFns */ - NULL, /* deviceProbe */ - NULL, /* pDeviceFlow */ - 16, /* ulMargin */ - 8, /* ulHysteresis */ - (void *)&term2, /* baud rate */ /* pDeviceParams */ - SCI_SMR1, /* ulCtrlPort1 */ - 3, /* ulCtrlPort2 as IRQ priority level*/ - TXI1_ISP_V, /* ulDataPort as TX end vector number*/ - NULL, /* unused */ /* getRegister */ - NULL, /* unused */ /* setRegister */ - NULL, /* unused */ /* getData */ - NULL, /* unused */ /* setData */ - 0, /* ulClock */ - RXI1_ISP_V, /* ulIntVector as RX end vector number*/ - } -}; - -/* - * Declare some information used by the console driver - */ - -#define NUM_CONSOLE_PORTS (sizeof(Console_Configuration_Ports)/sizeof(console_tbl)) - -unsigned long Console_Configuration_Count = NUM_CONSOLE_PORTS; diff --git a/c/src/lib/libbsp/sh/gensh2/console/sci.c b/c/src/lib/libbsp/sh/gensh2/console/sci.c deleted file mode 100644 index 143fc1bb94..0000000000 --- a/c/src/lib/libbsp/sh/gensh2/console/sci.c +++ /dev/null @@ -1,554 +0,0 @@ -/* - * /dev/sci[0|1] for Hitachi SH 704X - * - * The SH doesn't have a designated console device. Therefore we "alias" - * another device as /dev/console and revector all calls to /dev/console - * to this device. - * - * This approach is similar to installing a sym-link from one device to - * another device. If rtems once will support sym-links for devices files, - * this implementation could be dropped. - */ - -/* - * Author: Ralf Corsepius (corsepiu@faw.uni-ulm.de) - * - * COPYRIGHT (c) 1997-1998, FAW Ulm, Germany - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * - * COPYRIGHT (c) 1998. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - * Modified to reflect sh7045 processor: - * John M. Mills (jmills@tga.com) - * TGA Technologies, Inc. - * 100 Pinnacle Way, Suite 140 - * Norcross, GA 30071 U.S.A. - * - * This modified file may be copied and distributed in accordance - * the above-referenced license. It is provided for critique and - * developmental purposes without any warranty nor representation - * by the authors or by TGA Technologies. - */ - -#include - - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifndef STANDALONE_EVB -#define STANDALONE_EVB 0 -#endif - -/* - * NOTE: Some SH variants have 3 sci devices - */ - -#define SCI_MINOR_DEVICES 2 - -/* - * FIXME: sh7045 register names match Hitachi data book, - * but conflict with RTEMS sh7032 usage. - */ - -#define SH_SCI_BASE_0 SCI_SMR0 -#define SH_SCI_BASE_1 SCI_SMR1 - -#define SH_SCI_DEF_COMM_0 CS8, B9600 -#define SH_SCI_DEF_COMM_1 CS8, B38400 -/* #define SH_SCI_DEF_COMM_1 CS8, B9600 */ - -struct scidev_t { - char * name; - uint32_t addr; - rtems_device_minor_number minor; - unsigned short opened; - tcflag_t cflags; - speed_t spd; -} sci_device[SCI_MINOR_DEVICES] = -{ - { "/dev/sci0", SH_SCI_BASE_0, 0, 0, SH_SCI_DEF_COMM_0 }, - { "/dev/sci1", SH_SCI_BASE_1, 1, 0, SH_SCI_DEF_COMM_1 } -}; - -/* local data structures maintain hardware configuration */ -#if UNUSED -static sci_setup_t sio_param[2]; -#endif - -/* Translate termios' tcflag_t into sci settings */ -static int _sci_set_cflags( - struct scidev_t *sci_dev, - tcflag_t c_cflag, - speed_t spd -) -{ - uint8_t smr; - uint8_t brr; - - if ( spd ) - { - if ( _sci_get_brparms( spd, &smr, &brr ) != 0 ) - return -1; - } - - if ( c_cflag & CSIZE ) - { - if ( c_cflag & CS8 ) - smr &= ~SCI_SEVEN_BIT_DATA; - else if ( c_cflag & CS7 ) - smr |= SCI_SEVEN_BIT_DATA; - else - return -1; - } - - if ( c_cflag & CSTOPB ) - smr |= SCI_STOP_BITS_2; - else - smr &= ~SCI_STOP_BITS_2; - - if ( c_cflag & PARENB ) - smr |= SCI_PARITY_ON; - else - smr &= ~SCI_PARITY_ON; - - if ( c_cflag & PARODD ) - smr |= SCI_ODD_PARITY; - else - smr &= ~SCI_ODD_PARITY; - - write8( smr, sci_dev->addr + SCI_SMR ); - write8( brr, sci_dev->addr + SCI_BRR ); - - return 0; -} - -/* - * local functions operate SCI ports 0 and 1 - * called from polling routines or ISRs - */ -static bool wrtSCI0(unsigned char ch) -{ - uint8_t temp; - bool result = false; - - if ((read8(SCI_SSR0) & SCI_TDRE) != 0x00) { - /* Write the character to the TDR */ - write8(ch, SCI_TDR0); - /* Clear the TDRE bit */ - temp = read8(SCI_SSR0) & ~SCI_TDRE; - write8(temp, SCI_SSR0); - result = true; - } - return result; -} /* wrtSCI0 */ - -static bool wrtSCI1(unsigned char ch) -{ - uint8_t temp; - bool result = false; - - if ((read8(SCI_SSR1) & SCI_TDRE) != 0x00) { - /* Write the character to the TDR */ - write8(ch, SCI_TDR1); - /* Clear the TDRE bit */ - temp = read8(SCI_SSR1) & ~SCI_TDRE; - write8(temp, SCI_SSR1); - result = true; - } - return result; -} /* wrtSCI1 */ - -/* polled output steers byte to selected port */ -static void sh_sci_outbyte_polled( - rtems_device_minor_number minor, - char ch ) -{ - if (minor == 0) /* blocks until port ready */ - while (wrtSCI0(ch) != true); /* SCI0*/ - else - while (wrtSCI1(ch) != true); /* SCI1*/ -} /* sh_sci_outbyte_polled */ - -/* - * Initial version calls polled output driver and blocks - */ -static void outbyte( - rtems_device_minor_number minor, - char ch) -{ - sh_sci_outbyte_polled(minor, (unsigned char)ch); -} /* outbyte */ - -static bool rdSCI0(unsigned char *ch) -{ - uint8_t temp; - bool result = false; - - if ((read8(SCI_SSR0) & SCI_RDRF) != 0x00) { - /* read input */ - *ch = read8(SCI_RDR0); - /* Clear RDRF flag */ - temp = read8(SCI_SSR0) & ~SCI_RDRF; - write8(temp, SCI_SSR0); - /* Check for transmission errors */ - if (temp & (SCI_ORER | SCI_FER | SCI_PER)) { - /* TODO: report to RTEMS transmission error */ - - /* clear error flags*/ - temp &= ~(SCI_ORER | SCI_FER | SCI_PER); - write8(temp, SCI_SSR0); - } - result = true; - } - return result; -} /* rdSCI0 */ - -static bool rdSCI1(unsigned char *ch) -{ - uint8_t temp; - bool result = false; - - if ((read8(SCI_SSR1) & SCI_RDRF) != 0x00) { - /* read input */ - *ch = read8(SCI_RDR1); - /* Clear RDRF flag */ - temp= read8(SCI_SSR1) & ~SCI_RDRF; - write8(temp, SCI_SSR1); - /* Check for transmission errors */ - if (temp & (SCI_ORER | SCI_FER | SCI_PER)) { - /* TODO: report to RTEMS transmission error */ - - /* clear error flags*/ - temp &= ~(SCI_ORER | SCI_FER | SCI_PER); - write8(temp, SCI_SSR1); - } - result = true; - } - return result; -} /* rdSCI1 */ - -/* initial version pulls byte from selected port */ -static char sh_sci_inbyte_polled( rtems_device_minor_number minor ) -{ - uint8_t ch = 0; - - if (minor == 0) /* blocks until char.ready */ - while (rdSCI0(&ch) != true); /* SCI0 */ - else - while (rdSCI1(&ch) != true); /* SCI1 */ - return ch; -} /* sh_sci_inbyte_polled */ - -/* Initial version calls polled input driver */ -static char inbyte( rtems_device_minor_number minor ) -{ - char ch; - - ch = sh_sci_inbyte_polled(minor); - return ch; -} /* inbyte */ - -/* sh_sci_initialize - * - * This routine initializes (registers) the sh_sci IO drivers. - * - * Input parameters: ignored - * - * Output parameters: NONE - * - * Return values: RTEMS_SUCCESSFUL - * if all sci[...] register, else calls - * rtems_fatal_error_occurred(status) - */ -rtems_device_driver sh_sci_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg ) -{ - rtems_device_driver status; - rtems_device_minor_number i; - - /* - * register all possible devices. - * the initialization of the hardware is done by sci_open - * - * One of devices could be previously registered by console - * initialization therefore we check it everytime - */ - for ( i = 0 ; i < SCI_MINOR_DEVICES ; i++ ) { - /* OK. We assume it is not registered yet. */ - status = rtems_io_register_name( - sci_device[i].name, - major, - sci_device[i].minor - ); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - } - - /* non-default hardware setup occurs in sh_sci_open() */ - return RTEMS_SUCCESSFUL; -} - -/* - * Open entry point - * Sets up port and pins for selected sci. - */ -rtems_device_driver sh_sci_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg ) -{ - uint8_t temp8; - uint16_t temp16; - - unsigned a; - - /* check for valid minor number */ - if (( minor > ( SCI_MINOR_DEVICES -1 )) || ( minor < 0 )) { - return RTEMS_INVALID_NUMBER; - } - - /* device already opened */ - if ( sci_device[minor].opened > 0 ) { - sci_device[minor].opened++; - return RTEMS_SUCCESSFUL; - } - - /* set PFC registers to enable I/O pins */ - - if ((minor == 0)) { - temp16 = read16(PFC_PACRL2); /* disable SCK0, DMA, IRQ */ - temp16 &= ~(PA2MD1 | PA2MD0); - temp16 |= (PA_TXD0 | PA_RXD0); /* enable pins for Tx0, Rx0 */ - write16(temp16, PFC_PACRL2); - - } else if (minor == 1) { - temp16 = read16(PFC_PACRL2); /* disable SCK1, DMA, IRQ */ - temp16 &= ~(PA5MD1 | PA5MD0); - temp16 |= (PA_TXD1 | PA_RXD1); /* enable pins for Tx1, Rx1 */ - write16(temp16, PFC_PACRL2); - - } /* add other devices and pins as req'd. */ - - /* set up SCI registers */ - write8(0x00, sci_device[minor].addr + SCI_SCR); /* Clear SCR */ - /* set SMR and BRR */ - _sci_set_cflags( &sci_device[minor], sci_device[minor].cflags, sci_device[minor].spd ); - - for (a=0; a < 10000L; a++) { /* Delay */ - __asm__ volatile ("nop"); - } - - write8((SCI_RE | SCI_TE), /* enable async. Tx and Rx */ - sci_device[minor].addr + SCI_SCR); - - /* clear error flags */ - temp8 = read8(sci_device[minor].addr + SCI_SSR); - while (temp8 & (SCI_RDRF | SCI_ORER | SCI_FER | SCI_PER)) { - temp8 = read8(sci_device[minor].addr + SCI_RDR); /* flush input */ - temp8 = read8(sci_device[minor].addr + SCI_SSR); /* clear some flags */ - write8(temp8 & ~(SCI_RDRF | SCI_ORER | SCI_FER | SCI_PER), - sci_device[minor].addr + SCI_SSR); - temp8 = read8(sci_device[minor].addr + SCI_SSR); /* check if everything is OK */ - } - /* Clear RDRF flag */ - write8(0x00, sci_device[minor].addr + SCI_TDR); /* force output */ - /* Clear the TDRE bit */ - temp8 = read8(sci_device[minor].addr + SCI_SSR) & ~SCI_TDRE; - write8(temp8, sci_device[minor].addr + SCI_SSR); - - /* add interrupt setup if required */ - - - sci_device[minor].opened++; - - return RTEMS_SUCCESSFUL; -} - -/* - * Close entry point - */ -rtems_device_driver sh_sci_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - /* FIXME: Incomplete */ - if ( sci_device[minor].opened > 0 ) - sci_device[minor].opened--; - else - return RTEMS_INVALID_NUMBER; - - return RTEMS_SUCCESSFUL; -} - -/* - * read bytes from the serial port. We only have stdin. - */ -rtems_device_driver sh_sci_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_libio_rw_args_t *rw_args; - char *buffer; - int maximum; - int count = 0; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - for (count = 0; count < maximum; count++) { - buffer[ count ] = inbyte(minor); - if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { - buffer[ count++ ] = '\n'; - break; - } - } - - rw_args->bytes_moved = count; - return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; -} - -/* - * write bytes to the serial port. Stdout and stderr are the same. - */ -rtems_device_driver sh_sci_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - int count; - int maximum; - rtems_libio_rw_args_t *rw_args; - char *buffer; - - rw_args = (rtems_libio_rw_args_t *) arg; - - buffer = rw_args->buffer; - maximum = rw_args->count; - - for (count = 0; count < maximum; count++) { - if ( buffer[ count ] == '\n') { - outbyte(minor, '\r'); - } - outbyte( minor, buffer[ count ] ); - } - - rw_args->bytes_moved = maximum; - return 0; -} - -/* - * IO Control entry point - */ -rtems_device_driver sh_sci_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - /* Not yet supported */ - return RTEMS_SUCCESSFUL; -} - -/* - * Termios polled first open - */ -static int _sh_sci_poll_first_open(int major, int minor, void *arg) -{ - return sh_sci_open(major, minor, arg); -} - -/* - * Termios general last close - */ -static int _sh_sci_last_close(int major, int minor, void *arg) -{ - return sh_sci_close(major, minor, arg); -} - -/* - * Termios polled read - */ -static int _sh_sci_poll_read(int minor) -{ - int value = -1; - uint8_t ch = 0; - - if ( minor == 0 ) { - if ( rdSCI0( &ch ) ) - value = (int) ch; - } else if ( minor == 1 ) { - if ( rdSCI1( &ch ) ) - value = (int) ch; - } - return value; -} - -/* - * Termios polled write - */ -static ssize_t _sh_sci_poll_write(int minor, const char *buf, size_t len) -{ - size_t count; - - for (count = 0; count < len; count++) - outbyte( minor, buf[count] ); - return count; -} - -/* - * Termios set attributes - */ -static int _sh_sci_set_attributes( int minor, const struct termios *t) -{ - return _sci_set_cflags( &sci_device[ minor ], t->c_cflag, t->c_ospeed); -} - - -const rtems_termios_callbacks sci_poll_callbacks = { - _sh_sci_poll_first_open, /* FirstOpen*/ - _sh_sci_last_close, /* LastClose*/ - _sh_sci_poll_read, /* PollRead */ - _sh_sci_poll_write, /* Write */ - _sh_sci_set_attributes, /* setAttributes */ - NULL, /* stopRemoteTX */ - NULL, /* StartRemoteTX */ - 0 /* outputUsesInterrupts */ -}; - -/* FIXME: not yet supported */ -const rtems_termios_callbacks sci_interrupt_callbacks; - -const rtems_termios_callbacks* sh_sci_get_termios_handlers( bool poll ) -{ - return poll ? - &sci_poll_callbacks : - &sci_interrupt_callbacks; -} diff --git a/c/src/lib/libbsp/sh/gensh2/console/sci_termios.c b/c/src/lib/libbsp/sh/gensh2/console/sci_termios.c deleted file mode 100644 index 5d588065af..0000000000 --- a/c/src/lib/libbsp/sh/gensh2/console/sci_termios.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * Termios console serial driver. - */ - -/* - * Based on SCI driver by Ralf Corsepius and John M. Mills - * - * Author: Radzislaw Galler - * - * COPYRIGHT (c) 1989-2001. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - */ - -#include -#include - -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include - - -/* - * Some handy macros - */ -#define SH_SCI_REG_DATA(_data, _minor, _register) \ - (write8(_data, Console_Port_Tbl[_minor]->ulCtrlPort1 + (_register))) - -#define SH_SCI_REG_FLAG(_flag, _minor, _register) \ - (write8(read8(Console_Port_Tbl[_minor]->ulCtrlPort1 + (_register)) | (_flag), \ - Console_Port_Tbl[_minor]->ulCtrlPort1 + (_register))) - -#define SH_SCI_REG_MASK(_flag, _minor, _register) \ - (write8(read8(Console_Port_Tbl[_minor]->ulCtrlPort1 + (_register)) & ~(_flag),\ - Console_Port_Tbl[_minor]->ulCtrlPort1 + (_register))) - -/* - * NOTE: Some SH variants have 3 sci devices - */ - -#define SCI_MINOR_DEVICES 2 - - -/* - * Automatically generated function imported from scitab.rel - */ -extern int _sci_get_brparms( - speed_t spd, - unsigned char *smr, - unsigned char *brr -); - -/* - * Translate termios flags into SCI settings - */ -int sh_sci_set_attributes( - int minor, - const struct termios *t -) -{ - uint8_t smr; - uint8_t brr; - int a; - - tcflag_t c_cflag = t->c_cflag; - speed_t spd = t->c_ospeed; - - if ( spd ) { - if ( _sci_get_brparms( spd, &smr, &brr ) != 0 ) - return -1 ; - } - - if ( c_cflag & CSIZE ) { - if ( c_cflag & CS8 ) - smr &= ~SCI_SEVEN_BIT_DATA; - else if ( c_cflag & CS7 ) - smr |= SCI_SEVEN_BIT_DATA; - else - return -1 ; - } - - if ( c_cflag & CSTOPB ) - smr |= SCI_STOP_BITS_2; - else - smr &= ~SCI_STOP_BITS_2; - - if ( c_cflag & PARENB ) - smr |= SCI_PARITY_ON ; - else - smr &= ~SCI_PARITY_ON ; - - if ( c_cflag & PARODD ) - smr |= SCI_ODD_PARITY ; - else - smr &= ~SCI_ODD_PARITY; - - SH_SCI_REG_MASK((SCI_RE | SCI_TE), minor, SCI_SCR); - - SH_SCI_REG_DATA(smr, minor, SCI_SMR); - SH_SCI_REG_DATA(brr, minor, SCI_BRR); - - for (a=0; a < 10000L; a++) { /* Delay one bit */ - __asm__ volatile ("nop"); - } - - SH_SCI_REG_FLAG((SCI_RE | SCI_TE), minor, SCI_SCR); - - return 0; -} - -/* - * Receive-data-full ISR - * - * The same routine for all interrupt sources of the same type. - */ -static rtems_isr sh_sci_rx_isr(rtems_vector_number vector) -{ - int minor; - - for (minor = 0; minor < Console_Port_Count; minor++) { - if (Console_Port_Tbl[minor]->ulIntVector == vector) { - char temp8; - - /* - * FIXME: error handling should be added - */ - temp8 = read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_RDR); - - rtems_termios_enqueue_raw_characters( - Console_Port_Data[minor].termios_data, &temp8, 1); - - SH_SCI_REG_MASK(SCI_RDRF, minor, SCI_SSR); - break; - } - } -} - -/* - * Transmit-data-empty ISR - * - * The same routine for all interrupt sources of the same type. - */ -static rtems_isr sh_sci_tx_isr(rtems_vector_number vector) -{ - int minor; - - for (minor = 0; minor < Console_Port_Count; minor++) { - if (Console_Port_Tbl[minor]->ulDataPort == vector) { - /* - * FIXME: Error handling should be added - */ - - /* - * Mask end-of-transmission interrupt - */ - SH_SCI_REG_MASK(SCI_TIE, minor, SCI_SCR); - - if (rtems_termios_dequeue_characters( - Console_Port_Data[minor].termios_data, 1)) { - /* - * More characters to be received - interrupt must be enabled - */ - SH_SCI_REG_FLAG(SCI_TIE, minor, SCI_SCR); - } - break; - } - } -} - - -/* - * Initialization of serial port - */ -void sh_sci_init(int minor) -{ - uint16_t temp16; - - /* - * set PFC registers to enable I/O pins - */ - if ((minor == 0)) { - temp16 = read16(PFC_PACRL2); /* disable SCK0, DMA, IRQ */ - temp16 &= ~(PA2MD1 | PA2MD0); - temp16 |= (PA_TXD0 | PA_RXD0); /* enable pins for Tx0, Rx0 */ - write16(temp16, PFC_PACRL2); - - } else if (minor == 1) { - temp16 = read16(PFC_PACRL2); /* disable SCK1, DMA, IRQ */ - temp16 &= ~(PA5MD1 | PA5MD0); - temp16 |= (PA_TXD1 | PA_RXD1); /* enable pins for Tx1, Rx1 */ - write16(temp16, PFC_PACRL2); - } - - /* - * Non-default hardware setup occurs in sh_sci_first_open - */ -} - -/* - * Initialization of interrupts - * - * Interrupts can be started only after opening a device, so interrupt - * flags are set up in sh_sci_first_open function - */ -void sh_sci_initialize_interrupts(int minor) -{ - rtems_isr_entry old_isr; - rtems_status_code status; - - sh_sci_init(minor); - /* - * Disable IRQ of SCIx - */ - status = sh_set_irq_priority( Console_Port_Tbl[minor]->ulIntVector, 0); - - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - SH_SCI_REG_MASK(SCI_RIE, minor, SCI_SCR); - - /* - * Catch apropriate vectors - */ - status = rtems_interrupt_catch( - sh_sci_rx_isr, - Console_Port_Tbl[minor]->ulIntVector, - &old_isr); - - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - status = rtems_interrupt_catch( - sh_sci_tx_isr, - Console_Port_Tbl[minor]->ulDataPort, - &old_isr); - - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - /* - * Enable IRQ of SCIx - */ - SH_SCI_REG_FLAG(SCI_RIE, minor, SCI_SCR); - - status = sh_set_irq_priority( - Console_Port_Tbl[minor]->ulIntVector, - Console_Port_Tbl[minor]->ulCtrlPort2); - - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); -} - - -/* - * Open entry point - * Sets up port and pins for selected sci. - */ - -int sh_sci_first_open( - int major, - int minor, - void *arg -) -{ - char temp8; - unsigned int a ; - - /* - * check for valid minor number - */ - if (( minor > ( SCI_MINOR_DEVICES -1 )) || ( minor < 0 )) { - return RTEMS_INVALID_NUMBER; - } - - /* - * set up SCI registers - */ - /* Clear SCR - disable Tx and Rx */ - SH_SCI_REG_DATA(0x00, minor, SCI_SCR); - - /* set SMR and BRR - baudrate and format */ - sh_sci_set_attributes(minor, Console_Port_Tbl[minor]->pDeviceParams); - - for (a=0; a < 10000L; a++) { /* Delay */ - __asm__ volatile ("nop"); - } - - write8((SCI_RE | SCI_TE), /* enable async. Tx and Rx */ - Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_SCR); - - /* - * clear error flags - */ - temp8 = read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_SSR); - while(temp8 & (SCI_RDRF | SCI_ORER | SCI_FER | SCI_PER)) { - /* flush input */ - temp8 = read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_RDR); - - /* clear some flags */ - SH_SCI_REG_FLAG((SCI_RDRF|SCI_ORER|SCI_FER|SCI_PER), minor, SCI_SSR); - - /* check if everything is OK */ - temp8 = read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_SSR); - } - - /* Clear RDRF flag */ - SH_SCI_REG_DATA(0x00, minor, SCI_TDR); /* force output */ - - /* Clear the TDRE bit */ - SH_SCI_REG_FLAG(SCI_TDRE, minor, SCI_SSR); - - /* - * Interrupt setup - */ - if (Console_Port_Tbl[minor]->pDeviceFns->deviceOutputUsesInterrupts) { - SH_SCI_REG_FLAG(SCI_RIE, minor, SCI_SCR); - } - - return RTEMS_SUCCESSFUL ; -} - -/* - * Close entry point - */ - -int sh_sci_last_close( - int major, - int minor, - void *arg -) -{ - /* FIXME: Incomplete */ - - /* Shutdown interrupts if necessary */ - if (Console_Port_Tbl[minor]->pDeviceFns->deviceOutputUsesInterrupts) - { - SH_SCI_REG_MASK((SCI_TIE | SCI_RIE), minor, SCI_SCR); - } - return RTEMS_SUCCESSFUL ; -} - -/* - * Interrupt aware write routine - */ -ssize_t sh_sci_write_support_int( - int minor, - const char *buf, - size_t len -) -{ - if (!len) - return 0; - /* - * Put data into TDR and clear transmission-end-flag - */ - SH_SCI_REG_DATA(*buf, minor, SCI_TDR); - SH_SCI_REG_MASK(SCI_TDRE, minor, SCI_SSR); - /* - * Enable interrupt - */ - SH_SCI_REG_FLAG(SCI_TIE, minor, SCI_SCR); - - return 1; -} - -/* - * Polled write method - */ -ssize_t sh_sci_write_support_polled( - int minor, - const char *buf, - size_t len -) -{ - int count = 0; - - while(count < len) { - sh_sci_write_polled(minor, buf[count]); - count++; - } - /* - * Return number of bytes written - */ - return count; -} - -/* - * Polled write of one character at a time - */ -void sh_sci_write_polled( - int minor, - char c -) -{ - /* - * Wait for end of previous character - */ - while(!(read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_SSR) & SCI_TDRE)); - /* - * Send the character - */ - SH_SCI_REG_DATA(c, minor, SCI_TDR); - - /* - * Clear TDRE flag - */ - SH_SCI_REG_MASK(SCI_TDRE, minor, SCI_SSR); -} - -/* - * Non-blocking read - */ -int sh_sci_inbyte_nonblocking_polled(int minor) -{ - char inbyte; - - /* - * Check if input buffer is full - */ - if (read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_SSR) & SCI_RDRF) { - inbyte = read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_RDR); - SH_SCI_REG_MASK(SCI_RDRF, minor, SCI_SSR); - - /* - * Check for errors - */ - if (read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_SSR) & - (SCI_ORER | SCI_FER | SCI_PER)) { - SH_SCI_REG_MASK((SCI_ORER | SCI_FER | SCI_PER), minor, SCI_SSR); - return -1; - } - return (int)inbyte; - } - return -1; -} diff --git a/c/src/lib/libbsp/sh/gensh4/Makefile.am b/c/src/lib/libbsp/sh/gensh4/Makefile.am index 94c0601cc8..92a9cdf6e7 100644 --- a/c/src/lib/libbsp/sh/gensh4/Makefile.am +++ b/c/src/lib/libbsp/sh/gensh4/Makefile.am @@ -30,9 +30,9 @@ librtemsbsp_a_SOURCES += startup/ispsh7750.c librtemsbsp_a_SOURCES +=../../../../../../bsps/sh/gensh4/clock/ckinit.c librtemsbsp_a_SOURCES += timer/timer.c # console -librtemsbsp_a_SOURCES += console/console.c -librtemsbsp_a_SOURCES += ../../shared/dummy_printk_support.c -librtemsbsp_a_SOURCES += console/sh4uart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sh/gensh4/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/printk-dummy.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sh/gensh4/console/sh4uart.c # hw_init librtemsbsp_a_SOURCES += hw_init/hw_init.c diff --git a/c/src/lib/libbsp/sh/gensh4/console/console.c b/c/src/lib/libbsp/sh/gensh4/console/console.c deleted file mode 100644 index 917556df4e..0000000000 --- a/c/src/lib/libbsp/sh/gensh4/console/console.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - * Console driver for SH-4 UART modules - * - * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia - * Author: Alexandra Kossovsky - * - * COPYRIGHT (c) 1989-1998. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include -#include - -#include "sh/sh4uart.h" - -/* Descriptor structures for two on-chip UART channels */ -sh4uart sh4_uarts[2]; - -/* Console operations mode: - * 0 - raw (non-termios) polled input/output - * 1 - termios-based polled input/output - * 2 - termios-based interrupt-driven input/output - * 3 - non-termios over gdb stub - */ -int console_mode = 3; -#define CONSOLE_MODE_RAW (0) -#define CONSOLE_MODE_POLL (1) -#define CONSOLE_MODE_INT (2) -#define CONSOLE_MODE_IPL (3) - -/* Wrapper functions for SH-4 UART generic driver */ - -/* console_poll_read -- - * wrapper for poll read function - * - * PARAMETERS: - * minor - minor device number - * - * RETURNS: - * character code readed from UART, or -1 if there is no characters - * available - */ -static int -console_poll_read(int minor) -{ - return sh4uart_poll_read(&sh4_uarts[minor]); -} - -/* console_interrupt_write -- - * wrapper for interrupt write function - * - * PARAMETERS: - * minor - minor device number - * buf - output buffer - * len - output buffer length - * - * RETURNS: - * result code - */ -static ssize_t -console_interrupt_write(int minor, const char *buf, size_t len) -{ - return sh4uart_interrupt_write(&sh4_uarts[minor], buf, len); -} - -/* console_poll_write -- - * wrapper for polling mode write function - * - * PARAMETERS: - * minor - minor device number - * buf - output buffer - * len - output buffer length - * - * RETURNS: - * result code - */ -static ssize_t -console_poll_write(int minor, const char *buf, size_t len) -{ - return sh4uart_poll_write(&sh4_uarts[minor], buf, len); -} - -/* console_set_attributes -- - * wrapper for hardware-dependent termios attributes setting - * - * PARAMETERS: - * minor - minor device number - * t - pointer to the termios structure - * - * RETURNS: - * result code - */ -static int -console_set_attributes(int minor, const struct termios *t) -{ - return sh4uart_set_attributes(&sh4_uarts[minor], t); -} - -/* console_stop_remote_tx -- - * wrapper for stopping data flow from remote party. - * - * PARAMETERS: - * minor - minor device number - * - * RETURNS: - * result code - */ -static int -console_stop_remote_tx(int minor) -{ - if (minor < sizeof(sh4_uarts)/sizeof(sh4_uarts[0])) - return sh4uart_stop_remote_tx(&sh4_uarts[minor]); - else - return RTEMS_INVALID_NUMBER; -} - -/* console_start_remote_tx -- - * wrapper for resuming data flow from remote party. - * - * PARAMETERS: - * minor - minor device number - * - */ -static int -console_start_remote_tx(int minor) -{ - if (minor < sizeof(sh4_uarts)/sizeof(sh4_uarts[0])) - return sh4uart_start_remote_tx(&sh4_uarts[minor]); - else - return RTEMS_INVALID_NUMBER; -} - -/* console_first_open -- - * wrapper for UART controller initialization functions - * - * PARAMETERS: - * major - major device number - * minor - minor device number - * arg - libio device open argument - * - * RETURNS: - * error code - */ -static int -console_first_open(int major, int minor, void *arg) -{ - rtems_libio_open_close_args_t *args = arg; - rtems_status_code sc; - - sc = sh4uart_init(&sh4_uarts[minor], /* uart */ - args->iop->data1, /* tty */ - minor+1, /* channel */ - (console_mode == CONSOLE_MODE_INT)); - - if (sc == RTEMS_SUCCESSFUL) - sc = sh4uart_reset(&sh4_uarts[minor]); - - return sc; -} - -/* console_last_close -- - * wrapper for UART controller close function - * - * PARAMETERS: - * major - major device number - * minor - minor device number - * arg - libio device close argument - * - * RETURNS: - * error code - */ -static int -console_last_close(int major, int minor, void *arg) -{ - if (console_mode != CONSOLE_MODE_IPL) - /* working from gdb we should not disable port operations */ - return sh4uart_disable(&sh4_uarts[minor], - !(boot_mode == SH4_BOOT_MODE_IPL)); - else - return RTEMS_SUCCESSFUL; -} - -/* console_initialize -- - * This routine initializes the console IO drivers and register devices - * in RTEMS I/O system. - * - * PARAMETERS: - * major - major console device number - * minor - minor console device number (not used) - * arg - device initialize argument - * - * RETURNS: - * RTEMS error code (RTEMS_SUCCESSFUL if device initialized successfuly) - */ -rtems_device_driver -console_initialize(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - rtems_status_code status; - -#ifdef SH4_WITH_IPL - /* booting from flash we cannot have IPL console */ - if (boot_mode != SH4_BOOT_MODE_IPL && console_mode == CONSOLE_MODE_IPL) - console_mode = CONSOLE_MODE_INT; - - /* break out from gdb if neccessary */ - if (boot_mode == SH4_BOOT_MODE_IPL && console_mode != CONSOLE_MODE_IPL) - ipl_finish(); -#endif - - /* - * Set up TERMIOS - */ - if ((console_mode != CONSOLE_MODE_RAW) && - (console_mode != CONSOLE_MODE_IPL)) - rtems_termios_initialize (); - - /* - * Register the devices - */ - status = rtems_io_register_name ("/dev/console", major, 0); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - status = rtems_io_register_name ("/dev/aux", major, 1); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (status); - - if (console_mode == CONSOLE_MODE_RAW) - { - rtems_status_code sc; - sc = sh4uart_init(&sh4_uarts[0], /* uart */ - NULL, /* tty */ - 1, /* UART channel number */ - 0); /* Poll-mode */ - - if (sc == RTEMS_SUCCESSFUL) - sc = sh4uart_reset(&sh4_uarts[0]); - - sc = sh4uart_init(&sh4_uarts[1], /* uart */ - NULL, /* tty */ - 2, /* UART channel number */ - 0); /* Poll-mode */ - - if (sc == RTEMS_SUCCESSFUL) - sc = sh4uart_reset(&sh4_uarts[1]); - - return sc; - } - - return RTEMS_SUCCESSFUL; -} - -/* console_open -- - * Open console device driver. Pass appropriate termios callback - * functions to termios library. - * - * PARAMETERS: - * major - major device number for console devices - * minor - minor device number for console - * arg - device opening argument - * - * RETURNS: - * RTEMS error code - */ -rtems_device_driver -console_open(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - static const rtems_termios_callbacks intr_callbacks = { - console_first_open, /* firstOpen */ - console_last_close, /* lastClose */ - NULL, /* pollRead */ - console_interrupt_write, /* write */ - console_set_attributes, /* setAttributes */ - console_stop_remote_tx, /* stopRemoteTx */ - console_start_remote_tx, /* startRemoteTx */ - 1 /* outputUsesInterrupts */ - }; - static const rtems_termios_callbacks poll_callbacks = { - console_first_open, /* firstOpen */ - console_last_close, /* lastClose */ - console_poll_read, /* pollRead */ - console_poll_write, /* write */ - console_set_attributes, /* setAttributes */ - console_stop_remote_tx, /* stopRemoteTx */ - console_start_remote_tx, /* startRemoteTx */ - 0 /* outputUsesInterrupts */ - }; - - switch (console_mode) - { - case CONSOLE_MODE_RAW: - case CONSOLE_MODE_IPL: - return RTEMS_SUCCESSFUL; - - case CONSOLE_MODE_INT: - return rtems_termios_open(major, minor, arg, &intr_callbacks); - - case CONSOLE_MODE_POLL: - return rtems_termios_open(major, minor, arg, &poll_callbacks); - - default: - rtems_fatal_error_occurred(0xC07A1310); - } - - return RTEMS_INTERNAL_ERROR; -} - -/* console_close -- - * Close console device. - * - * PARAMETERS: - * major - major device number for console devices - * minor - minor device number for console - * arg - device close argument - * - * RETURNS: - * RTEMS error code - */ -rtems_device_driver -console_close(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - if ((console_mode != CONSOLE_MODE_RAW) && - (console_mode != CONSOLE_MODE_IPL)) - return rtems_termios_close (arg); - else - return RTEMS_SUCCESSFUL; -} - -/* console_read -- - * Read from the console device - * - * PARAMETERS: - * major - major device number for console devices - * minor - minor device number for console - * arg - device read argument - * - * RETURNS: - * RTEMS error code - */ -rtems_device_driver -console_read(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - if ((console_mode != CONSOLE_MODE_RAW) && - (console_mode != CONSOLE_MODE_IPL)) - { - return rtems_termios_read (arg); - } - else - { - rtems_libio_rw_args_t *argp = arg; - char *buf = argp->buffer; - int count = argp->count; - int n = 0; - int c; - while (n < count) - { - do { - c = (console_mode == CONSOLE_MODE_RAW) ? - sh4uart_poll_read(&sh4_uarts[minor]) : - ipl_console_poll_read(minor); - } while (c == -1); - if (c == '\r') - c = '\n'; - *(buf++) = c; - n++; - if (c == '\n') - break; - } - argp->bytes_moved = n; - return RTEMS_SUCCESSFUL; - } -} - -/* console_write -- - * Write to the console device - * - * PARAMETERS: - * major - major device number for console devices - * minor - minor device number for console - * arg - device write argument - * - * RETURNS: - * RTEMS error code - */ -rtems_device_driver -console_write(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - switch (console_mode) - { - case CONSOLE_MODE_POLL: - case CONSOLE_MODE_INT: - return rtems_termios_write (arg); - case CONSOLE_MODE_RAW: - { - rtems_libio_rw_args_t *argp = arg; - char cr = '\r'; - char *buf = argp->buffer; - int count = argp->count; - int i; - - for (i = 0; i < count; i++) - { - if (*buf == '\n') - sh4uart_poll_write(&sh4_uarts[minor], &cr, 1); - sh4uart_poll_write(&sh4_uarts[minor], buf, 1); - buf++; - } - argp->bytes_moved = count; - return RTEMS_SUCCESSFUL; - } -#ifdef SH4_WITH_IPL - case CONSOLE_MODE_IPL: - { - rtems_libio_rw_args_t *argp = arg; - char *buf = argp->buffer; - int count = argp->count; - ipl_console_poll_write(minor, buf, count); - argp->bytes_moved = count; - return RTEMS_SUCCESSFUL; - } -#endif - default: /* Unreachable */ - return RTEMS_NOT_DEFINED; - } -} - -/* console_control -- - * Handle console device I/O control (IOCTL) - * - * PARAMETERS: - * major - major device number for console devices - * minor - minor device number for console - * arg - device ioctl argument - * - * RETURNS: - * RTEMS error code - */ -rtems_device_driver -console_control(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - if ((console_mode != CONSOLE_MODE_RAW) && - (console_mode != CONSOLE_MODE_IPL)) - { - return rtems_termios_ioctl (arg); - } - else - { - return RTEMS_SUCCESSFUL; - } -} diff --git a/c/src/lib/libbsp/sh/gensh4/console/sh4uart.c b/c/src/lib/libbsp/sh/gensh4/console/sh4uart.c deleted file mode 100644 index 7acc1de337..0000000000 --- a/c/src/lib/libbsp/sh/gensh4/console/sh4uart.c +++ /dev/null @@ -1,910 +0,0 @@ -/* - * Generic UART Serial driver for SH-4 processors - * - * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russian Fed. - * Author: Alexandra Kossovsky - * - * COPYRIGHT (c) 1989-2000. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - */ - -#include -#include -#include -#include -#include "sh/sh4uart.h" - -#ifndef SH4_UART_INTERRUPT_LEVEL -#define SH4_UART_INTERRUPT_LEVEL 4 -#endif - -/* Forward function declarations */ -static rtems_isr -sh4uart1_interrupt_transmit(rtems_vector_number vec); -static rtems_isr -sh4uart1_interrupt_receive(rtems_vector_number vec); -static rtems_isr -sh4uart2_interrupt_transmit(rtems_vector_number vec); -static rtems_isr -sh4uart2_interrupt_receive(rtems_vector_number vec); - -/* - * sh4uart_init -- - * This function verifies the input parameters and perform initialization - * of the SH-4 on-chip UART descriptor structure. - * - * PARAMETERS: - * uart - pointer to the UART channel descriptor structure - * tty - pointer to termios structure - * chn - channel number (SH4_SCI/SH4_SCIF -- 1/2) - * int_driven - interrupt-driven (1) or polled (0) I/O mode - * - * RETURNS: - * RTEMS_SUCCESSFUL if all parameters are valid, or error code - */ -rtems_status_code -sh4uart_init(sh4uart *uart, void *tty, int chn, int int_driven) -{ - if (uart == NULL) - return RTEMS_INVALID_ADDRESS; - - if ((chn != SH4_SCI) && (chn != SH4_SCIF)) - return RTEMS_INVALID_NUMBER; - - uart->chn = chn; - uart->tty = tty; - uart->int_driven = int_driven; - -#if 0 - sh4uart_poll_write(uart, "init", 4); -#endif - return RTEMS_SUCCESSFUL; -} - -/* - * sh4uart_get_Pph -- - * Get current peripheral module clock. - * - * PARAMETERS: none; - * Cpu clock is get from CPU_CLOCK_RATE_HZ marco - * (defined in bspopts.h, included from bsp.h) - * - * RETURNS: - * peripheral module clock in Hz. - */ -static uint32_t -sh4uart_get_Pph(void) -{ - uint16_t frqcr = *(volatile uint16_t*)SH7750_FRQCR; - uint32_t Pph = CPU_CLOCK_RATE_HZ; - - switch (frqcr & SH7750_FRQCR_IFC) { - case SH7750_FRQCR_IFCDIV1: break; - case SH7750_FRQCR_IFCDIV2: Pph *= 2; break; - case SH7750_FRQCR_IFCDIV3: Pph *= 3; break; - case SH7750_FRQCR_IFCDIV4: Pph *= 4; break; - case SH7750_FRQCR_IFCDIV6: Pph *= 6; break; - case SH7750_FRQCR_IFCDIV8: Pph *= 8; break; - default: /* unreachable */ - break; - } - - switch (frqcr & SH7750_FRQCR_PFC) { - case SH7750_FRQCR_PFCDIV2: Pph /= 2; break; - case SH7750_FRQCR_PFCDIV3: Pph /= 3; break; - case SH7750_FRQCR_PFCDIV4: Pph /= 4; break; - case SH7750_FRQCR_PFCDIV6: Pph /= 6; break; - case SH7750_FRQCR_PFCDIV8: Pph /= 8; break; - default: /* unreachable */ - break; - } - - return Pph; -} - -/* - * sh4uart_set_baudrate -- - * Program the UART timer to specified baudrate - * - * PARAMETERS: - * uart - pointer to UART descriptor structure - * baud - termios baud rate (B50, B9600, etc...) - * - * ALGORITHM: - * see SH7750 Hardware Manual. - * - * RETURNS: - * none - */ -static void -sh4uart_set_baudrate(sh4uart *uart, speed_t baud) -{ - uint32_t rate; - int16_t div; - int n; - uint32_t Pph = sh4uart_get_Pph(); - - switch (baud) { - case B50: rate = 50; break; - case B75: rate = 75; break; - case B110: rate = 110; break; - case B134: rate = 134; break; - case B150: rate = 150; break; - case B200: rate = 200; break; - case B300: rate = 300; break; - case B600: rate = 600; break; - case B1200: rate = 1200; break; - case B2400: rate = 2400; break; - case B4800: rate = 4800; break; - case B9600: rate = 9600; break; - case B19200: rate = 19200; break; - case B38400: rate = 38400; break; - case B57600: rate = 57600; break; -#ifdef B115200 - case B115200: rate = 115200; break; -#endif -#ifdef B230400 - case B230400: rate = 230400; break; -#endif - default: rate = 9600; break; - } - - for (n = 0; n < 4; n++) { - div = Pph / (32 * (1 << (2 * n)) * rate) - 1; - if (div < 0x100) - break; - } - - /* Set default baudrate if specified baudrate is impossible */ - if (n >= 4) - sh4uart_set_baudrate(uart, B9600); - - if ( uart->chn == 1 ) { - volatile uint8_t *smr1 = (volatile uint8_t *)SH7750_SCSMR1; - *smr1 &= ~SH7750_SCSMR_CKS; - *smr1 |= n << SH7750_SCSMR_CKS_S; - } else { - volatile uint16_t *smr2 = (volatile uint16_t *)SH7750_SCSMR2; - *smr2 &= ~SH7750_SCSMR_CKS; - *smr2 |= n << SH7750_SCSMR_CKS_S; - } - - SCBRR(uart->chn) = div; - /* Wait at least 1 bit interwal */ - rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(1000 / rate)); -} - -/* - * sh4uart_reset -- - * This function perform the hardware initialization of SH-4 - * on-chip UART controller using parameters - * filled by the sh4uart_init function. - * - * PARAMETERS: - * uart - pointer to UART channel descriptor structure - * - * RETURNS: - * RTEMS_SUCCESSFUL if channel is initialized successfully, error - * code in other case - */ -rtems_status_code -sh4uart_reset(sh4uart *uart) -{ - register int chn; - register int int_driven; - rtems_status_code rc; - uint16_t tmp; - - if (uart == NULL) - return RTEMS_INVALID_ADDRESS; - - chn = uart->chn; - int_driven = uart->int_driven; - - if ( chn == 1 ) { - volatile uint8_t *scr1 = (volatile uint8_t *)SH7750_SCSCR1; - volatile uint8_t *smr1 = (volatile uint8_t *)SH7750_SCSMR1; - *scr1 = 0x0; /* Is set properly at the end of this function */ - *smr1 = 0x0; /* 8-bit, non-parity, 1 stop bit, pf/1 clock */ - } else { - volatile uint16_t *scr2 = (volatile uint16_t *)SH7750_SCSCR2; - volatile uint16_t *smr2 = (volatile uint16_t *)SH7750_SCSMR2; - *scr2 = 0x0; /* Is set properly at the end of this function */ - *smr2 = 0x0; /* 8-bit, non-parity, 1 stop bit, pf/1 clock */ - } - - if (chn == SH4_SCIF) - SCFCR2 = SH7750_SCFCR2_TFRST | SH7750_SCFCR2_RFRST | - SH7750_SCFCR2_RTRG_1 | SH7750_SCFCR2_TTRG_4; - - if (chn == SH4_SCI) - SCSPTR1 = int_driven ? 0x0 : SH7750_SCSPTR1_EIO; - else - SCSPTR2 = SH7750_SCSPTR2_RTSDT; - - if (int_driven) { - uint16_t ipr; - - if (chn == SH4_SCI) { - ipr = IPRB; - ipr &= ~SH7750_IPRB_SCI1; - ipr |= SH4_UART_INTERRUPT_LEVEL << SH7750_IPRB_SCI1_S; - IPRB = ipr; - - rc = rtems_interrupt_catch(sh4uart1_interrupt_transmit, - SH7750_EVT_TO_NUM(SH7750_EVT_SCI_TXI), - &uart->old_handler_transmit); - if (rc != RTEMS_SUCCESSFUL) - return rc; - - rc = rtems_interrupt_catch(sh4uart1_interrupt_receive, - SH7750_EVT_TO_NUM(SH7750_EVT_SCI_RXI), - &uart->old_handler_receive); - if (rc != RTEMS_SUCCESSFUL) - return rc; - } else { - ipr = IPRC; - ipr &= ~SH7750_IPRC_SCIF; - ipr |= SH4_UART_INTERRUPT_LEVEL << SH7750_IPRC_SCIF_S; - IPRC = ipr; - - rc = rtems_interrupt_catch(sh4uart2_interrupt_transmit, - SH7750_EVT_TO_NUM(SH7750_EVT_SCIF_TXI), - &uart->old_handler_transmit); - if (rc != RTEMS_SUCCESSFUL) - return rc; - rc = rtems_interrupt_catch(sh4uart2_interrupt_receive, - SH7750_EVT_TO_NUM(SH7750_EVT_SCIF_RXI), - &uart->old_handler_receive); - if (rc != RTEMS_SUCCESSFUL) - return rc; - } - uart->tx_buf = NULL; - uart->tx_ptr = uart->tx_buf_len = 0; - } - - sh4uart_set_baudrate(uart, B38400); /* debug defaults (unfortunately, - it is differ to termios default */ - - tmp = SH7750_SCSCR_TE | SH7750_SCSCR_RE | - (chn == SH4_SCI ? 0x0 : SH7750_SCSCR2_REIE) | - (int_driven ? (SH7750_SCSCR_RIE | SH7750_SCSCR_TIE) : 0x0); - - if ( chn == 1 ) { - volatile uint8_t *scr = (volatile uint8_t *)SH7750_SCSCR1; - *scr = tmp; - } else { - volatile uint16_t *scr = (volatile uint16_t *)SH7750_SCSCR2; - *scr = tmp; - } - - return RTEMS_SUCCESSFUL; -} - -/* - * sh4uart_disable -- - * This function disable the operations on SH-4 UART controller - * - * PARAMETERS: - * uart - pointer to UART channel descriptor structure - * disable_port - disable receive and transmit on the port - * - * RETURNS: - * RTEMS_SUCCESSFUL if UART closed successfuly, or error code in - * other case - */ -rtems_status_code -sh4uart_disable(sh4uart *uart, int disable_port) -{ - rtems_status_code rc; - - if (disable_port) { - if ( uart->chn == 1 ) { - volatile uint8_t *scr = (volatile uint8_t *)SH7750_SCSCR1; - *scr &= ~(SH7750_SCSCR_TE | SH7750_SCSCR_RE); - } else { - volatile uint16_t *scr = (volatile uint16_t *)SH7750_SCSCR2; - *scr &= ~(SH7750_SCSCR_TE | SH7750_SCSCR_RE); - } - } - - if (uart->int_driven) { - rc = rtems_interrupt_catch(uart->old_handler_transmit, - uart->chn == SH4_SCI ? SH7750_EVT_SCI_TXI : SH7750_EVT_SCIF_TXI, - NULL); - if (rc != RTEMS_SUCCESSFUL) - return rc; - rc = rtems_interrupt_catch(uart->old_handler_receive, - uart->chn == SH4_SCI ? SH7750_EVT_SCI_RXI : SH7750_EVT_SCIF_RXI, - NULL); - if (rc != RTEMS_SUCCESSFUL) - return rc; - } - - return RTEMS_SUCCESSFUL; -} - -/* - * sh4uart_set_attributes -- - * This function parse the termios attributes structure and perform - * the appropriate settings in hardware. - * - * PARAMETERS: - * uart - pointer to the UART descriptor structure - * t - pointer to termios parameters - * - * RETURNS: - * RTEMS_SUCCESSFUL - */ -rtems_status_code -sh4uart_set_attributes(sh4uart *uart, const struct termios *t) -{ - int level; - speed_t baud; - uint16_t smr; - - smr = (uint16_t)(*(uint8_t*)SH7750_SCSMR(uart->chn)); - - baud = cfgetospeed(t); - - /* Set flow control XXX*/ - if ((t->c_cflag & CRTSCTS) != 0) { - } - - /* Set character size -- only 7 or 8 bit */ - switch (t->c_cflag & CSIZE) { - case CS5: - case CS6: - case CS7: smr |= SH7750_SCSMR_CHR_7; break; - case CS8: smr &= ~SH7750_SCSMR_CHR_7; break; - } - - /* Set number of stop bits */ - if ((t->c_cflag & CSTOPB) != 0) - smr |= SH7750_SCSMR_STOP_2; - else - smr &= ~SH7750_SCSMR_STOP_2; - - /* Set parity mode */ - if ((t->c_cflag & PARENB) != 0) { - smr |= SH7750_SCSMR_PE; - if ((t->c_cflag & PARODD) != 0) - smr |= SH7750_SCSMR_PM_ODD; - else - smr &= ~SH7750_SCSMR_PM_ODD; - } else - smr &= ~SH7750_SCSMR_PE; - - rtems_interrupt_disable(level); - /* wait untill all data is transmitted */ - /* XXX JOEL says this is broken -- interrupts are OFF so NO ticks */ - rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(100)); - - if ( uart->chn == 1 ) { - volatile uint8_t *scrP = (volatile uint8_t *)SH7750_SCSCR1; - volatile uint8_t *smrP = (volatile uint8_t *)SH7750_SCSMR1; - - *scrP &= ~(SH7750_SCSCR_TE | SH7750_SCSCR_RE); /* disable operations */ - sh4uart_set_baudrate(uart, baud); - *smrP = (uint8_t)smr; - *scrP |= SH7750_SCSCR_TE | SH7750_SCSCR_RE; /* enable operations */ - } else { - volatile uint16_t *scrP = (volatile uint16_t *)SH7750_SCSCR2; - volatile uint16_t *smrP = (volatile uint16_t *)SH7750_SCSMR2; - - *scrP &= ~(SH7750_SCSCR_TE | SH7750_SCSCR_RE); /* disable operations */ - sh4uart_set_baudrate(uart, baud); - *smrP = (uint8_t)smr; - *scrP |= SH7750_SCSCR_TE | SH7750_SCSCR_RE; /* enable operations */ - } - - rtems_interrupt_enable(level); - - return RTEMS_SUCCESSFUL; -} - -/* - * sh4uart_handle_error -- - * Perfoms error (Overrun, Framing & Parity) handling - * - * PARAMETERS: - * uart - pointer to UART descriptor structure - * - * RETURNS: - * nothing - */ -static void -sh4uart_handle_error(sh4uart *uart) -{ - if (uart->chn == SH4_SCI) { - volatile uint8_t *scr = (volatile uint8_t *)SH7750_SCSCR1; - *scr &= ~(SH7750_SCSSR1_ORER | SH7750_SCSSR1_FER | SH7750_SCSSR1_PER); - } else { - volatile uint16_t *scr = (volatile uint16_t *)SH7750_SCSCR2; - *scr &= ~(SH7750_SCSSR2_ER | SH7750_SCSSR2_BRK | SH7750_SCSSR2_FER); - *scr &= ~(SH7750_SCLSR2_ORER); - } -} - -/* - * sh4uart_poll_read -- - * This function tried to read character from SH-4 UART and perform - * error handling. When parity or framing error occured, return - * value dependent on termios input mode flags: - * - received character, if IGNPAR == 1 - * - 0, if IGNPAR == 0 and PARMRK == 0 - * - 0xff and 0x00 on next poll_read invocation, if IGNPAR == 0 and - * PARMRK == 1 - * - * PARAMETERS: - * uart - pointer to UART descriptor structure - * - * RETURNS: - * code of received character or -1 if no characters received. - */ -int -sh4uart_poll_read(sh4uart *uart) -{ - int chn = uart->chn; - int parity_error = 0; - int break_occured = 0; - int ch; - - if (uart->parerr_mark_flag == true) { - uart->parerr_mark_flag = false; - return 0; - } - - if (chn == SH4_SCI) { - if ((SCSSR1 & (SH7750_SCSSR1_PER | SH7750_SCSSR1_FER | - SH7750_SCSSR1_ORER)) != 0) { - if (SCSSR1 & (SH7750_SCSSR1_PER | SH7750_SCSSR1_FER)) - parity_error = 1; - sh4uart_handle_error(uart); - } - if ((SCSSR1 & SH7750_SCSSR1_RDRF) == 0) - return -1; - } else { - if ((SCSSR2 & (SH7750_SCSSR2_ER | SH7750_SCSSR2_DR | - SH7750_SCSSR2_BRK)) != 0 || - (SCLSR2 & SH7750_SCLSR2_ORER) != 0) { - if (SCSSR2 & (SH7750_SCSSR1_PER | SH7750_SCSSR1_FER)) - parity_error = 1; - if (SCSSR2 & SH7750_SCSSR2_BRK) - break_occured = 1; - sh4uart_handle_error(uart); - } - if ((SCSSR2 & SH7750_SCSSR2_RDF) == 0) - return -1; - } - - if (parity_error && !(uart->c_iflag & IGNPAR)) { - if (uart->c_iflag & PARMRK) { - uart->parerr_mark_flag = true; - return 0xff; - } else - return 0; - } - - if (break_occured && !(uart->c_iflag & BRKINT)) { - if (uart->c_iflag & IGNBRK) - return 0; - else - return 0; /* XXX -- SIGINT */ - } - - ch = SCRDR(chn); - - if (uart->chn == SH4_SCI) { - volatile uint8_t *scr = (volatile uint8_t *)SH7750_SCSCR1; - *scr &= ~SH7750_SCSSR1_RDRF; - } else { - volatile uint16_t *scr = (volatile uint16_t *)SH7750_SCSCR2; - *scr &= ~SH7750_SCSSR2_RDF; - } - - return ch; -} - -/* - * sh4uart_poll_write -- - * This function transmit buffer byte-by-byte in polling mode. - * - * PARAMETERS: - * uart - pointer to the UART descriptor structure - * buf - pointer to transmit buffer - * len - transmit buffer length - * - * RETURNS: - * 0 - */ -int -sh4uart_poll_write(sh4uart *uart, const char *buf, int len) -{ - volatile uint8_t *ssr1 = (volatile uint8_t *)SH7750_SCSSR1; - volatile uint16_t *ssr2 = (volatile uint16_t *)SH7750_SCSSR2; - - while (len) { - if (uart->chn == SH4_SCI) { - while ((SCSSR1 & SH7750_SCSSR1_TDRE) != 0) { - SCTDR1 = *buf++; - len--; - *ssr1 &= ~SH7750_SCSSR1_TDRE; - } - } else { - while ((SCSSR2 & SH7750_SCSSR2_TDFE) != 0) { - int i; - for (i = 0; - i < 16 - TRANSMIT_TRIGGER_VALUE(SCFCR2 & - SH7750_SCFCR2_TTRG); - i++) { - SCTDR2 = *buf++; - len--; - } - while ((SCSSR2 & SH7750_SCSSR2_TDFE) == 0 || - (SCSSR2 & SH7750_SCSSR2_TEND) == 0); - *ssr2 &= ~(SH7750_SCSSR1_TDRE | SH7750_SCSSR2_TEND); - } - } - } - return 0; -} - -/********************************** - * Functions to handle interrupts * - **********************************/ -/* sh4uart1_interrupt_receive -- - * UART interrupt handler routine -- SCI - * Receiving data - * - * PARAMETERS: - * vec - interrupt vector number - * - * RETURNS: - * none - */ -static rtems_isr -sh4uart1_interrupt_receive(rtems_vector_number vec) -{ - register int bp = 0; - char buf[32]; - volatile uint8_t *ssr1 = (volatile uint8_t *)SH7750_SCSSR1; - - - /* Find UART descriptor from vector number */ - sh4uart *uart = &sh4_uarts[0]; - - while (1) { - if ((bp < sizeof(buf) - 1) && ((SCSSR1 & SH7750_SCSSR1_RDRF) != 0)) { - /* Receive character and handle frame/parity errors */ - if ((SCSSR1 & (SH7750_SCSSR1_PER | SH7750_SCSSR1_FER | - SH7750_SCSSR1_ORER)) != 0) { - if (SCSSR1 & (SH7750_SCSSR1_PER | SH7750_SCSSR1_FER)) { - if (!(uart->c_iflag & IGNPAR)) { - if (uart->c_iflag & PARMRK) { - buf[bp++] = 0xff; - buf[bp++] = 0x00; - } else - buf[bp++] = 0x00; - } else - buf[bp++] = SCRDR1; - } - sh4uart_handle_error(uart); - } else - buf[bp++] = SCRDR1; - *ssr1 &= ~SH7750_SCSSR1_RDRF; - } else { - if (bp != 0) - rtems_termios_enqueue_raw_characters(uart->tty, buf, bp); - break; - } - } -} - -/* sh4uart2_interrupt_receive -- - * UART interrupt handler routine -- SCIF - * Receiving data - * - * PARAMETERS: - * vec - interrupt vector number - * - * RETURNS: - * none - */ -static rtems_isr -sh4uart2_interrupt_receive(rtems_vector_number vec) -{ - register int bp = 0; - char buf[32]; - volatile uint16_t *ssr2 = (volatile uint16_t *)SH7750_SCSSR2; - - - /* Find UART descriptor from vector number */ - sh4uart *uart = &sh4_uarts[1]; - - while (1) { - if ((bp < sizeof(buf) - 1) && ((SCSSR2 & SH7750_SCSSR2_RDF) != 0)) { - if ((SCSSR2 & (SH7750_SCSSR2_ER | SH7750_SCSSR2_DR | - SH7750_SCSSR2_BRK)) != 0 || - (SH7750_SCLSR2 & SH7750_SCLSR2_ORER) != 0) { - if (SCSSR2 & SH7750_SCSSR2_ER) { - if (!(uart->c_iflag & IGNPAR)) { - if (uart->c_iflag & PARMRK) { - buf[bp++] = 0xff; - buf[bp++] = 0x00; - } else - buf[bp++] = 0x00; - } else - buf[bp++] = SCRDR1; - } - - if (SCSSR2 & SH7750_SCSSR2_BRK) { - if (uart->c_iflag & IGNBRK) - buf[bp++] = 0x00; - else - buf[bp++] = 0x00; /* XXX -- SIGINT */ - } - - sh4uart_handle_error(uart); - } else - buf[bp++] = SCRDR1; - *ssr2 &= ~SH7750_SCSSR2_RDF; - } else { - if (bp != 0) - rtems_termios_enqueue_raw_characters(uart->tty, buf, bp); - break; - } - } -} - - -/* sh4uart1_interrupt_transmit -- - * UART interrupt handler routine -- SCI - * It continues transmit data when old part of data is transmitted - * - * PARAMETERS: - * vec - interrupt vector number - * - * RETURNS: - * none - */ -static rtems_isr -sh4uart1_interrupt_transmit(rtems_vector_number vec) -{ - volatile uint8_t *scr1 = (volatile uint8_t *)SH7750_SCSCR1; - volatile uint8_t *ssr1 = (volatile uint8_t *)SH7750_SCSSR1; - - /* Find UART descriptor from vector number */ - sh4uart *uart = &sh4_uarts[0]; - - if (uart->tx_buf != NULL && uart->tx_ptr < uart->tx_buf_len) { - while ((SCSSR1 & SH7750_SCSSR1_TDRE) != 0 && - uart->tx_ptr < uart->tx_buf_len) { - SCTDR1 = uart->tx_buf[uart->tx_ptr++]; - *ssr1 &= ~SH7750_SCSSR1_TDRE; - } - } else { - register int dequeue = uart->tx_buf_len; - - uart->tx_buf = NULL; - uart->tx_ptr = uart->tx_buf_len = 0; - - /* Disable interrupts while we do not have any data to transmit */ - *scr1 &= ~SH7750_SCSCR_TIE; - - rtems_termios_dequeue_characters(uart->tty, dequeue); - } -} - -/* sh4uart2_interrupt_transmit -- - * UART interrupt handler routine -- SCI - * It continues transmit data when old part of data is transmitted - * - * PARAMETERS: - * vec - interrupt vector number - * - * RETURNS: - * none - */ -static rtems_isr -sh4uart2_interrupt_transmit(rtems_vector_number vec) -{ - volatile uint8_t *ssr1 = (volatile uint8_t *)SH7750_SCSSR1; - volatile uint16_t *scr2 = (volatile uint16_t *)SH7750_SCSCR2; - - /* Find UART descriptor from vector number */ - sh4uart *uart = &sh4_uarts[1]; - - if (uart->tx_buf != NULL && uart->tx_ptr < uart->tx_buf_len) { - while ((SCSSR2 & SH7750_SCSSR2_TDFE) != 0) { - int i; - for (i = 0; - i < 16 - TRANSMIT_TRIGGER_VALUE(SCFCR2 & SH7750_SCFCR2_TTRG); - i++) - SCTDR2 = uart->tx_buf[uart->tx_ptr++]; - while ((SCSSR1 & SH7750_SCSSR1_TDRE) == 0 || - (SCSSR1 & SH7750_SCSSR1_TEND) == 0); - *ssr1 &= ~(SH7750_SCSSR1_TDRE | SH7750_SCSSR2_TEND); - } - } else { - register int dequeue = uart->tx_buf_len; - - uart->tx_buf = NULL; - uart->tx_ptr = uart->tx_buf_len = 0; - - /* Disable interrupts while we do not have any data to transmit */ - *scr2 &= ~SH7750_SCSCR_TIE; - - rtems_termios_dequeue_characters(uart->tty, dequeue); - } -} - -/* sh4uart_interrupt_write -- - * This function initiate transmitting of the buffer in interrupt mode. - * - * PARAMETERS: - * uart - pointer to the UART descriptor structure - * buf - pointer to transmit buffer - * len - transmit buffer length - * - * RETURNS: - * 0 - */ -rtems_status_code -sh4uart_interrupt_write(sh4uart *uart, const char *buf, int len) -{ - if (len > 0) { - volatile uint8_t *scr1 = (volatile uint8_t *)SH7750_SCSCR1; - volatile uint16_t *scr2 = (volatile uint16_t *)SH7750_SCSCR2; - - while ((SCSSR1 & SH7750_SCSSR1_TEND) == 0); - - uart->tx_buf = buf; - uart->tx_buf_len = len; - uart->tx_ptr = 0; - - if (uart->chn == SH4_SCI) - *scr1 |= SH7750_SCSCR_TIE; - else - *scr2 |= SH7750_SCSCR_TIE; - } - - return RTEMS_SUCCESSFUL; -} - -/* sh4uart_stop_remote_tx -- - * This function stop data flow from remote device. - * - * PARAMETERS: - * uart - pointer to the UART descriptor structure - * - * RETURNS: - * RTEMS_SUCCESSFUL - */ -rtems_status_code -sh4uart_stop_remote_tx(sh4uart *uart) -{ - if ( uart->chn == 1 ) { - volatile uint8_t *scr = (volatile uint8_t *)SH7750_SCSCR1; - *scr &= ~(SH7750_SCSCR_RIE | SH7750_SCSCR_RE); - } else { - volatile uint16_t *scr = (volatile uint16_t *)SH7750_SCSCR2; - *scr &= ~(SH7750_SCSCR_RIE | SH7750_SCSCR_RE); - } - - return RTEMS_SUCCESSFUL; -} - -/* sh4uart_start_remote_tx -- - * This function resume data flow from remote device. - * - * PARAMETERS: - * uart - pointer to the UART descriptor structure - * - * RETURNS: - * RTEMS_SUCCESSFUL - */ -rtems_status_code -sh4uart_start_remote_tx(sh4uart *uart) -{ - if ( uart->chn == 1 ) { - volatile uint8_t *scr = (volatile uint8_t *)SH7750_SCSCR1; - *scr |= SH7750_SCSCR_RIE | SH7750_SCSCR_RE; - } else { - volatile uint16_t *scr = (volatile uint16_t *)SH7750_SCSCR2; - *scr |= SH7750_SCSCR_RIE | SH7750_SCSCR_RE; - } - - return RTEMS_SUCCESSFUL; -} - -#ifdef SH4_WITH_IPL -/********************************* - * Functions for SH-IPL gdb stub * - *********************************/ - -/* - * ipl_finish -- - * Says gdb that program finished to get out from it. - */ -extern void ipl_finish(void); -__asm__ ( -" .global _ipl_finish\n" -"_ipl_finish:\n" -" mov.l __ipl_finish_value, r0\n" -" trapa #0x3f\n" -" nop\n" -" rts\n" -" nop\n" -" .align 4\n" -"__ipl_finish_value:\n" -" .long 255" -); - -extern int ipl_serial_input(int poll_count); -__asm__ ( -" .global _ipl_serial_input\n" -"_ipl_serial_input:\n" -" mov #1,r0\n" -" trapa #0x3f\n" -" nop\n" -" rts\n" -" nop\n"); - -extern void ipl_serial_output(const char *buf, int len); -__asm__ ( -" .global _ipl_serial_output\n" -"_ipl_serial_output:\n" -" mov #0,r0\n" -" trapa #0x3f\n" -" nop\n" -" rts\n" -" nop\n"); - -/* ipl_console_poll_read -- - * poll read operation for simulator console through ipl mechanism. - * - * PARAMETERS: - * minor - minor device number - * - * RETURNS: - * character code red from UART, or -1 if there is no characters - * available - */ -int -ipl_console_poll_read(int minor) -{ - unsigned char buf; - buf = ipl_serial_input(0x100000); - return buf; -} - -/* ipl_console_poll_write -- - * wrapper for polling mode write function - * - * PARAMETERS: - * minor - minor device number - * buf - output buffer - * len - output buffer length - * - * RETURNS: - * result code (0) - */ -int -ipl_console_poll_write(int minor, const char *buf, int len) -{ - int c; - while (len > 0) { - c = (len < 64 ? len : 64); - ipl_serial_output(buf, c); - len -= c; - buf += c; - } - return 0; -} -#endif diff --git a/c/src/lib/libbsp/sh/shsim/Makefile.am b/c/src/lib/libbsp/sh/shsim/Makefile.am index 4d399083a1..edd911aaad 100644 --- a/c/src/lib/libbsp/sh/shsim/Makefile.am +++ b/c/src/lib/libbsp/sh/shsim/Makefile.am @@ -32,10 +32,10 @@ librtemsbsp_a_SOURCES += startup/ispshgdb.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/clock/clock-simidle.c # console -librtemsbsp_a_SOURCES += ../../shared/console-polled.c -librtemsbsp_a_SOURCES += console/console-io.c -librtemsbsp_a_SOURCES += console/console-support.S -librtemsbsp_a_SOURCES += console/console-debugio.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-polled.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sh/shsim/console/console-io.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sh/shsim/console/console-support.S +librtemsbsp_a_SOURCES += ../../../../../../bsps/sh/shsim/console/console-debugio.c # timer librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/btimer/btimer-stub.c diff --git a/c/src/lib/libbsp/sh/shsim/console/console-debugio.c b/c/src/lib/libbsp/sh/shsim/console/console-debugio.c deleted file mode 100644 index 0a81dbe45b..0000000000 --- a/c/src/lib/libbsp/sh/shsim/console/console-debugio.c +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file - * @brief Stub printk() support - */ - -/* - * COPYRIGHT (c) 1989-2014. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -/* - * To support printk - */ - -#include -#include - -void console_outbyte_polled( - int port, - char ch -); - -static void BSP_output_char_f(char c) -{ - console_outbyte_polled( 0, c ); -} - -BSP_output_char_function_type BSP_output_char = BSP_output_char_f; -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/sh/shsim/console/console-io.c b/c/src/lib/libbsp/sh/shsim/console/console-io.c deleted file mode 100644 index 71b089fdf7..0000000000 --- a/c/src/lib/libbsp/sh/shsim/console/console-io.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file contains the hardware specific portions of the TTY driver - * for the simulators stdin/out. - */ - -/* - * COPYRIGHT (c) 1989-2011. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include - -#include - -/* - * console_initialize_hardware - * - * This routine initializes the console hardware. - */ -void console_initialize_hardware(void) -{ -} - -/* - * console_outbyte_polled - * - * This routine transmits a character using polling. - */ -void console_outbyte_polled( - int port, - char ch -) -{ - __trap34 (SYS_write, 1, &ch, 1); -} - -/* - * console_inbyte_nonblocking - * - * This routine polls for a character. - */ -int console_inbyte_nonblocking( - int port -) -{ - unsigned char c; - - return __trap34 (SYS_read, 0, &c, 1); -} diff --git a/c/src/lib/libbsp/sh/shsim/console/console-support.S b/c/src/lib/libbsp/sh/shsim/console/console-support.S deleted file mode 100644 index 63f72f794b..0000000000 --- a/c/src/lib/libbsp/sh/shsim/console/console-support.S +++ /dev/null @@ -1,18 +0,0 @@ -/* - * newlib-1.8.2/newlib/libc/sys/sh/trap.S - */ - .text - .global ___trap34 -___trap34: - trapa #34 - tst r1,r1 ! r1 is errno - bt ret - mov.l perrno,r2 - mov.l r1,@r2 -ret: - rts - nop - - .align 2 -perrno: - .long _errno diff --git a/c/src/lib/libbsp/shared/console-output-char.c b/c/src/lib/libbsp/shared/console-output-char.c deleted file mode 100644 index fec204663a..0000000000 --- a/c/src/lib/libbsp/shared/console-output-char.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include - -static void output_char(char c) -{ - int minor = (int) Console_Port_Minor; - const console_tbl *ct = Console_Port_Tbl != NULL ? - Console_Port_Tbl[minor] : &Console_Configuration_Ports[minor]; - const console_fns *cf = ct->pDeviceFns; - - (*cf->deviceWritePolled)(minor, c); -} - -static void output_char_init(char c) -{ - if (Console_Port_Tbl == NULL) { - int minor = (int) Console_Port_Minor; - const console_fns *cf = Console_Configuration_Ports[minor].pDeviceFns; - - (*cf->deviceInitialize)(minor); - } - - BSP_output_char = output_char; - output_char(c); -} - -BSP_output_char_function_type BSP_output_char = output_char_init; - -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/shared/console-polled.c b/c/src/lib/libbsp/shared/console-polled.c deleted file mode 100644 index 26c9817bdb..0000000000 --- a/c/src/lib/libbsp/shared/console-polled.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * This file contains the hardware independent portion of a polled - * console device driver. If a BSP chooses to use this, then it - * only has to provide a few board dependent routines. - */ - -/* - * COPYRIGHT (c) 1989-1997. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include - -#include -#include -#include - -/* - * Prototypes - */ -ssize_t console_write_support(int, const char *, size_t); - -/* - * Console Termios Support Entry Points - * - */ -ssize_t console_write_support ( - int minor, - const char *bufarg, - size_t len -) -{ - int nwrite = 0; - const char *buf = bufarg; - - while (nwrite < len) { - console_outbyte_polled( minor, *buf++ ); - nwrite++; - } - return nwrite; -} - -/* - * Console Device Driver Entry Points - * - */ - -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - - /* - * Ensure Termios is initialized - */ - rtems_termios_initialize(); - - /* - * Make sure the hardware is initialized. - */ - console_initialize_hardware(); - - /* - * Register Device Names - */ - status = rtems_io_register_name( "/dev/console", major, 0 ); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(BSP_FATAL_CONSOLE_REGISTER_DEV_2); - - return RTEMS_SUCCESSFUL; -} - -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - static const rtems_termios_callbacks pollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - console_inbyte_nonblocking, /* pollRead */ - console_write_support, /* write */ - NULL, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - 0 /* outputUsesInterrupts */ - }; - - assert( minor == 0 ); - if ( minor != 0 ) - return RTEMS_INVALID_NUMBER; - - rtems_termios_open( major, minor, arg, &pollCallbacks ); - - return RTEMS_SUCCESSFUL; -} - -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_close( arg ); -} - -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_read( arg ); -} - -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_write( arg ); -} - -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_ioctl( arg ); -} diff --git a/c/src/lib/libbsp/shared/console-termios-init.c b/c/src/lib/libbsp/shared/console-termios-init.c deleted file mode 100644 index a01a75abf2..0000000000 --- a/c/src/lib/libbsp/shared/console-termios-init.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2014, 2016 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include - -#include - -#include - -bool console_device_probe_default(rtems_termios_device_context *context) -{ - (void) context; - - return true; -} - -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - bool console_device_done = false; - - rtems_termios_initialize(); - - for ( minor = 0; minor < console_device_count; ++minor ) { - const console_device *ctx = &console_device_table[ minor ]; - rtems_status_code sc; - - if ( ( *ctx->probe )( ctx->context ) ) { - sc = rtems_termios_device_install( - ctx->device_file, - ctx->handler, - ctx->flow, - ctx->context - ); - if ( sc != RTEMS_SUCCESSFUL ) { - bsp_fatal( BSP_FATAL_CONSOLE_INSTALL_0 ); - } - - if ( !console_device_done ) { - console_device_done = true; - - if ( link( ctx->device_file, CONSOLE_DEVICE_NAME ) != 0 ) { - bsp_fatal( BSP_FATAL_CONSOLE_INSTALL_1 ); - } - } - } - } - - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/lib/libbsp/shared/console-termios.c b/c/src/lib/libbsp/shared/console-termios.c deleted file mode 100644 index 1e755d91c9..0000000000 --- a/c/src/lib/libbsp/shared/console-termios.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2014, 2016 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include - -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - (void) major; - (void) minor; - (void) arg; - - return RTEMS_INTERNAL_ERROR; -} - -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - (void) major; - (void) minor; - (void) arg; - - return RTEMS_INTERNAL_ERROR; -} - -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - (void) major; - (void) minor; - (void) arg; - - return RTEMS_INTERNAL_ERROR; -} - -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - (void) major; - (void) minor; - (void) arg; - - return RTEMS_INTERNAL_ERROR; -} - -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - (void) major; - (void) minor; - (void) arg; - - return RTEMS_INTERNAL_ERROR; -} diff --git a/c/src/lib/libbsp/shared/dummy_printk_support.c b/c/src/lib/libbsp/shared/dummy_printk_support.c deleted file mode 100644 index 8273edb83a..0000000000 --- a/c/src/lib/libbsp/shared/dummy_printk_support.c +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @file - * @brief Stub printk() support - * - * This file contains a stub for the required printk() support. - * It is NOT functional!!! - */ - -/* - * COPYRIGHT (c) 1989-2014. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -/* - * To support printk - */ - -#include -#include - -static void BSP_output_char_f(char c) -{ - /* the character just needs to disappear */ -} - -BSP_output_char_function_type BSP_output_char = BSP_output_char_f; -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/shared/get-serial-mouse-ps2.c b/c/src/lib/libbsp/shared/get-serial-mouse-ps2.c deleted file mode 100644 index dc30deecbf..0000000000 --- a/c/src/lib/libbsp/shared/get-serial-mouse-ps2.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -bool bsp_get_serial_mouse_device( - const char **name, - const char **type -) -{ - *name = SERIAL_MOUSE_DEVICE_PS2; - *type = "ps2"; - - return true; -} diff --git a/c/src/lib/libbsp/sparc/erc32/Makefile.am b/c/src/lib/libbsp/sparc/erc32/Makefile.am index 89c7cd642b..489772f892 100644 --- a/c/src/lib/libbsp/sparc/erc32/Makefile.am +++ b/c/src/lib/libbsp/sparc/erc32/Makefile.am @@ -44,9 +44,9 @@ librtemsbsp_a_SOURCES += ../shared/gnatcommon.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c -librtemsbsp_a_SOURCES += console/erc32_console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/erc32/console/erc32_console.c # debugio -librtemsbsp_a_SOURCES += console/debugputs.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/erc32/console/debugputs.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/sparc/erc32/clock/ckinit.c # timer diff --git a/c/src/lib/libbsp/sparc/erc32/console/debugputs.c b/c/src/lib/libbsp/sparc/erc32/console/debugputs.c deleted file mode 100644 index 57c00048a5..0000000000 --- a/c/src/lib/libbsp/sparc/erc32/console/debugputs.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include - -/* - * console_outbyte_polled - * - * This routine transmits a character using polling. - */ -void console_outbyte_polled( - int port, - unsigned char ch -) -{ - if ( port == 0 ) { - while ( (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEA) == 0 ); - ERC32_MEC.UART_Channel_A = (unsigned int) ch; - return; - } - - while ( (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEB) == 0 ); - ERC32_MEC.UART_Channel_B = (unsigned int) ch; -} - -/* - * console_inbyte_nonblocking - * - * This routine polls for a character. - */ -int console_inbyte_nonblocking( int port ) -{ - int UStat; - - UStat = ERC32_MEC.UART_Status; - - switch (port) { - - case 0: - if (UStat & ERC32_MEC_UART_STATUS_ERRA) { - ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRA; - ERC32_MEC.Control = ERC32_MEC.Control; - } - - if ((UStat & ERC32_MEC_UART_STATUS_DRA) == 0) - return -1; - return (int) ERC32_MEC.UART_Channel_A; - - case 1: - if (UStat & ERC32_MEC_UART_STATUS_ERRB) { - ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRB; - ERC32_MEC.Control = ERC32_MEC.Control; - } - - if ((UStat & ERC32_MEC_UART_STATUS_DRB) == 0) - return -1; - return (int) ERC32_MEC.UART_Channel_B; - - default: - rtems_fatal_error_occurred( 'D' << 8 | (port & 0xffffff) ); - } - - return -1; -} - -/* - * To support printk - */ - -#include - -static void BSP_output_char_f(char c) { console_outbyte_polled( 0, c ); } - -BSP_output_char_function_type BSP_output_char = BSP_output_char_f; -BSP_polling_getchar_function_type BSP_poll_char = NULL; diff --git a/c/src/lib/libbsp/sparc/erc32/console/erc32_console.c b/c/src/lib/libbsp/sparc/erc32/console/erc32_console.c deleted file mode 100644 index 81dfe026fb..0000000000 --- a/c/src/lib/libbsp/sparc/erc32/console/erc32_console.c +++ /dev/null @@ -1,337 +0,0 @@ -/** - * @file - * - * @brief Driver for serial ports on the ERC32. - */ - -/* - * Copyright (c) 2010 Tiemen Schut - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include - -#define CONSOLE_BUF_SIZE (16) - -#define CONSOLE_UART_A_TRAP ERC32_TRAP_TYPE(ERC32_INTERRUPT_UART_A_RX_TX) -#define CONSOLE_UART_B_TRAP ERC32_TRAP_TYPE(ERC32_INTERRUPT_UART_B_RX_TX) - -static uint8_t erc32_console_get_register(uintptr_t addr, uint8_t i) -{ - volatile uint32_t *reg = (volatile uint32_t *)addr; - return (uint8_t) reg [i]; -} - -static void erc32_console_set_register(uintptr_t addr, uint8_t i, uint8_t val) -{ - volatile uint32_t *reg = (volatile uint32_t *)addr; - reg [i] = val; -} - -static int erc32_console_first_open(int major, int minor, void *arg); - -#if (CONSOLE_USE_INTERRUPTS) - static ssize_t erc32_console_write_support_int( - int minor, const char *buf, size_t len); -#else - int console_inbyte_nonblocking( int port ); - static ssize_t erc32_console_write_support_polled( - int minor, const char *buf, size_t len); -#endif -static void erc32_console_initialize(int minor); - -#if (CONSOLE_USE_INTERRUPTS) - const console_fns erc32_fns = { - libchip_serial_default_probe, /* deviceProbe */ - erc32_console_first_open, /* deviceFirstOpen */ - NULL, /* deviceLastClose */ - NULL, /* deviceRead */ - erc32_console_write_support_int, /* deviceWrite */ - erc32_console_initialize, /* deviceInitialize */ - NULL, /* deviceWritePolled */ - NULL, /* deviceSetAttributes */ - TERMIOS_IRQ_DRIVEN /* deviceOutputUsesInterrupts */ - }; -#else - const console_fns erc32_fns = { - libchip_serial_default_probe, /* deviceProbe */ - erc32_console_first_open, /* deviceFirstOpen */ - NULL, /* deviceLastClose */ - console_inbyte_nonblocking, /* deviceRead */ - erc32_console_write_support_polled, /* deviceWrite */ - erc32_console_initialize, /* deviceInitialize */ - NULL, /* deviceWritePolled */ - NULL, /* deviceSetAttributes */ - TERMIOS_POLLED /* deviceOutputUsesInterrupts */ - }; -#endif - -console_tbl Console_Configuration_Ports [] = { - { - .sDeviceName = "/dev/console_a", - .deviceType = SERIAL_CUSTOM, - .pDeviceFns = &erc32_fns, - .deviceProbe = NULL, - .pDeviceFlow = NULL, - .ulMargin = 16, - .ulHysteresis = 8, - .pDeviceParams = (void *) -1, /* could be baud rate */ - .ulCtrlPort1 = 0, - .ulCtrlPort2 = 0, - .ulDataPort = 0, - .getRegister = erc32_console_get_register, - .setRegister = erc32_console_set_register, - .getData = NULL, - .setData = NULL, - .ulClock = 16, - .ulIntVector = ERC32_INTERRUPT_UART_A_RX_TX - }, - { - .sDeviceName = "/dev/console_b", - .deviceType = SERIAL_CUSTOM, - .pDeviceFns = &erc32_fns, - .deviceProbe = NULL, - .pDeviceFlow = NULL, - .ulMargin = 16, - .ulHysteresis = 8, - .pDeviceParams = (void *) -1, /* could be baud rate */ - .ulCtrlPort1 = 0, - .ulCtrlPort2 = 0, - .ulDataPort = 0, - .getRegister = erc32_console_get_register, - .setRegister = erc32_console_set_register, - .getData = NULL, - .setData = NULL, - .ulClock = 16, - .ulIntVector = ERC32_INTERRUPT_UART_B_RX_TX - }, -}; - -/* always exactly two uarts for erc32 */ -#define ERC32_UART_COUNT (2) - -unsigned long Console_Configuration_Count = ERC32_UART_COUNT; - -static int erc32_console_first_open(int major, int minor, void *arg) -{ - /* Check minor number */ - if (minor < 0 || minor > 1) { - return -1; - } - - rtems_libio_open_close_args_t *oca = arg; - struct rtems_termios_tty *tty = oca->iop->data1; - console_tbl *ct = Console_Port_Tbl [minor]; - console_data *cd = &Console_Port_Data [minor]; - - cd->termios_data = tty; - rtems_termios_set_initial_baud(tty, (int32_t)ct->pDeviceParams); - - return 0; -} - -#if (CONSOLE_USE_INTERRUPTS) -static ssize_t erc32_console_write_support_int( - int minor, const char *buf, size_t len) -{ - if (len > 0) { - console_data *cd = &Console_Port_Data[minor]; - int k = 0; - - if (minor == 0) { /* uart a */ - for (k = 0; - k < len && (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEA); - k ++) { - ERC32_MEC.UART_Channel_A = (unsigned char)buf[k]; - } - ERC32_Force_interrupt(ERC32_INTERRUPT_UART_A_RX_TX); - } else { /* uart b */ - for (k = 0; - k < len && (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEB); - k ++) { - ERC32_MEC.UART_Channel_B = (unsigned char)buf[k]; - } - ERC32_Force_interrupt(ERC32_INTERRUPT_UART_B_RX_TX); - } - - cd->pDeviceContext = (void *)k; - cd->bActive = true; - } - - return 0; -} - -static void erc32_console_isr_error( - rtems_vector_number vector -) -{ - int UStat; - - UStat = ERC32_MEC.UART_Status; - - if (UStat & ERC32_MEC_UART_STATUS_ERRA) { - ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRA; - ERC32_MEC.Control = ERC32_MEC.Control; - } - - if (UStat & ERC32_MEC_UART_STATUS_ERRB) { - ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRB; - ERC32_MEC.Control = ERC32_MEC.Control; - } - - ERC32_Clear_interrupt( ERC32_INTERRUPT_UART_ERROR ); -} - -static void erc32_console_isr_a( - rtems_vector_number vector -) -{ - console_data *cd = &Console_Port_Data[0]; - - /* check for error */ - if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_ERRA) { - ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRA; - ERC32_MEC.Control = ERC32_MEC.Control; - } - - do { - int chars_to_dequeue = (int)cd->pDeviceContext; - int rv = 0; - int i = 0; - char buf[CONSOLE_BUF_SIZE]; - - /* enqueue received chars */ - while (i < CONSOLE_BUF_SIZE) { - if (!(ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_DRA)) - break; - buf[i] = ERC32_MEC.UART_Channel_A; - ++i; - } - if ( i ) - rtems_termios_enqueue_raw_characters(cd->termios_data, buf, i); - - /* dequeue transmitted chars */ - if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEA) { - rv = rtems_termios_dequeue_characters( - cd->termios_data, chars_to_dequeue); - if ( !rv ) { - cd->pDeviceContext = 0; - cd->bActive = false; - } - ERC32_Clear_interrupt (ERC32_INTERRUPT_UART_A_RX_TX); - } - } while (ERC32_Is_interrupt_pending (ERC32_INTERRUPT_UART_A_RX_TX)); -} - -static void erc32_console_isr_b( - rtems_vector_number vector -) -{ - console_data *cd = &Console_Port_Data[1]; - - /* check for error */ - if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_ERRB) { - ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRB; - ERC32_MEC.Control = ERC32_MEC.Control; - } - - do { - int chars_to_dequeue = (int)cd->pDeviceContext; - int rv = 0; - int i = 0; - char buf[CONSOLE_BUF_SIZE]; - - /* enqueue received chars */ - while (i < CONSOLE_BUF_SIZE) { - if (!(ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_DRB)) - break; - buf[i] = ERC32_MEC.UART_Channel_B; - ++i; - } - if ( i ) - rtems_termios_enqueue_raw_characters(cd->termios_data, buf, i); - - /* dequeue transmitted chars */ - if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEB) { - rv = rtems_termios_dequeue_characters( - cd->termios_data, chars_to_dequeue); - if ( !rv ) { - cd->pDeviceContext = 0; - cd->bActive = false; - } - ERC32_Clear_interrupt (ERC32_INTERRUPT_UART_B_RX_TX); - } - } while (ERC32_Is_interrupt_pending (ERC32_INTERRUPT_UART_B_RX_TX)); -} -#else - -extern void console_outbyte_polled( int port, unsigned char ch ); - -static ssize_t erc32_console_write_support_polled( - int minor, - const char *buf, - size_t len -) -{ - int nwrite = 0; - - while (nwrite < len) { - console_outbyte_polled( minor, *buf++ ); - nwrite++; - } - return nwrite; -} - -#endif - - -/* - * Console Device Driver Entry Points - * - */ - -static void erc32_console_initialize( - int minor -) -{ - console_data *cd = &Console_Port_Data [minor]; - - cd->bActive = false; - cd->pDeviceContext = 0; - - /* - * Initialize the Termios infrastructure. If Termios has already - * been initialized by another device driver, then this call will - * have no effect. - */ - rtems_termios_initialize(); - - /* - * Initialize Hardware - */ - #if (CONSOLE_USE_INTERRUPTS) - set_vector(erc32_console_isr_a, CONSOLE_UART_A_TRAP, 1); - set_vector(erc32_console_isr_b, CONSOLE_UART_B_TRAP, 1); - set_vector(erc32_console_isr_error, CONSOLE_UART_ERROR_TRAP, 1); - #endif - - /* Clear any previous error flags */ - ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRA; - ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRB; -} diff --git a/c/src/lib/libbsp/sparc/leon2/Makefile.am b/c/src/lib/libbsp/sparc/leon2/Makefile.am index 4df4cd917f..a20cd32605 100644 --- a/c/src/lib/libbsp/sparc/leon2/Makefile.am +++ b/c/src/lib/libbsp/sparc/leon2/Makefile.am @@ -42,8 +42,8 @@ librtemsbsp_a_SOURCES += ../shared/irq_asm.S librtemsbsp_a_SOURCES += gnatsupp/gnatsupp.c librtemsbsp_a_SOURCES += ../shared/gnatcommon.c # console -librtemsbsp_a_SOURCES += console/console.c -librtemsbsp_a_SOURCES += console/debugputs.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon2/console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon2/console/debugputs.c # clock librtemsbsp_a_SOURCES +=../../../../../../bsps/sparc/leon2/clock/ckinit.c # IRQ diff --git a/c/src/lib/libbsp/sparc/leon2/console/console.c b/c/src/lib/libbsp/sparc/leon2/console/console.c deleted file mode 100644 index 611dbfa5f3..0000000000 --- a/c/src/lib/libbsp/sparc/leon2/console/console.c +++ /dev/null @@ -1,437 +0,0 @@ -/** - * @file - * @ingroup sparc_leon2 - * @brief TTY driver driver for the serial ports on the LEON console - * - * This file contains the TTY driver for the serial ports on the LEON. - */ - -/* - * COPYRIGHT (c) 1989-2014. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include - -#include -#include -#include -#include - -/* - * console_outbyte_polled - * - * This routine transmits a character using polling. - */ -void console_outbyte_polled( - int port, - unsigned char ch -); - -/* body is in debugputs.c */ - -/* - * console_inbyte_nonblocking - * - * This routine polls for a character. - */ - -int console_inbyte_nonblocking( int port ); - -/* body is in debugputs.c */ - -/* - * Interrupt driven console IO - */ - -#if (CONSOLE_USE_INTERRUPTS) - -/* - * Buffers between task and ISRs - */ - -#include - -Ring_buffer_t TX_Buffer[ 2 ]; -bool Is_TX_active[ 2 ]; - -void *console_termios_data[ 2 ]; - -/* - * console_isr_a - * - * This routine is the console interrupt handler for Channel 1. - * - * Input parameters: - * vector - vector number - * - * Output parameters: NONE - * - * Return values: NONE - */ - -rtems_isr console_isr_a( - rtems_vector_number vector -) -{ - char ch; - int UStat; - - if ( (UStat = LEON_REG.UART_Status_1) & LEON_REG_UART_STATUS_DR ) { - if (UStat & LEON_REG_UART_STATUS_ERR) { - LEON_REG.UART_Status_1 = LEON_REG_UART_STATUS_CLR; - } - ch = LEON_REG.UART_Channel_1; - - rtems_termios_enqueue_raw_characters( console_termios_data[ 0 ], &ch, 1 ); - } - - if ( LEON_REG.UART_Status_1 & LEON_REG_UART_STATUS_THE ) { - if ( !Ring_buffer_Is_empty( &TX_Buffer[ 0 ] ) ) { - Ring_buffer_Remove_character( &TX_Buffer[ 0 ], ch ); - LEON_REG.UART_Channel_1 = (uint32_t) ch; - } else - Is_TX_active[ 0 ] = false; - } - - LEON_Clear_interrupt( LEON_INTERRUPT_UART_1_RX_TX ); -} - -/* - * console_isr_b - * - * This routine is the console interrupt handler for Channel 2. - * - * Input parameters: - * vector - vector number - * - * Output parameters: NONE - * - * Return values: NONE - */ - -rtems_isr console_isr_b( - rtems_vector_number vector -) -{ - char ch; - int UStat; - - if ( (UStat = LEON_REG.UART_Status_2) & LEON_REG_UART_STATUS_DR ) { - if (UStat & LEON_REG_UART_STATUS_ERR) { - LEON_REG.UART_Status_2 = LEON_REG_UART_STATUS_CLR; - } - ch = LEON_REG.UART_Channel_2; - rtems_termios_enqueue_raw_characters( console_termios_data[ 1 ], &ch, 1 ); - - } - - if ( LEON_REG.UART_Status_2 & LEON_REG_UART_STATUS_THE ) { - if ( !Ring_buffer_Is_empty( &TX_Buffer[ 1 ] ) ) { - Ring_buffer_Remove_character( &TX_Buffer[ 1 ], ch ); - LEON_REG.UART_Channel_2 = (uint32_t) ch; - } else - Is_TX_active[ 1 ] = false; - } - - LEON_Clear_interrupt( LEON_INTERRUPT_UART_2_RX_TX ); -} - -/* - * console_exit - * - * This routine allows the console to exit by masking its associated interrupt - * vectors. - * - * Input parameters: NONE - * - * Output parameters: NONE - * - * Return values: NONE - */ - -void console_exit() -{ - uint32_t port; - uint32_t ch; - - /* - * Although the interrupts for the UART are unmasked, the PIL is set to - * disable all external interrupts. So we might as well do this first. - */ - - LEON_Mask_interrupt( LEON_INTERRUPT_UART_1_RX_TX ); - LEON_Mask_interrupt( LEON_INTERRUPT_UART_2_RX_TX ); - - for ( port=0 ; port <= 1 ; port++ ) { - while ( !Ring_buffer_Is_empty( &TX_Buffer[ port ] ) ) { - Ring_buffer_Remove_character( &TX_Buffer[ port ], ch ); - console_outbyte_polled( port, ch ); - } - } - - /* - * Now wait for all the data to actually get out ... the send register - * should be empty. - */ - - while ( (LEON_REG.UART_Status_1 & LEON_REG_UART_STATUS_THE) != - LEON_REG_UART_STATUS_THE ); - - while ( (LEON_REG.UART_Status_2 & LEON_REG_UART_STATUS_THE) != - LEON_REG_UART_STATUS_THE ); - - LEON_REG.UART_Control_1 = 0; - LEON_REG.UART_Control_2 = 0; - LEON_REG.UART_Status_1 = 0; - LEON_REG.UART_Status_2 = 0; - - -} - -#define CONSOLE_UART_1_TRAP LEON_TRAP_TYPE( LEON_INTERRUPT_UART_1_RX_TX ) -#define CONSOLE_UART_2_TRAP LEON_TRAP_TYPE( LEON_INTERRUPT_UART_2_RX_TX ) - -/* - * console_initialize_interrupts - * - * This routine initializes the console's receive and transmit - * ring buffers and loads the appropriate vectors to handle the interrupts. - * - * Input parameters: NONE - * - * Output parameters: NONE - * - * Return values: NONE - */ - -#ifdef RDB_BREAK_IN - extern uint32_t trap_table[]; -#endif - -void console_initialize_interrupts( void ) -{ - Ring_buffer_Initialize( &TX_Buffer[ 0 ] ); - Ring_buffer_Initialize( &TX_Buffer[ 1 ] ); - - Is_TX_active[ 0 ] = false; - Is_TX_active[ 1 ] = false; - - atexit( console_exit ); - - LEON_REG.UART_Control_1 |= LEON_REG_UART_CTRL_RI | LEON_REG_UART_CTRL_TI; - LEON_REG.UART_Control_2 |= LEON_REG_UART_CTRL_RI | LEON_REG_UART_CTRL_TI; - - set_vector( console_isr_a, CONSOLE_UART_1_TRAP, 1 ); -#ifdef RDB_BREAK_IN - if (trap_table[0x150/4] == 0x91d02000) -#endif - set_vector( console_isr_b, CONSOLE_UART_2_TRAP, 1 ); -} - -/* - * console_outbyte_interrupt - * - * This routine transmits a character out. - * - * Input parameters: - * port - port to transmit character to - * ch - character to be transmitted - * - * Output parameters: NONE - * - * Return values: NONE - */ - -void console_outbyte_interrupt( - int port, - char ch -) -{ - /* - * If this is the first character then we need to prime the pump - */ - - if ( Is_TX_active[ port ] == false ) { - Is_TX_active[ port ] = true; - console_outbyte_polled( port, ch ); - return; - } - - while ( Ring_buffer_Is_full( &TX_Buffer[ port ] ) ); - - Ring_buffer_Add_character( &TX_Buffer[ port ], ch ); -} - -#endif /* CONSOLE_USE_INTERRUPTS */ - -/* - * Console Termios Support Entry Points - * - */ - -static ssize_t console_write_support (int minor, const char *buf, size_t len) -{ - int nwrite = 0; - - while (nwrite < len) { -#if (CONSOLE_USE_INTERRUPTS) - console_outbyte_interrupt( minor, *buf++ ); -#else - console_outbyte_polled( minor, *buf++ ); -#endif - nwrite++; - } - return nwrite; -} - -/* - * Console Device Driver Entry Points - * - */ - -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - - rtems_termios_initialize(); - - /* - * Register Device Names - */ - - status = rtems_io_register_name( "/dev/console", major, 0 ); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - status = rtems_io_register_name( "/dev/console_b", major, 1 ); - if (status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); - - /* - * Initialize Hardware - */ - - LEON_REG.UART_Control_1 |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE; - LEON_REG.UART_Control_2 |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE | - LEON_REG_UART_CTRL_RI; /* rx irq default enable for remote debugger */ - LEON_REG.UART_Status_1 = 0; - LEON_REG.UART_Status_2 = 0; -#if (CONSOLE_USE_INTERRUPTS) - console_initialize_interrupts(); -#endif - - return RTEMS_SUCCESSFUL; -} - -rtems_device_driver console_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - rtems_status_code sc; -#if (CONSOLE_USE_INTERRUPTS) - rtems_libio_open_close_args_t *args = arg; - static const rtems_termios_callbacks intrCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - NULL, /* pollRead */ - console_write_support, /* write */ - NULL, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - 0 /* outputUsesInterrupts */ - }; -#else - static const rtems_termios_callbacks pollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - console_inbyte_nonblocking, /* pollRead */ - console_write_support, /* write */ - NULL, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - 0 /* outputUsesInterrupts */ - }; -#endif - - assert( minor <= 1 ); - if ( minor > 2 ) - return RTEMS_INVALID_NUMBER; - -#if (CONSOLE_USE_INTERRUPTS) - sc = rtems_termios_open (major, minor, arg, &intrCallbacks); - - console_termios_data[ minor ] = args->iop->data1; -#else - sc = rtems_termios_open (major, minor, arg, &pollCallbacks); -#endif - (void) sc; /* avoid set but not used warning */ - - return RTEMS_SUCCESSFUL; -} - -rtems_device_driver console_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_close (arg); -} - -rtems_device_driver console_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_read (arg); -} - -rtems_device_driver console_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_write (arg); -} - -rtems_device_driver console_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void * arg -) -{ - return rtems_termios_ioctl (arg); -} - -/* putchar/getchar for printk */ - -static void bsp_out_char (char c) -{ - console_outbyte_polled(0, c); -} - -BSP_output_char_function_type BSP_output_char = bsp_out_char; - -static int bsp_in_char(void) -{ - int tmp; - - while ((tmp = console_inbyte_nonblocking(0)) < 0); - return tmp; -} - -BSP_polling_getchar_function_type BSP_poll_char = bsp_in_char; diff --git a/c/src/lib/libbsp/sparc/leon2/console/debugputs.c b/c/src/lib/libbsp/sparc/leon2/console/debugputs.c deleted file mode 100644 index c5919f275e..0000000000 --- a/c/src/lib/libbsp/sparc/leon2/console/debugputs.c +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @file - * @ingroup sparc_leon2 - * @brief TTY driver for the serial ports on the LEON - */ - -/* - * This file contains the TTY driver for the serial ports on the LEON. - * - * This driver uses the termios pseudo driver. - * - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include - -/* - * Method is shared with console.c - */ -void console_outbyte_polled( int port, unsigned char ch ); -int console_inbyte_nonblocking( int port ); - -/* - * console_outbyte_polled - * - * This routine transmits a character using polling. - */ - -void console_outbyte_polled( - int port, - unsigned char ch -) -{ - if ( port == 0 ) { - while ( (LEON_REG.UART_Status_1 & LEON_REG_UART_STATUS_THE) == 0 ); - LEON_REG.UART_Channel_1 = (unsigned int) ch; - return; - } - - while ( (LEON_REG.UART_Status_2 & LEON_REG_UART_STATUS_THE) == 0 ); - LEON_REG.UART_Channel_2 = (unsigned int) ch; -} - -/* - * console_inbyte_nonblocking - * - * This routine polls for a character. - */ - -int console_inbyte_nonblocking( int port ) -{ - - switch (port) { - - case 0: - if (LEON_REG.UART_Status_1 & LEON_REG_UART_STATUS_ERR) { - LEON_REG.UART_Status_1 = ~LEON_REG_UART_STATUS_ERR; - } - - if ((LEON_REG.UART_Status_1 & LEON_REG_UART_STATUS_DR) == 0) - return -1; - return (int) LEON_REG.UART_Channel_1; - return 1; - - case 1: - if (LEON_REG.UART_Status_2 & LEON_REG_UART_STATUS_ERR) { - LEON_REG.UART_Status_2 = ~LEON_REG_UART_STATUS_ERR; - } - - if ((LEON_REG.UART_Status_2 & LEON_REG_UART_STATUS_DR) == 0) - return -1; - return (int) LEON_REG.UART_Channel_2; - - default: - assert( 0 ); - } - - return -1; -} diff --git a/c/src/lib/libbsp/sparc/leon3/Makefile.am b/c/src/lib/libbsp/sparc/leon3/Makefile.am index 6432fcde9a..7c76d726f0 100644 --- a/c/src/lib/libbsp/sparc/leon3/Makefile.am +++ b/c/src/lib/libbsp/sparc/leon3/Makefile.am @@ -67,12 +67,12 @@ librtemsbsp_a_SOURCES += ../shared/timer/tlib_ckinit.c librtemsbsp_a_SOURCES +=../../../../../../bsps/sparc/leon3/clock/ckinit.c # console -librtemsbsp_a_SOURCES += ../../shared/console-termios.c -librtemsbsp_a_SOURCES += console/console.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon3/console/console.c librtemsbsp_a_SOURCES += ../shared/uart/cons.c librtemsbsp_a_SOURCES += ../shared/uart/apbuart_cons.c # debugio -librtemsbsp_a_SOURCES += console/printk_support.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon3/console/printk_support.c # IRQ librtemsbsp_a_SOURCES += startup/eirq.c diff --git a/c/src/lib/libbsp/sparc/leon3/console/console.c b/c/src/lib/libbsp/sparc/leon3/console/console.c deleted file mode 100644 index acab893399..0000000000 --- a/c/src/lib/libbsp/sparc/leon3/console/console.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * This file contains the TTY driver for the serial ports on the LEON. - * - * This driver uses the termios pseudo driver. - * - * COPYRIGHT (c) 1989-1998. - * On-Line Applications Research Corporation (OAR). - * - * Modified for LEON3 BSP. - * COPYRIGHT (c) 2004. - * Gaisler Research. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -/* Define CONSOLE_USE_INTERRUPTS to enable APBUART interrupt handling instead - * of polling mode. - * - * Note that it is not possible to use the interrupt mode of the driver - * together with the "old" APBUART and -u to GRMON. However the new - * APBUART core (from GRLIB 1.0.17-b2710) has the GRMON debug bit and can - * handle interrupts. - * - * NOTE: This can be defined in the make/custom/leon3.cfg file. - */ - -#include -#include -#include -#include -#include - -/* The LEON3 BSP UART driver can rely on the Driver Manager if the - * DrvMgr is initialized during startup. Otherwise the classic driver - * must be used. - * - * The DrvMgr APBUART driver is located in the shared/uart directory - */ -#ifndef RTEMS_DRVMGR_STARTUP - -int syscon_uart_index __attribute__((weak)) = 0; - -/* body is in debugputs.c */ -static struct apbuart_context apbuarts[BSP_NUMBER_OF_TERMIOS_PORTS]; -static int uarts = 0; - -static rtems_termios_device_context *leon3_console_get_context(int index) -{ - struct apbuart_context *uart = &apbuarts[index]; - - rtems_termios_device_context_initialize(&uart->base, "APBUART"); - - return &uart->base; -} - -/* AMBA PP find routine. Extract AMBA PnP information into data structure. */ -static int find_matching_apbuart(struct ambapp_dev *dev, int index, void *arg) -{ - struct ambapp_apb_info *apb = (struct ambapp_apb_info *)dev->devinfo; - - /* Extract needed information of one APBUART */ - apbuarts[uarts].regs = (struct apbuart_regs *)apb->start; - apbuarts[uarts].irq = apb->irq; - /* Get APBUART core frequency, it is assumed that it is the same - * as Bus frequency where the UART is situated - */ - apbuarts[uarts].freq_hz = ambapp_freq_get(&ambapp_plb, dev); - uarts++; - - if (uarts >= BSP_NUMBER_OF_TERMIOS_PORTS) - return 1; /* Satisfied number of UARTs, stop search */ - else - return 0; /* Continue searching for more UARTs */ -} - -/* Find all UARTs */ -static void leon3_console_scan_uarts(void) -{ - memset(apbuarts, 0, sizeof(apbuarts)); - - /* Find APBUART cores */ - ambapp_for_each(&ambapp_plb, (OPTIONS_ALL|OPTIONS_APB_SLVS), VENDOR_GAISLER, - GAISLER_APBUART, find_matching_apbuart, NULL); -} - -rtems_device_driver console_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - const rtems_termios_device_handler *handler = -#if CONSOLE_USE_INTERRUPTS - &apbuart_handler_interrupt; -#else - &apbuart_handler_polled; -#endif - rtems_status_code status; - int i; - char console_name[16]; - - rtems_termios_initialize(); - - /* Find UARTs */ - leon3_console_scan_uarts(); - - /* Update syscon_uart_index to index used as /dev/console - * Let user select System console by setting syscon_uart_index. If the - * BSP is to provide the default UART (syscon_uart_index==0): - * non-MP: APBUART[0] is system console - * MP: LEON CPU index select UART - */ - if (syscon_uart_index == 0) { -#if defined(RTEMS_MULTIPROCESSING) - syscon_uart_index = LEON3_Cpu_Index; -#else - syscon_uart_index = 0; -#endif - } else { - syscon_uart_index = syscon_uart_index - 1; /* User selected sys-console */ - } - - /* Register Device Names - * - * 0 /dev/console - APBUART[USER-SELECTED, DEFAULT=APBUART[0]] - * 1 /dev/console_a - APBUART[0] (by default not present because is console) - * 2 /dev/console_b - APBUART[1] - * ... - * - * On a MP system one should not open UARTs that other OS instances use. - */ - if (syscon_uart_index < uarts) { - status = rtems_termios_device_install( - CONSOLE_DEVICE_NAME, - handler, - NULL, - leon3_console_get_context(syscon_uart_index) - ); - if (status != RTEMS_SUCCESSFUL) - bsp_fatal(LEON3_FATAL_CONSOLE_REGISTER_DEV); - } - strcpy(console_name,"/dev/console_a"); - for (i = 0; i < uarts; i++) { - if (i == syscon_uart_index) - continue; /* skip UART that is registered as /dev/console */ - console_name[13] = 'a' + i; - rtems_termios_device_install( - console_name, - handler, - NULL, - leon3_console_get_context(i) - ); - } - - return RTEMS_SUCCESSFUL; -} - -#endif diff --git a/c/src/lib/libbsp/sparc/leon3/console/printk_support.c b/c/src/lib/libbsp/sparc/leon3/console/printk_support.c deleted file mode 100644 index f7e1fb683f..0000000000 --- a/c/src/lib/libbsp/sparc/leon3/console/printk_support.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * This file contains the TTY driver for the serial ports on the LEON. - * - * This driver uses the termios pseudo driver. - * - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * Modified for LEON3 BSP. - * COPYRIGHT (c) 2011. - * Aeroflex Gaisler. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int leon3_debug_uart_index __attribute__((weak)) = 0; -struct apbuart_regs *leon3_debug_uart = NULL; - -/* Before UART driver has registered (or when no UART is available), calls to - * printk that gets to bsp_out_char() will be filling data into the - * pre_printk_dbgbuf[] buffer, hopefully the buffer can help debugging the - * early BSP boot.. At least the last printk() will be caught. - */ -static char pre_printk_dbgbuf[32] = {0}; -static int pre_printk_pos = 0; - -/* Initialize the BSP system debug console layer. It will scan AMBA Plu&Play - * for a debug APBUART and enable RX/TX for that UART. - */ -static void bsp_debug_uart_init(void) -{ - int i; - struct ambapp_dev *adev; - struct ambapp_apb_info *apb; - - /* Update leon3_debug_uart_index to index used as debug console. Let user - * select Debug console by setting leon3_debug_uart_index. If the BSP is to - * provide the default UART (leon3_debug_uart_index==0): - * non-MP: APBUART[0] is debug console - * MP: LEON CPU index select UART - */ - if (leon3_debug_uart_index == 0) { -#if defined(RTEMS_MULTIPROCESSING) - leon3_debug_uart_index = LEON3_Cpu_Index; -#else - leon3_debug_uart_index = 0; -#endif - } else { - leon3_debug_uart_index--; /* User selected dbg-console */ - } - - /* Find APBUART core for System Debug Console */ - i = leon3_debug_uart_index; - adev = (void *)ambapp_for_each(&ambapp_plb, (OPTIONS_ALL|OPTIONS_APB_SLVS), - VENDOR_GAISLER, GAISLER_APBUART, - ambapp_find_by_idx, (void *)&i); - if (adev) { - /* Found a matching debug console, initialize debug uart if present - * for printk - */ - apb = (struct ambapp_apb_info *)adev->devinfo; - leon3_debug_uart = (struct apbuart_regs *)apb->start; - leon3_debug_uart->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; - leon3_debug_uart->status = 0; - } -} - -RTEMS_SYSINIT_ITEM( - bsp_debug_uart_init, - RTEMS_SYSINIT_BSP_START, - RTEMS_SYSINIT_ORDER_FOURTH -); - -/* putchar/getchar for printk */ -static void bsp_out_char(char c) -{ - if (leon3_debug_uart == NULL) { - /* Local debug buffer when UART driver has not registered */ - pre_printk_dbgbuf[pre_printk_pos++] = c; - pre_printk_pos = pre_printk_pos & (sizeof(pre_printk_dbgbuf)-1); - return; - } - - apbuart_outbyte_polled(leon3_debug_uart, c, 1, 1); -} - -/* - * To support printk - */ - -#include - -BSP_output_char_function_type BSP_output_char = bsp_out_char; - -static int bsp_in_char(void) -{ - int tmp; - - if (leon3_debug_uart == NULL) - return EOF; - - while ((tmp = apbuart_inbyte_nonblocking(leon3_debug_uart)) < 0) - ; - return tmp; -} - -BSP_polling_getchar_function_type BSP_poll_char = bsp_in_char; diff --git a/c/src/lib/libbsp/sparc64/niagara/Makefile.am b/c/src/lib/libbsp/sparc64/niagara/Makefile.am index 7ff741fe12..a0614da7ba 100644 --- a/c/src/lib/libbsp/sparc64/niagara/Makefile.am +++ b/c/src/lib/libbsp/sparc64/niagara/Makefile.am @@ -37,7 +37,7 @@ librtemsbsp_a_SOURCES += ../shared/asm/asm.S librtemsbsp_a_SOURCES +=../../../../../../bsps/sparc64/shared/clock/ckinit.c -librtemsbsp_a_SOURCES += ../shared/console/conscfg.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc64/shared/console/conscfg.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c diff --git a/c/src/lib/libbsp/sparc64/shared/console/conscfg.c b/c/src/lib/libbsp/sparc64/shared/console/conscfg.c deleted file mode 100644 index 560bdc05bf..0000000000 --- a/c/src/lib/libbsp/sparc64/shared/console/conscfg.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * COPYRIGHT (c) 2010 Eugen Leontie. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include - -#include - -#include - -static int sun4v_console_device_first_open(int major, int minor, void *arg) -{ - return 0; -} - -static ssize_t sun4v_console_poll_write(int minor, const char *buf, size_t n) -{ - ofw_write(buf, n); - return 0; -} - -static void sun4v_console_deviceInitialize (int minor) -{ - -} - -static int sun4v_console_poll_read(int minor){ - int a; - ofw_read(&a,1); - if ( a != 0 ) { - return a>>24; - } - return -1; -} - -static bool sun4v_console_deviceProbe (int minor){ - return true; -} - -/* - * Polled mode functions - */ -const console_fns pooled_functions={ - sun4v_console_deviceProbe, /* deviceProbe */ - sun4v_console_device_first_open, /* deviceFirstOpen */ - NULL, /* deviceLastClose */ - sun4v_console_poll_read, /* deviceRead */ - sun4v_console_poll_write, /* deviceWrite */ - sun4v_console_deviceInitialize, /* deviceInitialize */ - NULL, /* deviceWritePolled */ - NULL, /* deviceSetAttributes */ - NULL /* deviceOutputUsesInterrupts */ -}; - -const console_flow sun4v_console_console_flow = { - NULL, /* deviceStopRemoteTx */ - NULL /* deviceStartRemoteTx */ -}; - -console_tbl Console_Configuration_Ports[] = { - { - "/dev/ttyS0", /* sDeviceName */ - SERIAL_CUSTOM, /* deviceType */ - &pooled_functions, /* pDeviceFns */ - NULL, /* deviceProbe, assume it is there */ - &sun4v_console_console_flow, /* pDeviceFlow */ - 0, /* ulMargin */ - 0, /* ulHysteresis */ - (void *) NULL, /* pDeviceParams */ - 0, /* ulCtrlPort1 */ - 0, /* ulCtrlPort2 */ - 1, /* ulDataPort */ - NULL, /* getRegister */ - NULL, /* setRegister */ - NULL, /* unused */ /* getData */ - NULL, /* unused */ /* setData */ - 0, /* ulClock */ - 0 /* ulIntVector -- base for port */ - }, -}; - -/* - * Declare some information used by the console driver - */ - -#define NUM_CONSOLE_PORTS 1 - -unsigned long Console_Configuration_Count = NUM_CONSOLE_PORTS; - -/* putchar/getchar for printk */ - -static void bsp_out_char (char c) -{ - ofw_write(&c, 1); -} - -BSP_output_char_function_type BSP_output_char = bsp_out_char; - -static int bsp_in_char( void ){ - int tmp; - ofw_read( &tmp, 1 ); /* blocks */ - if( tmp != 0 ) { - return tmp>>24; - } - return -1; -} - -BSP_polling_getchar_function_type BSP_poll_char = bsp_in_char; - diff --git a/c/src/lib/libbsp/sparc64/usiii/Makefile.am b/c/src/lib/libbsp/sparc64/usiii/Makefile.am index 1e7c503ea0..e693732c05 100644 --- a/c/src/lib/libbsp/sparc64/usiii/Makefile.am +++ b/c/src/lib/libbsp/sparc64/usiii/Makefile.am @@ -48,7 +48,7 @@ librtemsbsp_a_SOURCES += ../shared/start/trap_table.S librtemsbsp_a_SOURCES +=../../../../../../bsps/sparc64/shared/clock/ckinit.c -librtemsbsp_a_SOURCES += ../shared/console/conscfg.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc64/shared/console/conscfg.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c diff --git a/c/src/lib/libbsp/v850/gdbv850sim/Makefile.am b/c/src/lib/libbsp/v850/gdbv850sim/Makefile.am index 8efdb42f0a..367f838c5d 100644 --- a/c/src/lib/libbsp/v850/gdbv850sim/Makefile.am +++ b/c/src/lib/libbsp/v850/gdbv850sim/Makefile.am @@ -27,8 +27,8 @@ librtemsbsp_a_SOURCES += ../shared/crt1.c librtemsbsp_a_SOURCES += startup/trap.S librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/clock/clock-simidle.c -librtemsbsp_a_SOURCES += ../../shared/console-polled.c -librtemsbsp_a_SOURCES += console/console-io.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-polled.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/v850/gdbv850sim/console/console-io.c librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/btimer/btimer-stub.c # Cache diff --git a/c/src/lib/libbsp/v850/gdbv850sim/console/console-io.c b/c/src/lib/libbsp/v850/gdbv850sim/console/console-io.c deleted file mode 100644 index c1f51a34d7..0000000000 --- a/c/src/lib/libbsp/v850/gdbv850sim/console/console-io.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * COPYRIGHT (c) 1989-2012. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include - -/* - * console_initialize_hardware - * - * This routine initializes the console hardware. - */ -void console_initialize_hardware(void) -{ -} - -/* - * console_outbyte_polled - * - * This routine transmits a character using polling. - */ -void console_outbyte_polled( - int port, - char ch -) -{ - TRAP0(SYS_write, 1, &ch, 1); -} - -/* - * console_inbyte_nonblocking - * - * This routine polls for a character. - */ - -int console_inbyte_nonblocking( - int port -) -{ - char ch; - int rc; - - rc = TRAP0 (SYS_read, 0, &ch, 1); - - if ( rc != 1 ) - return -1; - return ch; -} - -#include - -static void console_output_char(char c) { console_outbyte_polled( 0, c ); } - -BSP_output_char_function_type BSP_output_char = console_output_char; -BSP_polling_getchar_function_type BSP_poll_char = NULL; -- cgit v1.2.3