summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halsgi/mips/sxport.c
blob: 57814824de6739e4108ddf7678faa1f4cb1dc390 (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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
/*++

Copyright (c) 1991  Microsoft Corporation
Copyright (c) 1992  Silicon Graphics, Inc.

Module Name:

    s3port.c

Abstract:

    This module implements the code that provides communication between
    the kernel debugger on SGI's Indigo system and the host system.

Author:

    David N. Cutler (davec) 28-Apr-1991
    Kevin Meier (o-kevinm) 20-Jan-1992

Environment:

    Kernel mode

Revision History:

--*/

#include "halp.h"
#define HEADER_FILE
#include "kxmips.h"

// BUGBUG put these in a header file!!!
// Defines from sgikbmou.h for the z8530
//
#define DBGPORT_BASE           0xbfb80d10

#define DBGPORT_CTRL       DBGPORT_BASE
#define DBGPORT_DATA       (DBGPORT_BASE+4)

#define  RR0_TX_EMPTY      0x04  /* Tx buffer empty */
#define  RR0_RX_CHR     0x01  /* Rx character available */

#define  RR1_FRAMING_ERR      0x40  /* framing error */
#define  RR1_RX_ORUN_ERR      0x20  /* Rx overrun */
#define  RR1_PARITY_ERR    0x10  /* parity error */

#define  WR0_RST_ERR    0x30  /* reset error (bits in RR1) */

#define  RR1         1  /* Rx condition status/residue codes */
#define  WR12        12
#define  WR13        13
#define  WR14        14
#define  WR14_BRG_ENBL     0x01

#define Z8530_DELAY             KeStallExecutionProcessor(1)
#define BRATE        19200
#define  CLK_SPEED      3672000
#define  CLK_FACTOR     16
#define WR_CNTRL(p, r, v)  {Z8530_DELAY;  \
            WRITE_REGISTER_ULONG((p), (ULONG)(r)); \
            Z8530_DELAY;   \
                 WRITE_REGISTER_ULONG((p), (ULONG)(v));}

#define TIMEOUT_COUNT 1024*512

//
// BUGBUG For now, the kernel debugger will use this variable to
// port to the debugger port it is using.
//
PUCHAR KdComPortInUse = NULL;

BOOLEAN
KdPortInitialize (
    PDEBUG_PARAMETERS DebugParameters,
    PLOADER_PARAMETER_BLOCK LoaderBlock,
    BOOLEAN Initialize
    )
{
    ULONG baud =
   (CLK_SPEED + BRATE * CLK_FACTOR) / (BRATE * CLK_FACTOR * 2) - 2;


    //
    // If the debugger is not being enabled, then return. There is no
    // need to capture any parameters.
    //

    if (Initialize == FALSE) {
        return(TRUE);
    }

    //
    // BUGBUG For now, simply save the physical base of the
    // uart being used for debugging.  The serial driver will
    // use this to prevent itself from using the UART.
    //
    KdComPortInUse = (PUCHAR)DBGPORT_CTRL;

    // The prom has already initialized the port, simply set the baud
    // rate to 19200.
    //
    WR_CNTRL(DBGPORT_CTRL, WR14, 0x00)
    WR_CNTRL(DBGPORT_CTRL, WR12, baud & 0xff)
    WR_CNTRL(DBGPORT_CTRL, WR13, (baud >> 8) & 0xff)
    WR_CNTRL(DBGPORT_CTRL, WR14, WR14_BRG_ENBL)

    return TRUE;
}

ULONG
HalpGetByte (
    IN PCHAR Input,
    IN BOOLEAN Wait
    )

/*++

Routine Description:

    This routine gets a byte from the serial port used by the kernel
    debugger.

Arguments:

    Input - Supplies a pointer to a variable that receives the input
        data byte.

    Wait - Supplies a boolean value that detemines whether a timeout
        is applied to the input operation.

Return Value:

    CP_GET_SUCCESS is returned if a byte is successfully read from the
        kernel debugger line.

    CP_GET_ERROR is returned if an error is encountered during reading.

    CP_GET_NODATA is returned if timeout occurs.

--*/

{
    ULONG TimeoutCount;

    //
    // Attempt to read a byte from the debugger port until a byte is
    // available or until a timeout occurs.
    //

    TimeoutCount = Wait ? TIMEOUT_COUNT : 1;
    do {
        TimeoutCount -= 1;

        //
        // Wait until data is available in the receive buffer.
        //

        KeStallExecutionProcessor(1);
        if (!(READ_REGISTER_ULONG(DBGPORT_CTRL) & RR0_RX_CHR))
            continue;

        //
        // Read input byte and store in callers buffer.
        //
	WRITE_REGISTER_ULONG(DBGPORT_CTRL, RR1);
	if((READ_REGISTER_ULONG(DBGPORT_CTRL) &
		(RR1_RX_ORUN_ERR | RR1_FRAMING_ERR | RR1_PARITY_ERR))) {
	    WRITE_REGISTER_ULONG(DBGPORT_CTRL, WR0_RST_ERR);
            return CP_GET_ERROR;
	} else {
	    *Input = (UCHAR)(READ_REGISTER_ULONG(DBGPORT_DATA));
	}

        return CP_GET_SUCCESS;
    } while(TimeoutCount != 0);

    return CP_GET_NODATA;
}

ULONG
KdPortGetByte (
    OUT PUCHAR Input
    )

/*++

Routine Description:

    This routine gets a byte from the serial port used by the kernel
    debugger.

    N.B. It is assumed that the IRQL has been raised to the highest
        level, and necessary multiprocessor synchronization has been
        performed before this routine is called.

Arguments:

    Input - Supplies a pointer to a variable that receives the input
        data byte.

Return Value:

    CP_GET_SUCCESS is returned if a byte is successfully read from the
        kernel debugger line.

    CP_GET_ERROR is returned if an error is encountered during reading.

    CP_GET_NODATA is returned if timeout occurs.

--*/

{

    return HalpGetByte(Input, TRUE);
}

ULONG
KdPortPollByte (
    OUT PUCHAR Input
    )

/*++

Routine Description:

    This routine gets a byte from the serial port used by the kernel
    debugger iff a byte is available.

    N.B. It is assumed that the IRQL has been raised to the highest
        level, and necessary multiprocessor synchronization has been
        performed before this routine is called.

Arguments:

    Input - Supplies a pointer to a variable that receives the input
        data byte.

Return Value:

    CP_GET_SUCCESS is returned if a byte is successfully read from the
        kernel debugger line.

    CP_GET_ERROR is returned if an error encountered during reading.

    CP_GET_NODATA is returned if timeout occurs.

--*/

{

    ULONG Status;

    //
    // Save port status, map the serial controller, get byte from the
    // debugger port is one is avaliable, restore port status, unmap
    // the serial controller, and return the operation status.
    //

    KdPortSave();
    Status = HalpGetByte(Input, FALSE);
    KdPortRestore();
    return Status;
}

VOID
KdPortPutByte (IN UCHAR Output)
{
    // Wait for the transmit buffer to empty, and write the char.
    //
    while(!(READ_REGISTER_ULONG(DBGPORT_CTRL) & RR0_TX_EMPTY))
   ;  // empty
    WRITE_REGISTER_ULONG(DBGPORT_DATA,(ULONG)Output);
    return;
}

VOID
KdPortRestore (VOID)
{
    return;
}

VOID
KdPortSave (VOID)
{
    return;
}

#ifdef DBG
VOID
SgiPortPuts(IN PCHAR pString)
{
    for(; *pString; KdPortPutByte((UCHAR)*pString), ++pString );
}
#endif