source: rtems/c/src/lib/libbsp/sh/shsim/gdbsci/gdbsci.c @ 0fdc099

4.104.114.84.95
Last change on this file since 0fdc099 was 0fdc099, checked in by Ralf Corsepius <ralf.corsepius@…>, on 04/16/04 at 21:51:30

Remove stray white spaces.

  • Property mode set to 100644
File size: 8.4 KB
Line 
1/*
2 * /dev/gdbsci[0|1] for gdb's simulator's SH sci emulation
3 *
4 *  Author: Ralf Corsepius (corsepiu@faw.uni-ulm.de)
5 *
6 *  COPYRIGHT (c) 2001, Ralf Corsepius, Ulm, Germany
7 *
8 *  This program is distributed in the hope that it will be useful,
9 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 *  $Id$
13 */
14
15#include <rtems.h>
16
17#include <stdlib.h>
18
19#include <rtems/libio.h>
20#include <rtems/iosupp.h>
21#include <rtems/score/sh_io.h>
22/* HACK: There must be something better than this :) */
23#if defined(__sh1__)
24#include <rtems/score/ispsh7032.h>
25#include <rtems/score/iosh7032.h>
26#elif defined(__sh2__)
27#include <rtems/score/ispsh7045.h>
28#include <rtems/score/iosh7045.h>
29#else
30#error unsupported sh model
31#endif
32#include <sh/sh7_sci.h>
33#include <sh/sh7_pfc.h>
34#include <sh/sci.h>
35
36/*
37 * gdb assumes area 5/char access (base address & 0x0500000),
38 * the RTEMS's sh7045 code however defaults to area 5/int/short/char access
39 * [Very likely a bug in the sh7045 code, RC.]
40 */
41
42#define GDBSCI_BASE 0x05ffffff
43
44#define GDBSCI0_SMR (SCI0_SMR & GDBSCI_BASE)
45#define GDBSCI0_BRR (SCI0_BRR & GDBSCI_BASE)
46#define GDBSCI0_SCR (SCI0_SCR & GDBSCI_BASE)
47#define GDBSCI0_TDR (SCI0_TDR & GDBSCI_BASE)
48#define GDBSCI0_SSR (SCI0_SSR & GDBSCI_BASE)
49#define GDBSCI0_RDR (SCI0_RDR & GDBSCI_BASE)
50
51#define GDBSCI1_SMR (SCI1_SMR & GDBSCI_BASE)
52#define GDBSCI1_BRR (SCI1_BRR & GDBSCI_BASE)
53#define GDBSCI1_SCR (SCI1_SCR & GDBSCI_BASE)
54#define GDBSCI1_TDR (SCI1_TDR & GDBSCI_BASE)
55#define GDBSCI1_SSR (SCI1_SSR & GDBSCI_BASE)
56#define GDBSCI1_RDG (SCI1_RDR & GDBSCI_BASE)
57
58/*
59 * NOTE: Only device 1 is valid for the simulator
60 */
61
62#define SH_GDBSCI_MINOR_DEVICES       2
63
64/* Force SIGBUS by using an unsupported address for /dev/gdbsci0 */
65#define SH_GDBSCI_BASE_0   SCI0_SMR
66#define SH_GDBSCI_BASE_1   GDBSCI1_SMR
67
68struct scidev_t {
69  char *                        name ;
70  uint32_t                      addr ;
71  rtems_device_minor_number     minor ;
72  unsigned short                opened ;
73  tcflag_t                      cflags ;
74} sci_device[SH_GDBSCI_MINOR_DEVICES] =
75{
76  { "/dev/gdbsci0", SH_GDBSCI_BASE_0, 0, 0, B9600 | CS8 },
77  { "/dev/gdbsci1", SH_GDBSCI_BASE_1, 1, 0, B9600 | CS8 }
78} ;
79
80/*  imported from scitab.rel */
81extern int _sci_get_brparms(
82  tcflag_t      cflag,
83  unsigned char *smr,
84  unsigned char *brr );
85
86#if 0
87/* Translate termios' tcflag_t into sci settings */
88static int _sci_set_cflags(
89  struct scidev_t      *sci_dev,
90  tcflag_t      c_cflag )
91{
92  uint8_t       smr;
93  uint8_t       brr;
94
95  if ( c_cflag & CBAUD )
96  {
97    if ( _sci_get_brparms( c_cflag, &smr, &brr ) != 0 )
98      return -1 ;
99  }
100
101  if ( c_cflag & CSIZE )
102  {
103    if ( c_cflag & CS8 )
104      smr &= ~SCI_SEVEN_BIT_DATA;
105    else if ( c_cflag & CS7 )
106      smr |= SCI_SEVEN_BIT_DATA;
107    else
108      return -1 ;
109  }
110
111  if ( c_cflag & CSTOPB )
112    smr |= SCI_STOP_BITS_2;
113  else
114    smr &= ~SCI_STOP_BITS_2;
115
116  if ( c_cflag & PARENB )
117    smr |= SCI_PARITY_ON ;
118  else
119    smr &= ~SCI_PARITY_ON ;
120
121  if ( c_cflag & PARODD )
122    smr |= SCI_ODD_PARITY ;
123  else
124    smr &= ~SCI_ODD_PARITY;
125
126  write8( smr, sci_dev->addr + SCI_SMR );
127  write8( brr, sci_dev->addr + SCI_BRR );
128
129  return 0 ;
130}
131#endif
132
133static void _sci_init(
134  rtems_device_minor_number minor )
135{
136#if NOT_SUPPORTED_BY_GDB
137  uint16_t      temp16 ;
138
139  /* Pin function controller initialisation for asynchronous mode */
140  if( minor == 0)
141    {
142      temp16 = read16( PFC_PBCR1);
143      temp16 &= ~( PB8MD | PB9MD );
144      temp16 |= (PB_TXD0 | PB_RXD0);
145      write16( temp16, PFC_PBCR1);
146    }
147  else
148    {
149      temp16 = read16( PFC_PBCR1);
150      temp16 &= ~( PB10MD | PB11MD);
151      temp16 |= (PB_TXD1 | PB_RXD1);
152      write16( temp16, PFC_PBCR1);
153    }
154
155  /* disable sck-pin */
156  if( minor == 0)
157  {
158          temp16 = read16( PFC_PBCR1);
159          temp16 &= ~(PB12MD);
160          write16( temp16, PFC_PBCR1);
161  }
162  else
163  {
164          temp16 = read16( PFC_PBCR1);
165          temp16 &= ~(PB13MD);
166          write16( temp16, PFC_PBCR1);
167  }
168#endif
169}
170
171static void _sci_tx_polled(
172  int minor,
173  const char buf )
174{
175  struct scidev_t *scidev = &sci_device[minor] ;
176#if NOT_SUPPORTED_BY_GDB
177  int8_t           ssr ;
178
179  while ( !inb((scidev->addr + SCI_SSR) & SCI_TDRE ))
180      ;
181#endif
182  write8(buf,scidev->addr+SCI_TDR);
183
184#if NOT_SUPPORTED_BY_GDB
185  ssr = inb(scidev->addr+SCI_SSR);
186  ssr &= ~SCI_TDRE ;
187  write8(ssr,scidev->addr+SCI_SSR);
188#endif
189}
190
191static int _sci_rx_polled (
192  int minor)
193{
194  struct scidev_t *scidev = &sci_device[minor] ;
195
196  unsigned char c;
197#if NOT_SUPPORTED_BY_GDB
198  char ssr ;
199  ssr = read8(scidev->addr + SCI_SSR) ;
200
201  if (ssr & (SCI_PER | SCI_FER | SCI_ORER))
202    write8(ssr & ~(SCI_PER | SCI_FER | SCI_ORER), scidev->addr+SCI_SSR);
203
204  if ( !(ssr & SCI_RDRF) )
205    return -1;
206#endif
207  c = read8(scidev->addr + SCI_RDR) ;
208#if NOT_SUPPORTED_BY_GDB
209  write8(ssr & ~SCI_RDRF,scidev->addr + SCI_SSR);
210#endif
211  return c;
212}
213
214/*
215 * sci_initialize
216 */
217
218rtems_device_driver sh_gdbsci_initialize(
219  rtems_device_major_number  major,
220  rtems_device_minor_number  minor,
221  void                      *arg )
222{
223  rtems_device_driver status ;
224  rtems_device_minor_number     i;
225
226  /*
227   * register all possible devices.
228   * the initialization of the hardware is done by sci_open
229   */
230
231  for ( i = 0 ; i < SH_GDBSCI_MINOR_DEVICES ; i++ )
232  {
233    status = rtems_io_register_name(
234      sci_device[i].name,
235      major,
236      sci_device[i].minor );
237    if (status != RTEMS_SUCCESSFUL)
238      rtems_fatal_error_occurred(status);
239  }
240
241  /* default hardware setup */
242
243  return RTEMS_SUCCESSFUL;
244}
245
246
247/*
248 *  Open entry point
249 */
250
251rtems_device_driver sh_gdbsci_open(
252  rtems_device_major_number major,
253  rtems_device_minor_number minor,
254  void                    * arg )
255{
256#if NOT_SUPPORTED_BY_GDB
257  uint8_t   temp8;
258#endif
259 /* check for valid minor number */
260   if(( minor > ( SH_GDBSCI_MINOR_DEVICES -1 )) || ( minor < 0 ))
261   {
262     return RTEMS_INVALID_NUMBER;
263   }
264
265 /* device already opened */
266  if ( sci_device[minor].opened > 0 )
267  {
268    sci_device[minor].opened++ ;
269    return RTEMS_SUCCESSFUL ;
270  }
271
272  _sci_init( minor );
273
274#if NOT_SUPPORTED_BY_GDB
275  if (minor == 0) {
276    temp8 = read8(sci_device[minor].addr + SCI_SCR);
277    temp8 &= ~(SCI_TE | SCI_RE) ;
278    write8(temp8, sci_device[minor].addr + SCI_SCR);    /* Clear SCR */
279    _sci_set_cflags( &sci_device[minor], sci_device[minor].cflags );
280
281/* FIXME: Should be one bit delay */
282    CPU_delay(50000); /* microseconds */
283
284    temp8 |= SCI_RE | SCI_TE;
285    write8(temp8, sci_device[minor].addr + SCI_SCR);    /* Enable clock output */
286  } else {
287    temp8 = read8(sci_device[minor].addr + SCI_SCR);
288    temp8 &= ~(SCI_TE | SCI_RE) ;
289    write8(temp8, sci_device[minor].addr + SCI_SCR);    /* Clear SCR */
290    _sci_set_cflags( &sci_device[minor], sci_device[minor].cflags );
291
292/* FIXME: Should be one bit delay */
293    CPU_delay(50000); /* microseconds */
294
295    temp8 |= SCI_RE | SCI_TE;
296    write8(temp8, sci_device[minor].addr + SCI_SCR);    /* Enable clock output */
297  }
298#endif
299
300  sci_device[minor].opened++ ;
301
302  return RTEMS_SUCCESSFUL ;
303}
304
305/*
306 *  Close entry point
307 */
308
309rtems_device_driver sh_gdbsci_close(
310  rtems_device_major_number major,
311  rtems_device_minor_number minor,
312  void                    * arg
313)
314{
315  if( sci_device[minor].opened == 0 )
316    {
317      return RTEMS_INVALID_NUMBER;
318    }
319
320  sci_device[minor].opened-- ;
321
322  return RTEMS_SUCCESSFUL ;
323}
324
325/*
326 * read bytes from the serial port.
327 */
328
329rtems_device_driver sh_gdbsci_read(
330  rtems_device_major_number major,
331  rtems_device_minor_number minor,
332  void                    * arg
333)
334{
335  int count = 0;
336
337  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
338  char * buffer = rw_args->buffer;
339  int maximum = rw_args->count;
340
341  for (count = 0; count < maximum; count++) {
342    buffer[ count ] = _sci_rx_polled(minor);
343    if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
344      buffer[ count++ ]  = '\n';
345      break;
346    }
347  }
348
349  rw_args->bytes_moved = count;
350  return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
351}
352
353/*
354 * write bytes to the serial port.
355 */
356
357rtems_device_driver sh_gdbsci_write(
358  rtems_device_major_number major,
359  rtems_device_minor_number minor,
360  void                    * arg
361)
362{
363  int count;
364
365  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
366  char *buffer = rw_args->buffer;
367  int maximum = rw_args->count;
368
369  for (count = 0; count < maximum; count++) {
370    _sci_tx_polled( minor, buffer[ count ] );
371  }
372
373  rw_args->bytes_moved = maximum;
374  return 0;
375}
376
377/*
378 *  IO Control entry point
379 */
380
381rtems_device_driver sh_gdbsci_control(
382  rtems_device_major_number major,
383  rtems_device_minor_number minor,
384  void                    * arg
385)
386{
387  /* Not yet supported */
388  return RTEMS_SUCCESSFUL ;
389}
Note: See TracBrowser for help on using the repository browser.