Import upstream u-boot 1.1.4
[u-boot.git] / board / MAI / bios_emulator / scitech / src / pm / qnx / mtrrqnx.c
1 /****************************************************************************
2 *
3 *                   SciTech OS Portability Manager Library
4 *
5 *  ========================================================================
6 *
7 *    The contents of this file are subject to the SciTech MGL Public
8 *    License Version 1.0 (the "License"); you may not use this file
9 *    except in compliance with the License. You may obtain a copy of
10 *    the License at http://www.scitechsoft.com/mgl-license.txt
11 *
12 *    Software distributed under the License is distributed on an
13 *    "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 *    implied. See the License for the specific language governing
15 *    rights and limitations under the License.
16 *
17 *    The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
18 *
19 *    The Initial Developer of the Original Code is SciTech Software, Inc.
20 *    All Rights Reserved.
21 *
22 *  ========================================================================
23 *
24 * Language:     ANSI C
25 * Environment:  QNX
26 *
27 * Description:  MTRR helper functions module. To make it easier to implement
28 *               the MTRR support under QNX, we simply put our ring 0 helper
29 *               functions into stubs that run them at ring 0 using whatever
30 *               mechanism is available.
31 *
32 ****************************************************************************/
33
34 #include "pmapi.h"
35 #include <stdio.h>
36 #include <sys/mman.h>
37 #include <time.h>
38 #ifdef __QNXNTO__
39 #include <sys/neutrino.h>
40 #include <sys/syspage.h>
41 #else
42 #include <i86.h>
43 #include <sys/irqinfo.h>
44 #endif
45
46 /*--------------------------- Global variables ----------------------------*/
47
48 #define R0_FLUSH_TLB    0
49 #define R0_SAVE_CR4     1
50 #define R0_RESTORE_CR4  2
51 #define R0_READ_MSR     3
52 #define R0_WRITE_MSR    4
53
54 typedef struct {
55     int     service;
56     int     reg;
57     ulong   eax;
58     ulong   edx;
59     } R0_data;
60
61 extern volatile R0_data _PM_R0;
62
63 /*----------------------------- Implementation ----------------------------*/
64
65 #ifdef __QNXNTO__
66 const struct sigevent * _ASMAPI _PM_ring0_isr(void *arg, int id);
67 #else
68 pid_t far _ASMAPI _PM_ring0_isr();
69 #endif
70
71 /****************************************************************************
72 REMARKS:
73 Return true if ring 0 (or if we can call the helpers functions at ring 0)
74 ****************************************************************************/
75 ibool _ASMAPI _MTRR_isRing0(void)
76 {
77 #ifdef __QNXNTO__
78     return false;   /* Not implemented yet! */
79 #else
80     return true;
81 #endif
82 }
83
84 /****************************************************************************
85 REMARKS:
86 Function to execute a service at ring 0. This is done using the clock
87 interrupt handler since the code we attach to it will always run at ring 0.
88 ****************************************************************************/
89 static void CallRing0(void)
90 {
91 #ifdef __QNXNTO__
92     uint    clock_intno = SYSPAGE_ENTRY(qtime)->intr;
93 #else
94     uint    clock_intno = 0;    /* clock irq */
95 #endif
96     int     intrid;
97
98 #ifdef __QNXNTO__
99     mlock((void*)&_PM_R0, sizeof(_PM_R0));
100     ThreadCtl(_NTO_TCTL_IO, 0);
101 #endif
102 #ifdef __QNXNTO__
103     if ((intrid = InterruptAttach(_NTO_INTR_CLASS_EXTERNAL | clock_intno,
104         _PM_ring0_isr, (void*)&_PM_R0, sizeof(_PM_R0), _NTO_INTR_FLAGS_END)) == -1) {
105 #else
106     if ((intrid = qnx_hint_attach(clock_intno, _PM_ring0_isr, FP_SEG(&_PM_R0))) == -1) {
107 #endif
108         perror("Attach");
109         exit(-1);
110         }
111     while (_PM_R0.service != -1)
112         ;
113 #ifdef __QNXNTO__
114     InterruptDetachId(intrid);
115 #else
116     qnx_hint_detach(intrid);
117 #endif
118 }
119
120 /****************************************************************************
121 REMARKS:
122 Flush the translation lookaside buffer.
123 ****************************************************************************/
124 void PMAPI PM_flushTLB(void)
125 {
126     _PM_R0.service = R0_FLUSH_TLB;
127     CallRing0();
128 }
129
130 /****************************************************************************
131 REMARKS:
132 Read and return the value of the CR4 register
133 ****************************************************************************/
134 ulong _ASMAPI _MTRR_saveCR4(void)
135 {
136     _PM_R0.service = R0_SAVE_CR4;
137     CallRing0();
138     return _PM_R0.reg;
139 }
140
141 /****************************************************************************
142 REMARKS:
143 Restore the value of the CR4 register
144 ****************************************************************************/
145 void _ASMAPI _MTRR_restoreCR4(ulong cr4Val)
146 {
147     _PM_R0.service = R0_RESTORE_CR4;
148     _PM_R0.reg = cr4Val;
149     CallRing0();
150 }
151
152 /****************************************************************************
153 REMARKS:
154 Read a machine status register for the CPU.
155 ****************************************************************************/
156 void _ASMAPI _MTRR_readMSR(
157     int reg,
158     ulong *eax,
159     ulong *edx)
160 {
161     _PM_R0.service = R0_READ_MSR;
162     _PM_R0.reg = reg;
163     CallRing0();
164     *eax = _PM_R0.eax;
165     *edx = _PM_R0.edx;
166 }
167
168 /****************************************************************************
169 REMARKS:
170 Write a machine status register for the CPU.
171 ****************************************************************************/
172 void _ASMAPI _MTRR_writeMSR(
173     int reg,
174     ulong eax,
175     ulong edx)
176 {
177     _PM_R0.service = R0_WRITE_MSR;
178     _PM_R0.reg = reg;
179     _PM_R0.eax = eax;
180     _PM_R0.edx = edx;
181     CallRing0();
182 }