1 /////////////////////////////////////////////////////////////////////////
2 // $Id: biosdev.cc,v 1.14 2008/07/26 08:02:27 vruppert Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (C) 2002 MandrakeSoft S.A.
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 // Here are the virtual ports use to display messages from the bioses :
30 // 0x0400 : rombios Panic port with line number
31 // 0x0401 : rombios Panic port with message, panic flag or line number
32 // 0x0402 : rombios Info port with message
33 // 0x0403 : rombios Debug port with message
35 // 0x0500 : vgabios Info port with message
36 // 0x0501 : vgabios Panic port with line number
37 // 0x0502 : vgabios Panic port with message, panic flag or line number
38 // 0x0503 : vgabios Debug port with message
41 // Define BX_PLUGGABLE in files that can be compiled into plugins. For
42 // platforms that require a special tag on exported symbols, BX_PLUGGABLE
43 // is used to know when we are exporting symbols and when we are importing.
48 bx_biosdev_c
*theBiosDevice
= NULL
;
50 logfunctions
*bioslog
;
51 logfunctions
*vgabioslog
;
53 int libbiosdev_LTX_plugin_init(plugin_t
*plugin
, plugintype_t type
, int argc
, char *argv
[])
55 theBiosDevice
= new bx_biosdev_c();
56 BX_REGISTER_DEVICE_DEVMODEL(plugin
, type
, theBiosDevice
, BX_PLUGIN_BIOSDEV
);
60 void libbiosdev_LTX_plugin_fini(void)
65 bx_biosdev_c::bx_biosdev_c(void)
67 bioslog
= new logfunctions();
69 bioslog
->settype(BIOSLOG
);
71 vgabioslog
= new logfunctions();
72 vgabioslog
->put("VBIOS");
73 vgabioslog
->settype(BIOSLOG
);
76 bx_biosdev_c::~bx_biosdev_c(void)
78 bioslog
->ldebug("Exit");
79 if (bioslog
!= NULL
) {
83 if (vgabioslog
!= NULL
) {
89 void bx_biosdev_c::init(void)
91 DEV_register_iowrite_handler(this, write_handler
, 0x0400, "Bios Panic Port 1", 3);
92 DEV_register_iowrite_handler(this, write_handler
, 0x0401, "Bios Panic Port 2", 3);
93 DEV_register_iowrite_handler(this, write_handler
, 0x0402, "Bios Info Port", 1);
94 DEV_register_iowrite_handler(this, write_handler
, 0x0403, "Bios Debug Port", 1);
96 DEV_register_iowrite_handler(this, write_handler
, 0x0500, "VGABios Info Port", 1);
97 DEV_register_iowrite_handler(this, write_handler
, 0x0501, "VGABios Panic Port 1", 3);
98 DEV_register_iowrite_handler(this, write_handler
, 0x0502, "VGABios Panic Port 2", 3);
99 DEV_register_iowrite_handler(this, write_handler
, 0x0503, "VGABios Debug Port", 1);
101 s
.bios_message_i
= 0;
102 s
.bios_panic_flag
= 0;
103 s
.vgabios_message_i
= 0;
104 s
.vgabios_panic_flag
= 0;
107 // static IO port write callback handler
108 // redirects to non-static class handler to avoid virtual functions
110 void bx_biosdev_c::write_handler(void *this_ptr
, Bit32u address
, Bit32u value
, unsigned io_len
)
113 bx_biosdev_c
*class_ptr
= (bx_biosdev_c
*) this_ptr
;
115 class_ptr
->write(address
, value
, io_len
);
118 void bx_biosdev_c::write(Bit32u address
, Bit32u value
, unsigned io_len
)
122 #endif // !BX_USE_BIOS_SMF
127 // 0x400-0x401 are used as panic ports for the rombios
130 // The next message sent to the info port will cause a panic
131 BX_BIOS_THIS s
.bios_panic_flag
= 1;
133 } else if (BX_BIOS_THIS s
.bios_message_i
> 0) {
134 // if there are bits of message in the buffer, print them as the
135 // panic message. Otherwise fall into the next case.
136 if (BX_BIOS_THIS s
.bios_message_i
>= BX_BIOS_MESSAGE_SIZE
)
137 BX_BIOS_THIS s
.bios_message_i
= BX_BIOS_MESSAGE_SIZE
-1;
138 BX_BIOS_THIS s
.bios_message
[ BX_BIOS_THIS s
.bios_message_i
] = 0;
139 BX_BIOS_THIS s
.bios_message_i
= 0;
140 bioslog
->panic("%s", BX_BIOS_THIS s
.bios_message
);
145 bioslog
->panic("BIOS panic at rombios.c, line %d", value
);
149 // 0x0402 is used as the info port for the rombios
150 // 0x0403 is used as the debug port for the rombios
153 BX_BIOS_THIS s
.bios_message
[BX_BIOS_THIS s
.bios_message_i
] =
155 BX_BIOS_THIS s
.bios_message_i
++;
156 if (BX_BIOS_THIS s
.bios_message_i
>= BX_BIOS_MESSAGE_SIZE
) {
157 BX_BIOS_THIS s
.bios_message
[ BX_BIOS_MESSAGE_SIZE
- 1] = 0;
158 BX_BIOS_THIS s
.bios_message_i
= 0;
160 bioslog
->ldebug("%s", BX_BIOS_THIS s
.bios_message
);
162 bioslog
->info("%s", BX_BIOS_THIS s
.bios_message
);
163 } else if ((value
& 0xff) == '\n') {
164 BX_BIOS_THIS s
.bios_message
[ BX_BIOS_THIS s
.bios_message_i
- 1 ] = 0;
165 BX_BIOS_THIS s
.bios_message_i
= 0;
166 if (BX_BIOS_THIS s
.bios_panic_flag
==1)
167 bioslog
->panic("%s", BX_BIOS_THIS s
.bios_message
);
168 else if (address
==0x403)
169 bioslog
->ldebug("%s", BX_BIOS_THIS s
.bios_message
);
171 bioslog
->info("%s", BX_BIOS_THIS s
.bios_message
);
172 BX_BIOS_THIS s
.bios_panic_flag
= 0;
176 // 0x501-0x502 are used as panic ports for the vgabios
179 BX_BIOS_THIS s
.vgabios_panic_flag
= 1;
181 } else if (BX_BIOS_THIS s
.vgabios_message_i
> 0) {
182 // if there are bits of message in the buffer, print them as the
183 // panic message. Otherwise fall into the next case.
184 if (BX_BIOS_THIS s
.vgabios_message_i
>= BX_BIOS_MESSAGE_SIZE
)
185 BX_BIOS_THIS s
.vgabios_message_i
= BX_BIOS_MESSAGE_SIZE
-1;
186 BX_BIOS_THIS s
.vgabios_message
[ BX_BIOS_THIS s
.vgabios_message_i
] = 0;
187 BX_BIOS_THIS s
.vgabios_message_i
= 0;
188 vgabioslog
->panic("%s", BX_BIOS_THIS s
.vgabios_message
);
193 vgabioslog
->panic("VGABIOS panic at vgabios.c, line %d", value
);
197 // 0x0500 is used as the message port for the vgabios
200 BX_BIOS_THIS s
.vgabios_message
[BX_BIOS_THIS s
.vgabios_message_i
] =
202 BX_BIOS_THIS s
.vgabios_message_i
++;
203 if (BX_BIOS_THIS s
.vgabios_message_i
>= BX_BIOS_MESSAGE_SIZE
) {
204 BX_BIOS_THIS s
.vgabios_message
[ BX_BIOS_MESSAGE_SIZE
- 1] = 0;
205 BX_BIOS_THIS s
.vgabios_message_i
= 0;
207 vgabioslog
->ldebug("%s", BX_BIOS_THIS s
.vgabios_message
);
209 vgabioslog
->info("%s", BX_BIOS_THIS s
.vgabios_message
);
210 } else if ((value
& 0xff) == '\n') {
211 BX_BIOS_THIS s
.vgabios_message
[ BX_BIOS_THIS s
.vgabios_message_i
- 1 ] = 0;
212 BX_BIOS_THIS s
.vgabios_message_i
= 0;
213 if (BX_BIOS_THIS s
.vgabios_panic_flag
==1)
214 vgabioslog
->panic("%s", BX_BIOS_THIS s
.vgabios_message
);
215 else if (address
==0x503)
216 vgabioslog
->ldebug("%s", BX_BIOS_THIS s
.vgabios_message
);
218 vgabioslog
->info("%s", BX_BIOS_THIS s
.vgabios_message
);
219 BX_BIOS_THIS s
.vgabios_panic_flag
= 0;