summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halr96b/mips/jxreturn.c
blob: d77d5642bd0d4988376f339cc574e739fdd2fb2a (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
// #pragma comment(exestr, "@(#) jxreturn.c 1.1 95/09/28 15:40:17 nec")
/*++

Copyright (c) 1991  Microsoft Corporation

Module Name:

    jxreturn.c

Abstract:

    This module implements the HAL return to firmware function.

Author:

    David N. Cutler (davec) 21-Aug-1991

Revision History:

    H000 Tue Apr 25 16:02:05 1995	kbnes!kisimoto
         -add Powerdown if argument value indicates
              HalPowerDownRoutine
    S001 kuriyama@oa2.kb.nec.co.jp Sun May 21 18:32:55 JST 1995
	 -compile error clear
    S002 kuriyama@oa2.kb.nec.co.jp Sun May 21 20:19:48 JST 1995
	 - powoff bug? fixed
    H003 Sat Aug 12 19:33:45 1995	kbnes!kisimoto
         - Removed _J94C_ definitions.
         _J94C_ definition indicates that the status of the
         dump switch can acknowledge from Self-test register.

    M004 kuriyama@oa2.kb.nec.co.jp Wed Aug 23 19:28:35 JST 1995
         - add for x86bios emurator support
--*/
#include "halp.h"
#define HEADER_FILE
#include "kxmips.h"

//
// Define keyboard registers structure.
//

typedef struct _KBD_REGISTERS {
    union {
        UCHAR Output;
        UCHAR Input;
    } Data;

    union {
        UCHAR Status;
        UCHAR Command;
    } Control;
} KBD_REGISTERS;

#define KBD_IBF_MASK 2                  // input buffer full mask

#define KbdGetStatus() (READ_REGISTER_UCHAR(&KbdBase->Control.Status))
#define KbdStoreCommand(Byte) WRITE_REGISTER_UCHAR(&KbdBase->Control.Command, Byte)
#define KbdStoreData(Byte) WRITE_REGISTER_UCHAR(&KbdBase->Data.Input, Byte)
#define KbdGetData() (READ_REGISTER_UCHAR(&KbdBase->Data.Output))

VOID
HalReturnToFirmware(
    IN FIRMWARE_REENTRY Routine
    )

/*++

Routine Description:

    This function returns control to the specified firmware routine.
    In most cases it generates a soft reset by asserting the reset line
    trough the keyboard controller.
    The Keyboard controller is mapped using the same virtual address
    and the same fixed entry as the DMA.

Arguments:

    Routine - Supplies a value indicating which firmware routine to invoke.

Return Value:

    Does not return.

--*/

{

    KIRQL OldIrql;
    ENTRYLO Pte[2];
    ULONG Index; // A001
    volatile KBD_REGISTERS * KbdBase = (KBD_REGISTERS *)DMA_VIRTUAL_BASE;
    ULONG Eax,Ebx,Ecx,Edx,Esi,Edi,Ebp; //S004

    //
    // Disable Interrupts.
    //

    KeRaiseIrql(HIGH_LEVEL, &OldIrql);

    //
    // Case on the type of return.
    //

    switch (Routine) {
    case HalHaltRoutine:

        //
        // Hang looping.
        //

        for (;;) {
        }

    case HalPowerDownRoutine:

#if defined (_MRCPOWER_)

	//
	// S004
        // Reset ISA Display Adapter to 80x25 color text mode.
        //

	Eax = 0x12;		// AH = 0    AL = 0x12
	HalCallBios(0x10, &Eax,&Ebx,&Ecx,&Edx,&Esi,&Edi,&Ebp);

        //
        // H000,S001
        // Powerdown the machine
        //

        //
        // Map the MRC
        //

        Pte[0].PFN = MRC_TEMP_PHYSICAL_BASE >> PAGE_SHIFT;

        Pte[0].G = 1;
        Pte[0].V = 1;
        Pte[0].D = 1;

    #if defined(R3000)

        Pte[0].N = 1;

    #endif

    #if defined(R4000)

        //
        // set second page to global and not valid.
        //

        Pte[0].C = UNCACHED_POLICY;
        Pte[1].G = 1;
        Pte[1].V = 0;

    #endif

        //
        // Map MRC using virtual address of DMA controller.
        //

        KeFillFixedEntryTb((PHARDWARE_PTE)&Pte[0],
                           (PVOID)DMA_VIRTUAL_BASE,
                           DMA_ENTRY);

        //
        // Send Powerdown Command to the MRC.
        //


        for (;;) { // S002
               WRITE_REGISTER_UCHAR(
                    &MRC_CONTROL->SoftwarePowerOff,
                    0x1
                    );
        }

        for (;;) {
        }
#endif //_MRCPOWER_

    case HalRestartRoutine:
    case HalRebootRoutine:
    case HalInteractiveModeRoutine:

        //
	// S004
        // Reset ISA Display Adapter to 80x25 color text mode.
        //

	Eax = 0x12;		// AH = 0    AL = 0x12
	HalCallBios(0x10, &Eax,&Ebx,&Ecx,&Edx,&Esi,&Edi,&Ebp);

        //
        // Map the keyboard controller
        //

        Pte[0].PFN = KEYBOARD_PHYSICAL_BASE >> PAGE_SHIFT;
        Pte[0].G = 1;
        Pte[0].V = 1;
        Pte[0].D = 1;

    #if defined(R3000)

        Pte[0].N = 1;

    #endif

    #if defined(R4000)

        //
        // set second page to global and not valid.
        //

        Pte[0].C = UNCACHED_POLICY;
        Pte[1].G = 1;
        Pte[1].V = 0;

    #endif

        //
        // Map keyboard controller using virtual address of DMA controller.
        //

        KeFillFixedEntryTb((PHARDWARE_PTE)&Pte[0],
                           (PVOID)DMA_VIRTUAL_BASE,
                           DMA_ENTRY);

        //
        // Send WriteOutputBuffer Command to the controller.
        //

        while ((KbdGetStatus() & KBD_IBF_MASK) != 0) {
        }

        KbdStoreCommand(0xD1);

        //
        // Write a zero to the output buffer. Causes reset line to be asserted.
        //

        while ((KbdGetStatus() & KBD_IBF_MASK) != 0) {
        }

        KbdStoreData(0);
        for (;;) {
        }

    default:
        KdPrint(("HalReturnToFirmware invalid argument\n"));
        KeLowerIrql(OldIrql);
        DbgBreakPoint();
    }
}