aboutsummaryrefslogtreecommitdiffstats
path: root/tools/ioemu/iodev/unmapped.cc
blob: 5c7aafedb1b66dade781b05220789c2828be9395 (plain)
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
295
296
297
298
299
300
301
302
303
304
305
/////////////////////////////////////////////////////////////////////////
// $Id: unmapped.cc,v 1.22 2003/08/10 17:19:49 akrisak Exp $
/////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2001  MandrakeSoft S.A.
//
//    MandrakeSoft S.A.
//    43, rue d'Aboukir
//    75002 Paris - France
//    http://www.linux-mandrake.com/
//    http://www.mandrakesoft.com/
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA



// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
// is used to know when we are exporting symbols and when we are importing.
#define BX_PLUGGABLE

#include "bochs.h"

#define LOG_THIS theUnmappedDevice->


bx_unmapped_c *theUnmappedDevice = NULL;

  int
libunmapped_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
{
  theUnmappedDevice = new bx_unmapped_c ();
  bx_devices.pluginUnmapped = theUnmappedDevice;
  BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theUnmappedDevice, BX_PLUGIN_UNMAPPED);
  return(0); // Success
}

  void
libunmapped_LTX_plugin_fini(void)
{
}

bx_unmapped_c::bx_unmapped_c(void)
{
  put("UNMP");
  settype(UNMAPLOG);
  s.port80 = 0x00;
  s.port8e = 0x00;
  s.shutdown = 0;
}

bx_unmapped_c::~bx_unmapped_c(void)
{
  // Nothing yet
}

  void
bx_unmapped_c::init(void)
{
  DEV_register_default_ioread_handler(this, read_handler, "Unmapped", 7);
  DEV_register_default_iowrite_handler(this, write_handler, "Unmapped", 7);
}

  void
bx_unmapped_c::reset(unsigned type)
{
}

  // static IO port read callback handler
  // redirects to non-static class handler to avoid virtual functions

  Bit32u
bx_unmapped_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
{
#if !BX_USE_UM_SMF
  bx_unmapped_c *class_ptr = (bx_unmapped_c *) this_ptr;

  return( class_ptr->read(address, io_len) );
}

  Bit32u
bx_unmapped_c::read(Bit32u address, unsigned io_len)
{
#else
  UNUSED(this_ptr);
#endif  // !BX_USE_UM_SMF
  UNUSED(io_len);

  Bit32u retval;

  // This function gets called for access to any IO ports which
  // are not mapped to any device handler.  Reads return 0

  if (address >= 0x02e0 && address <= 0x02ef) {
	retval = 0;
	goto return_from_read;
  }

  switch (address) {
    case 0x80:
	  retval = BX_UM_THIS s.port80;
	  break;
    case 0x8e:
	  retval = BX_UM_THIS s.port8e;
	  break;
#if BX_PORT_E9_HACK
    // Unused port on ISA - this can be used by the emulated code
    // to detect it is running inside Bochs and that the debugging
    // features are available (write 0xFF or something on unused
    // port 0x80, then read from 0xe9, if value is 0xe9, debug
    // output is available) (see write() for that) -- Andreas and Emmanuel
    case 0xe9:
	  retval = 0xe9;
	  break;
#endif
    case 0x03df:
	  retval = 0xffffffff;
      BX_DEBUG(("unsupported IO read from port %04x (CGA)", address));
      break;
    case 0x023a:
    case 0x02f8: /* UART */
    case 0x02f9: /* UART */
    case 0x02fb: /* UART */
    case 0x02fc: /* UART */
    case 0x02fd: /* UART */
    case 0x02ea:
    case 0x02eb:
    case 0x03e8:
    case 0x03e9:
    case 0x03ea:
    case 0x03eb:
    case 0x03ec:
    case 0x03ed:
    case 0x03f8: /* UART */
    case 0x03f9: /* UART */
    case 0x03fb: /* UART */
    case 0x03fc: /* UART */
    case 0x03fd: /* UART */
    case 0x17c6:
	  retval = 0xffffffff;
      BX_DEBUG(("unsupported IO read from port %04x", address));
      break;
    default:
	  retval = 0xffffffff;
    }

  return_from_read:
  if (bx_dbg.unsupported_io)
	  switch (io_len) {
	  case 1:
		  retval = (Bit8u)retval;
		  BX_DEBUG(("unmapped: 8-bit read from %04x = %02x", address, retval));
		  break;
	  case 2:
		  retval = (Bit16u)retval;
		  BX_DEBUG(("unmapped: 16-bit read from %04x = %04x", address, retval));
		  break;
	  case 4:
		  BX_DEBUG(("unmapped: 32-bit read from %04x = %08x", address, retval));
		  break;
	  default:
		  BX_DEBUG(("unmapped: %d-bit read from %04x = %x", io_len * 8, address, retval));
	  }
  return retval;
}


  // static IO port write callback handler
  // redirects to non-static class handler to avoid virtual functions

  void
bx_unmapped_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
{
#if !BX_USE_UM_SMF
  bx_unmapped_c *class_ptr = (bx_unmapped_c *) this_ptr;

  class_ptr->write(address, value, io_len);
}

  void
bx_unmapped_c::write(Bit32u address, Bit32u value, unsigned io_len)
{
#else
  UNUSED(this_ptr);
#endif  // !BX_USE_UM_SMF
  UNUSED(io_len);


  // This function gets called for access to any IO ports which
  // are not mapped to any device handler.  Writes to an unmapped
  // IO port are ignored.

// ???

  if (address >= 0x02e0 && address <= 0x02ef)
	goto return_from_write;

  switch (address) {
    case 0x80: // diagnostic test port to display progress of POST
      //BX_DEBUG(("Diagnostic port 80h: write = %02xh", (unsigned) value));
      BX_UM_THIS s.port80 = value;
      break;

    case 0x8e: // ???
      BX_UM_THIS s.port8e = value;
      break;

#if BX_PORT_E9_HACK
    // This port doesn't exist on normal ISA architecture. However,
    // we define a convention here, to display on the console of the
    // system running Bochs, anything that is written to it. The
    // idea is to provide debug output very early when writing
    // BIOS or OS code for example, without having to bother with
    // properly setting up a serial port or anything.
    //
    // Idea by Andreas Beck (andreas.beck@ggi-project.org)

    case 0xe9:
      putchar(value);
      fflush(stdout);
      break;
#endif

    case 0xed: // Dummy port used as I/O delay
	  break;
    case 0xee: // ???
	  break;

    case 0x2f2:
    case 0x2f3:
    case 0x2f4:
    case 0x2f5:
    case 0x2f6:
    case 0x2f7:
    case 0x3e8:
    case 0x3e9:
    case 0x3eb:
    case 0x3ec:
    case 0x3ed:
	    // BX_DEBUG(("unsupported IO write to port %04x of %02x",
	    // address, value));
      break;
    
    case 0x8900: // Shutdown port, could be moved in a PM device
                 // or a host <-> guest communication device 
      switch (value) {
        case 'S': if (BX_UM_THIS s.shutdown == 0) BX_UM_THIS s.shutdown = 1; break;
        case 'h': if (BX_UM_THIS s.shutdown == 1) BX_UM_THIS s.shutdown = 2; break;
        case 'u': if (BX_UM_THIS s.shutdown == 2) BX_UM_THIS s.shutdown = 3; break;
        case 't': if (BX_UM_THIS s.shutdown == 3) BX_UM_THIS s.shutdown = 4; break;
        case 'd': if (BX_UM_THIS s.shutdown == 4) BX_UM_THIS s.shutdown = 5; break;
        case 'o': if (BX_UM_THIS s.shutdown == 5) BX_UM_THIS s.shutdown = 6; break;
        case 'w': if (BX_UM_THIS s.shutdown == 6) BX_UM_THIS s.shutdown = 7; break;
        case 'n': if (BX_UM_THIS s.shutdown == 7) BX_UM_THIS s.shutdown = 8; break;
#if BX_DEBUGGER 
        // Very handy for debugging:
	// output 'D' to port 8900, and bochs quits to debugger
        case 'D': bx_debug_break (); break;
#endif
	default :  BX_UM_THIS s.shutdown = 0; break;
        }
      if (BX_UM_THIS s.shutdown == 8) {
        bx_user_quit = 1;
        LOG_THIS setonoff(LOGLEV_PANIC, ACT_FATAL);
        BX_PANIC(("Shutdown port: shutdown requested"));
        }
      break;

    case 0xfedc:
      bx_dbg.debugger = (value > 0);
		BX_DEBUG(( "DEBUGGER = %u", (unsigned) bx_dbg.debugger));
      break;

    default:
	    break;
    }
  return_from_write:
  if (bx_dbg.unsupported_io)
	  switch (io_len) {
	  case 1:
		  BX_INFO(("unmapped: 8-bit write to %04x = %02x", address, value));
		  break;
	  case 2:
		  BX_INFO(("unmapped: 16-bit write to %04x = %04x", address, value));
		  break;
	  case 4:
		  BX_INFO(("unmapped: 32-bit write to %04x = %08x", address, value));
		  break;
	  default:
		  BX_INFO(("unmapped: %d-bit write to %04x = %x", io_len * 8, address, value));
		  break;
	  }
}