📄 console.c
字号:
/* Enable SDMA. */ ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1; /* Use Port B for SMCs instead of other functions. */ cp->cp_pbpar |= 0x00000cc0; cp->cp_pbdir &= ~0x00000cc0; cp->cp_pbodr &= ~0x00000cc0; /* Allocate space for two buffer descriptors in the DP ram. * For now, this address seems OK, but it may have to * change with newer versions of the firmware. */ dpaddr = 0x0800; /* Grab a few bytes from the top of memory. EPPC-Bug isn't * running any more, so we can do this. */ memaddr = (bd->bi_memsize - 32) & ~15; /* Set the physical address of the host memory buffers in * the buffer descriptors. */ rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr]; rbdf->cbd_bufaddr = memaddr; rbdf->cbd_sc = 0; tbdf = rbdf + 1; tbdf->cbd_bufaddr = memaddr+4; tbdf->cbd_sc = 0; /* Set up the uart parameters in the parameter ram. */ up->smc_rbase = dpaddr; up->smc_tbase = dpaddr+sizeof(cbd_t); up->smc_rfcr = SMC_EB; up->smc_tfcr = SMC_EB; /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. */ sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; /* Mask all interrupts and remove anything pending. */ sp->smc_smcm = 0; sp->smc_smce = 0xff; /* Set up the baud rate generator. * See 8xx_io/commproc.c for details. */ cp->cp_simode = 0x10000000; cp->cp_brgc1 = ((((bd->bi_intfreq * 1000000)/16) / 9600) << 1) | CPM_BRG_EN; /* Enable SMC1 for console output. */ *MBX_CSR1 &= ~CSR1_COMEN; } else { /* SMCx is used as console port. */ tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase]; rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase]; /* Issue a stop transmit, and wait for it. */ cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, CPM_CR_STOP_TX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG); } /* Make the first buffer the only buffer. */ tbdf->cbd_sc |= BD_SC_WRAP; rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; /* Single character receive. */ up->smc_mrblr = 1; up->smc_maxidl = 0; /* Initialize Tx/Rx parameters. */ cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, CPM_CR_INIT_TRX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG); /* Enable transmitter/receiver. */ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;#if NVRAM_CONFIGURE == 1 } else { const char bootmsg_text[]= "using EPPC bug for console I/O\n"; _EPPCBug_pollWrite((nvram->console_printk_port & 0x70) >> 4, bootmsg_text, sizeof(bootmsg_text)-1); }#endif#if NVRAM_CONFIGURE == 1 if ((nvram->console_mode & 0x30) == 0x20 ) { BSP_output_char = _BSP_output_char; } else { BSP_output_char = serial_putchar; }#else BSP_output_char = serial_putchar;#endif}voidserial_putchar(const char c){ volatile cbd_t *tbdf; volatile char *buf; volatile smc_uart_t *up; up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase]; /* Wait for last character to go. */ buf = (char *)tbdf->cbd_bufaddr; while (tbdf->cbd_sc & BD_SC_READY); *buf = c; tbdf->cbd_datlen = 1; tbdf->cbd_sc |= BD_SC_READY;}charserial_getc(){ volatile cbd_t *rbdf; volatile char *buf; volatile smc_uart_t *up; char c; up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; /* Wait for character to show up. */ buf = (char *)rbdf->cbd_bufaddr; while (rbdf->cbd_sc & BD_SC_EMPTY); c = *buf; rbdf->cbd_sc |= BD_SC_EMPTY; return(c);}intserial_tstc(){ volatile cbd_t *rbdf; volatile smc_uart_t *up; up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; return(!(rbdf->cbd_sc & BD_SC_EMPTY));}#endif/* *************** * 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 == 1 /* Use NVRAM info for configuration */ console_minor = nvram->console_printk_port & 0x07; if ( nvram->console_mode & 0x01 ) /* termios */ rtems_termios_initialize (); /* * Do common initialization. */ m8xx_uart_initialize(); /* * Do device-specific initialization */ if ( !nvram->eppcbug_smc1 && ( ((nvram->console_mode & 0x30) != 0x20) || (((nvram->console_printk_port & 0x30) >> 4) != SMC1_MINOR) ) ) m8xx_uart_smc_initialize(SMC1_MINOR); /* /dev/tty0 */ if ( ((nvram->console_mode & 0x30) != 0x20) || (((nvram->console_printk_port & 0x30) >> 4) != SMC2_MINOR) ) m8xx_uart_smc_initialize(SMC2_MINOR); /* /dev/tty1 */ if ( ((nvram->console_mode & 0x30) != 0x20) || (((nvram->console_printk_port & 0x30) >> 4) != SCC2_MINOR) ) m8xx_uart_scc_initialize(SCC2_MINOR); /* /dev/tty2 */ #ifdef mpc860 if ( ((nvram->console_mode & 0x30) != 0x20) || (((nvram->console_printk_port & 0x30) >> 4) != SCC3_MINOR) ) m8xx_uart_scc_initialize(SCC3_MINOR); /* /dev/tty3 */ if ( ((nvram->console_mode & 0x30) != 0x20) || (((nvram->console_printk_port & 0x30) >> 4) != SCC4_MINOR) ) m8xx_uart_scc_initialize(SCC4_MINOR); /* /dev/tty4 */#endif /* mpc860 */ BSP_output_char = _BSP_output_char;#else /* NVRAM_CONFIGURE != 1 */ console_minor = CONSOLE_MINOR; #if UARTS_USE_TERMIOS == 1 rtems_termios_initialize (); #endif /* UARTS_USE_TERMIOS */ /* * Do common initialization. */ m8xx_uart_initialize(); /* * Do device-specific initialization */#if !defined(EPPCBUG_SMC1) && ( PRINTK_IO_MODE != 2 || PRINTK_MINOR != SMC1_MINOR ) m8xx_uart_smc_initialize(SMC1_MINOR); /* /dev/tty0 */#endif#if PRINTK_IO_MODE != 2 || PRINTK_MINOR != SMC2_MINOR m8xx_uart_smc_initialize(SMC2_MINOR); /* /dev/tty1 */ #endif #if PRINTK_IO_MODE != 2 || PRINTK_MINOR != SCC2_MINOR m8xx_uart_scc_initialize(SCC2_MINOR); /* /dev/tty2 */ #endif #ifdef mpc860#if PRINTK_IO_MODE != 2 || PRINTK_MINOR != SCC3_MINOR m8xx_uart_scc_initialize(SCC3_MINOR); /* /dev/tty3 */#endif#if PRINTK_IO_MODE != 2 || PRINTK_MINOR != SCC4_MINOR m8xx_uart_scc_initialize(SCC4_MINOR); /* /dev/tty4 */#endif#endif /* mpc860 */ BSP_output_char = _BSP_output_char;#endif /* NVRAM_CONFIGURE != 1 */ status = rtems_io_register_name ("/dev/tty0", major, SMC1_MINOR); if (status != RTEMS_SUCCESSFUL) rtems_fatal_error_occurred (status); status = rtems_io_register_name ("/dev/tty1", major, SMC2_MINOR); if (status != RTEMS_SUCCESSFUL) rtems_fatal_error_occurred (status); status = rtems_io_register_name ("/dev/tty2", major, SCC2_MINOR); if (status != RTEMS_SUCCESSFUL) rtems_fatal_error_occurred (status); #ifdef mpc860 status = rtems_io_register_name ("/dev/tty3", major, SCC3_MINOR); if (status != RTEMS_SUCCESSFUL) rtems_fatal_error_occurred (status); status = rtems_io_register_name ("/dev/tty4", major, SCC4_MINOR); if (status != RTEMS_SUCCESSFUL) rtems_fatal_error_occurred (status); #endif /* mpc860 */ /* 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){#if NVRAM_CONFIGURE == 1 /* 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 sccEPPCBugCallbacks = { NULL, /* firstOpen */ NULL, /* lastClose */ _EPPCBug_pollRead, /* pollRead */ _EPPCBug_pollWrite, /* write */ NULL, /* stopRemoteTx */ NULL, /* startRemoteTx */ 0 /* outputUsesInterrupts */ };#endif 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 */ }; rtems_status_code sc; #if (NVRAM_CONFIGURE == 1) || \ ((NVRAM_CONFIGURE != 1) && (UARTS_USE_TERMIOS == 1) && \ (UARTS_IO_MODE == 1)) 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 */ };#endif if ( minor > NUM_PORTS-1 ) return RTEMS_INVALID_NUMBER;#if NVRAM_CONFIGURE == 1 /* Use NVRAM info for configuration */ if ( nvram->console_mode & 0x01 ) { /* Use termios */ if ( (nvram->console_mode & 0x06) == 0x02 ) { /* interrupt-driven I/O */ sc = rtems_termios_open( major, minor, arg, &intrCallbacks ); ttyp[minor] = args->iop->data1; /* Keep cookie returned by termios_open */ return sc; } else if ( (nvram->console_mode & 0x06) == 0x04 ) /* polled I/O through EPPC-Bug, better be through SMC1 */ return rtems_termios_open( major, minor, arg, &sccEPPCBugCallbacks ); else /* normal polled I/O */ return rtems_termios_open( major, minor, arg, &pollCallbacks ); } else /* no termios -- default to polled I/O */ return RTEMS_SUCCESSFUL; #else /* NVRAM_CONFIGURE != 1 */#if UARTS_USE_TERMIOS == 1#if UARTS_IO_MODE == 2 /* EPPCBug polled I/O with termios */ sc = rtems_termios_open( major, minor, arg, &sccEPPCBugCallbacks );#elif 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; #endif /* NVRAM_CONFIGURE != 1 */}/* * 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 NVRAM_CONFIGURE == 1 /* Use NVRAM info for configuration */ if ( nvram->console_mode & 0x01 ) /* use termios */ return rtems_termios_close( arg ); else /* no termios */ return RTEMS_SUCCESSFUL;#else /* NVRAM_CONFIGURE != 1 */#if UARTS_USE_TERMIOS == 1 return rtems_termios_close( arg );#else return RTEMS_SUCCESSFUL;#endif#endif /* NVRAM_CONFIGURE != 1 */}/* * 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 NVRAM_CONFIGURE == 1 /* Use NVRAM info for configuration */ if ( nvram->console_mode & 0x01 ) /* use termios */ return rtems_termios_read( arg ); else /* no termios -- default to polled */ return do_poll_read( major, minor, arg );#else#if UARTS_USE_TERMIOS == 1 return rtems_termios_read( arg );#else return do_poll_read( major, minor, arg );#endif#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 NVRAM_CONFIGURE == 1 /* Use NVRAM info for configuration */ if ( nvram->console_mode & 0x01 ) /* use termios */ return rtems_termios_write( arg ); else /* no termios -- default to polled */ return do_poll_write( major, minor, arg );#else#if UARTS_USE_TERMIOS == 1 return rtems_termios_write( arg );#else /* no termios -- default to polled */ return do_poll_write( major, minor, arg );#endif#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 NVRAM_CONFIGURE == 1 /* Uuse NVRAM info for configuration */ if ( nvram->console_mode & 0x01 ) /* termios */ return rtems_termios_ioctl( arg ); else /* no termios -- default to polled */ return RTEMS_SUCCESSFUL;#else#if UARTS_USE_TERMIOS == 1 return rtems_termios_ioctl( arg );#else return RTEMS_SUCCESSFUL;#endif#endif}/* * Support routine for console-generic */int mbx8xx_console_get_configuration(void){#if NVRAM_CONFIGURE == 1 return nvram->console_mode;#else#if UARTS_IO_MODE == 1 return 0x02;#else return 0;#endif#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -