summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i386/shared/comm/i386-stub-glue.c
blob: 228b99b3e540c4a79c052fce3c60399abffa1eed (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/*
 * 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 <rtems/system.h>
#include <rtems/score/cpu.h>
#include <bsp.h>
#include <bsp/irq.h>
#include <uart.h>
#include <assert.h>

int  putDebugChar(int ch);     /* write a single character      */
int  getDebugChar(void);       /* read and return a single char */

/* assign an exception handler */
void exceptionHandler(int, void (*handler)(void));

static void
nop(const rtems_raw_irq_connect_data* notused)
{
}

static int
isOn(const rtems_raw_irq_connect_data* notused)
{
  return 1;
}

void BSP_loop(int uart);

/* Current uart used by gdb stub */
static int uart_current = 0;

/*
 * Initialize glue code linking i386-stub with the rest of
 * the system
 */
void
i386_stub_glue_init(int uart)
{
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);

  uart_current = uart;

  /* BSP_uart_init(uart, 38400, CHR_8_BITS, 0, 0, 0);*/
  BSP_uart_init(uart, 115200, CHR_8_BITS, 0, 0, 0);
}

void BSP_uart_on(const rtems_raw_irq_connect_data* used)
{
  BSP_irq_enable_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);
}

void BSP_uart_off(const rtems_raw_irq_connect_data* used)
{
  BSP_irq_disable_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);
}

int BSP_uart_isOn(const rtems_raw_irq_connect_data* used)
{
  return BSP_irq_enabled_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);
}

/*
 * In order to have a possibility to break into
 * running program, one has to call this function
 */
void i386_stub_glue_init_breakin(void)
{
  rtems_raw_irq_connect_data uart_raw_irq_data;

  assert(uart_current == BSP_UART_COM1 || uart_current == BSP_UART_COM2);

  if(uart_current == BSP_UART_COM1)
    {
      uart_raw_irq_data.idtIndex = BSP_UART_COM1_IRQ + BSP_IRQ_VECTOR_BASE;
    }
  else
    {
      uart_raw_irq_data.idtIndex = BSP_UART_COM2_IRQ + BSP_IRQ_VECTOR_BASE;
    }

  if(!i386_get_current_idt_entry(&uart_raw_irq_data))
    {
      printk("cannot get idt entry\n");
      rtems_fatal_error_occurred(1);
    }

  if(!i386_delete_idt_entry(&uart_raw_irq_data))
    {
      printk("cannot delete idt entry\n");
      rtems_fatal_error_occurred(1);
    }

  uart_raw_irq_data.on  = BSP_uart_on;
  uart_raw_irq_data.off = BSP_uart_off;
  uart_raw_irq_data.isOn= BSP_uart_isOn;

  /* Install ISR  */
  if(uart_current == BSP_UART_COM1)
    {
      uart_raw_irq_data.idtIndex = BSP_UART_COM1_IRQ + BSP_IRQ_VECTOR_BASE;
      uart_raw_irq_data.hdl = BSP_uart_dbgisr_com1;
    }
  else
    {
      uart_raw_irq_data.idtIndex = BSP_UART_COM2_IRQ + BSP_IRQ_VECTOR_BASE;
      uart_raw_irq_data.hdl = BSP_uart_dbgisr_com2;
    }

  if (!i386_set_idt_entry (&uart_raw_irq_data))
    {
      printk("raw exception handler connection failed\n");
      rtems_fatal_error_occurred(1);
    }

  /* Enable interrupts */
  BSP_uart_intr_ctrl(uart_current, BSP_UART_INTR_CTRL_GDB);

  return;
}

int
putDebugChar(int ch)
{
  assert(uart_current == BSP_UART_COM1 || uart_current == BSP_UART_COM2);

  BSP_uart_polled_write(uart_current, ch);

  return 1;
}

int getDebugChar(void)
{
  int val;

  assert(uart_current == BSP_UART_COM1 || uart_current == BSP_UART_COM2);

  val = BSP_uart_polled_read(uart_current);

  return val;
}

void exceptionHandler(int vector, void (*handler)(void))
{
  rtems_raw_irq_connect_data excep_raw_irq_data;

  excep_raw_irq_data.idtIndex = vector;

  if(!i386_get_current_idt_entry(&excep_raw_irq_data))
    {
      printk("cannot get idt entry\n");
      rtems_fatal_error_occurred(1);
    }

  if(!i386_delete_idt_entry(&excep_raw_irq_data))
    {
      printk("cannot delete idt entry\n");
      rtems_fatal_error_occurred(1);
    }

  excep_raw_irq_data.on = nop;
  excep_raw_irq_data.off = nop;
  excep_raw_irq_data.isOn = isOn;
  excep_raw_irq_data.hdl = handler;

  if (!i386_set_idt_entry (&excep_raw_irq_data)) {
      printk("raw exception handler connection failed\n");
      rtems_fatal_error_occurred(1);
    }
  return;
}