besys.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /****************************************************************************
  2. *
  3. * BIOS emulator and interface
  4. * to Realmode X86 Emulator Library
  5. *
  6. * Copyright (C) 1996-1999 SciTech Software, Inc.
  7. *
  8. * ========================================================================
  9. *
  10. * Permission to use, copy, modify, distribute, and sell this software and
  11. * its documentation for any purpose is hereby granted without fee,
  12. * provided that the above copyright notice appear in all copies and that
  13. * both that copyright notice and this permission notice appear in
  14. * supporting documentation, and that the name of the authors not be used
  15. * in advertising or publicity pertaining to distribution of the software
  16. * without specific, written prior permission. The authors makes no
  17. * representations about the suitability of this software for any purpose.
  18. * It is provided "as is" without express or implied warranty.
  19. *
  20. * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  21. * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  22. * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  23. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  24. * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  25. * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  26. * PERFORMANCE OF THIS SOFTWARE.
  27. *
  28. * ========================================================================
  29. *
  30. * Language: ANSI C
  31. * Environment: Any
  32. * Developer: Kendall Bennett
  33. *
  34. * Description: This file includes BIOS emulator I/O and memory access
  35. * functions.
  36. *
  37. ****************************************************************************/
  38. #include "biosemui.h"
  39. /*------------------------------- Macros ----------------------------------*/
  40. /* Macros to read and write values to x86 bus memory. Replace these as
  41. * necessary if you need to do something special to access memory over
  42. * the bus on a particular processor family.
  43. */
  44. #define readb(base,off) *((u8*)((u32)(base) + (off)))
  45. #define readw(base,off) *((u16*)((u32)(base) + (off)))
  46. #define readl(base,off) *((u32*)((u32)(base) + (off)))
  47. #define writeb(v,base,off) *((u8*)((u32)(base) + (off))) = (v)
  48. #define writew(v,base,off) *((u16*)((u32)(base) + (off))) = (v)
  49. #define writel(v,base,off) *((u32*)((u32)(base) + (off))) = (v)
  50. /*----------------------------- Implementation ----------------------------*/
  51. #ifdef DEBUG
  52. # define DEBUG_MEM() (M.x86.debug & DEBUG_MEM_TRACE_F)
  53. #else
  54. # define DEBUG_MEM()
  55. #endif
  56. /****************************************************************************
  57. PARAMETERS:
  58. addr - Emulator memory address to read
  59. RETURNS:
  60. Byte value read from emulator memory.
  61. REMARKS:
  62. Reads a byte value from the emulator memory. We have three distinct memory
  63. regions that are handled differently, which this function handles.
  64. ****************************************************************************/
  65. u8 X86API BE_rdb(
  66. u32 addr)
  67. {
  68. u8 val = 0;
  69. if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
  70. val = *(u8*)(_BE_env.biosmem_base + addr - 0xC0000);
  71. }
  72. else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
  73. val = readb(_BE_env.busmem_base, addr - 0xA0000);
  74. }
  75. else if (addr > M.mem_size - 1) {
  76. DB( printk("mem_read: address %#lx out of range!\n", addr);)
  77. HALT_SYS();
  78. }
  79. else {
  80. val = *(u8*)(M.mem_base + addr);
  81. }
  82. DB( if (DEBUG_MEM())
  83. printk("%#08x 1 -> %#x\n", addr, val);)
  84. return val;
  85. }
  86. /****************************************************************************
  87. PARAMETERS:
  88. addr - Emulator memory address to read
  89. RETURNS:
  90. Word value read from emulator memory.
  91. REMARKS:
  92. Reads a word value from the emulator memory. We have three distinct memory
  93. regions that are handled differently, which this function handles.
  94. ****************************************************************************/
  95. u16 X86API BE_rdw(
  96. u32 addr)
  97. {
  98. u16 val = 0;
  99. if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
  100. #ifdef __BIG_ENDIAN__
  101. if (addr & 0x1) {
  102. addr -= 0xC0000;
  103. val = ( *(u8*)(_BE_env.biosmem_base + addr) |
  104. (*(u8*)(_BE_env.biosmem_base + addr + 1) << 8));
  105. }
  106. else
  107. #endif
  108. val = *(u16*)(_BE_env.biosmem_base + addr - 0xC0000);
  109. }
  110. else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
  111. #ifdef __BIG_ENDIAN__
  112. if (addr & 0x1) {
  113. addr -= 0xA0000;
  114. val = ( readb(_BE_env.busmem_base, addr) |
  115. (readb(_BE_env.busmem_base, addr + 1) << 8));
  116. }
  117. else
  118. #endif
  119. val = readw(_BE_env.busmem_base, addr - 0xA0000);
  120. }
  121. else if (addr > M.mem_size - 2) {
  122. DB( printk("mem_read: address %#lx out of range!\n", addr);)
  123. HALT_SYS();
  124. }
  125. else {
  126. #ifdef __BIG_ENDIAN__
  127. if (addr & 0x1) {
  128. val = ( *(u8*)(M.mem_base + addr) |
  129. (*(u8*)(M.mem_base + addr + 1) << 8));
  130. }
  131. else
  132. #endif
  133. val = *(u16*)(M.mem_base + addr);
  134. }
  135. DB( if (DEBUG_MEM())
  136. printk("%#08x 2 -> %#x\n", addr, val);)
  137. return val;
  138. }
  139. /****************************************************************************
  140. PARAMETERS:
  141. addr - Emulator memory address to read
  142. RETURNS:
  143. Long value read from emulator memory.
  144. REMARKS:
  145. Reads a long value from the emulator memory. We have three distinct memory
  146. regions that are handled differently, which this function handles.
  147. ****************************************************************************/
  148. u32 X86API BE_rdl(
  149. u32 addr)
  150. {
  151. u32 val = 0;
  152. if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
  153. #ifdef __BIG_ENDIAN__
  154. if (addr & 0x3) {
  155. addr -= 0xC0000;
  156. val = ( *(u8*)(_BE_env.biosmem_base + addr + 0) |
  157. (*(u8*)(_BE_env.biosmem_base + addr + 1) << 8) |
  158. (*(u8*)(_BE_env.biosmem_base + addr + 2) << 16) |
  159. (*(u8*)(_BE_env.biosmem_base + addr + 3) << 24));
  160. }
  161. else
  162. #endif
  163. val = *(u32*)(_BE_env.biosmem_base + addr - 0xC0000);
  164. }
  165. else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
  166. #ifdef __BIG_ENDIAN__
  167. if (addr & 0x3) {
  168. addr -= 0xA0000;
  169. val = ( readb(_BE_env.busmem_base, addr) |
  170. (readb(_BE_env.busmem_base, addr + 1) << 8) |
  171. (readb(_BE_env.busmem_base, addr + 2) << 16) |
  172. (readb(_BE_env.busmem_base, addr + 3) << 24));
  173. }
  174. else
  175. #endif
  176. val = readl(_BE_env.busmem_base, addr - 0xA0000);
  177. }
  178. else if (addr > M.mem_size - 4) {
  179. DB( printk("mem_read: address %#lx out of range!\n", addr);)
  180. HALT_SYS();
  181. }
  182. else {
  183. #ifdef __BIG_ENDIAN__
  184. if (addr & 0x3) {
  185. val = ( *(u8*)(M.mem_base + addr + 0) |
  186. (*(u8*)(M.mem_base + addr + 1) << 8) |
  187. (*(u8*)(M.mem_base + addr + 2) << 16) |
  188. (*(u8*)(M.mem_base + addr + 3) << 24));
  189. }
  190. else
  191. #endif
  192. val = *(u32*)(M.mem_base + addr);
  193. }
  194. DB( if (DEBUG_MEM())
  195. printk("%#08x 4 -> %#x\n", addr, val);)
  196. return val;
  197. }
  198. /****************************************************************************
  199. PARAMETERS:
  200. addr - Emulator memory address to read
  201. val - Value to store
  202. REMARKS:
  203. Writes a byte value to emulator memory. We have three distinct memory
  204. regions that are handled differently, which this function handles.
  205. ****************************************************************************/
  206. void X86API BE_wrb(
  207. u32 addr,
  208. u8 val)
  209. {
  210. DB( if (DEBUG_MEM())
  211. printk("%#08x 1 <- %#x\n", addr, val);)
  212. if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
  213. *(u8*)(_BE_env.biosmem_base + addr - 0xC0000) = val;
  214. }
  215. else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
  216. writeb(val, _BE_env.busmem_base, addr - 0xA0000);
  217. }
  218. else if (addr > M.mem_size-1) {
  219. DB( printk("mem_write: address %#lx out of range!\n", addr);)
  220. HALT_SYS();
  221. }
  222. else {
  223. *(u8*)(M.mem_base + addr) = val;
  224. }
  225. }
  226. /****************************************************************************
  227. PARAMETERS:
  228. addr - Emulator memory address to read
  229. val - Value to store
  230. REMARKS:
  231. Writes a word value to emulator memory. We have three distinct memory
  232. regions that are handled differently, which this function handles.
  233. ****************************************************************************/
  234. void X86API BE_wrw(
  235. u32 addr,
  236. u16 val)
  237. {
  238. DB( if (DEBUG_MEM())
  239. printk("%#08x 2 <- %#x\n", addr, val);)
  240. if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
  241. #ifdef __BIG_ENDIAN__
  242. if (addr & 0x1) {
  243. addr -= 0xC0000;
  244. *(u8*)(_BE_env.biosmem_base + addr + 0) = (val >> 0) & 0xff;
  245. *(u8*)(_BE_env.biosmem_base + addr + 1) = (val >> 8) & 0xff;
  246. }
  247. else
  248. #endif
  249. *(u16*)(_BE_env.biosmem_base + addr - 0xC0000) = val;
  250. }
  251. else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
  252. #ifdef __BIG_ENDIAN__
  253. if (addr & 0x1) {
  254. addr -= 0xA0000;
  255. writeb(val >> 0, _BE_env.busmem_base, addr);
  256. writeb(val >> 8, _BE_env.busmem_base, addr + 1);
  257. }
  258. else
  259. #endif
  260. writew(val, _BE_env.busmem_base, addr - 0xA0000);
  261. }
  262. else if (addr > M.mem_size-2) {
  263. DB( printk("mem_write: address %#lx out of range!\n", addr);)
  264. HALT_SYS();
  265. }
  266. else {
  267. #ifdef __BIG_ENDIAN__
  268. if (addr & 0x1) {
  269. *(u8*)(M.mem_base + addr + 0) = (val >> 0) & 0xff;
  270. *(u8*)(M.mem_base + addr + 1) = (val >> 8) & 0xff;
  271. }
  272. else
  273. #endif
  274. *(u16*)(M.mem_base + addr) = val;
  275. }
  276. }
  277. /****************************************************************************
  278. PARAMETERS:
  279. addr - Emulator memory address to read
  280. val - Value to store
  281. REMARKS:
  282. Writes a long value to emulator memory. We have three distinct memory
  283. regions that are handled differently, which this function handles.
  284. ****************************************************************************/
  285. void X86API BE_wrl(
  286. u32 addr,
  287. u32 val)
  288. {
  289. DB( if (DEBUG_MEM())
  290. printk("%#08x 4 <- %#x\n", addr, val);)
  291. if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
  292. #ifdef __BIG_ENDIAN__
  293. if (addr & 0x1) {
  294. addr -= 0xC0000;
  295. *(u8*)(M.mem_base + addr + 0) = (val >> 0) & 0xff;
  296. *(u8*)(M.mem_base + addr + 1) = (val >> 8) & 0xff;
  297. *(u8*)(M.mem_base + addr + 2) = (val >> 16) & 0xff;
  298. *(u8*)(M.mem_base + addr + 3) = (val >> 24) & 0xff;
  299. }
  300. else
  301. #endif
  302. *(u32*)(M.mem_base + addr - 0xC0000) = val;
  303. }
  304. else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
  305. #ifdef __BIG_ENDIAN__
  306. if (addr & 0x3) {
  307. addr -= 0xA0000;
  308. writeb(val >> 0, _BE_env.busmem_base, addr);
  309. writeb(val >> 8, _BE_env.busmem_base, addr + 1);
  310. writeb(val >> 16, _BE_env.busmem_base, addr + 1);
  311. writeb(val >> 24, _BE_env.busmem_base, addr + 1);
  312. }
  313. else
  314. #endif
  315. writel(val, _BE_env.busmem_base, addr - 0xA0000);
  316. }
  317. else if (addr > M.mem_size-4) {
  318. DB( printk("mem_write: address %#lx out of range!\n", addr);)
  319. HALT_SYS();
  320. }
  321. else {
  322. #ifdef __BIG_ENDIAN__
  323. if (addr & 0x1) {
  324. *(u8*)(M.mem_base + addr + 0) = (val >> 0) & 0xff;
  325. *(u8*)(M.mem_base + addr + 1) = (val >> 8) & 0xff;
  326. *(u8*)(M.mem_base + addr + 2) = (val >> 16) & 0xff;
  327. *(u8*)(M.mem_base + addr + 3) = (val >> 24) & 0xff;
  328. }
  329. else
  330. #endif
  331. *(u32*)(M.mem_base + addr) = val;
  332. }
  333. }
  334. /* Debug functions to do ISA/PCI bus port I/O */
  335. #ifdef DEBUG
  336. #define DEBUG_IO() (M.x86.debug & DEBUG_IO_TRACE_F)
  337. u8 X86API BE_inb(int port)
  338. {
  339. u8 val = PM_inpb(port);
  340. if (DEBUG_IO())
  341. printk("%04X:%04X: inb.%04X -> %02X\n",M.x86.saved_cs, M.x86.saved_ip, (ushort)port, val);
  342. return val;
  343. }
  344. u16 X86API BE_inw(int port)
  345. {
  346. u16 val = PM_inpw(port);
  347. if (DEBUG_IO())
  348. printk("%04X:%04X: inw.%04X -> %04X\n",M.x86.saved_cs, M.x86.saved_ip, (ushort)port, val);
  349. return val;
  350. }
  351. u32 X86API BE_inl(int port)
  352. {
  353. u32 val = PM_inpd(port);
  354. if (DEBUG_IO())
  355. printk("%04X:%04X: inl.%04X -> %08X\n",M.x86.saved_cs, M.x86.saved_ip, (ushort)port, val);
  356. return val;
  357. }
  358. void X86API BE_outb(int port, u8 val)
  359. {
  360. if (DEBUG_IO())
  361. printk("%04X:%04X: outb.%04X <- %02X\n",M.x86.saved_cs, M.x86.saved_ip, (ushort)port, val);
  362. PM_outpb(port,val);
  363. }
  364. void X86API BE_outw(int port, u16 val)
  365. {
  366. if (DEBUG_IO())
  367. printk("%04X:%04X: outw.%04X <- %04X\n",M.x86.saved_cs, M.x86.saved_ip, (ushort)port, val);
  368. PM_outpw(port,val);
  369. }
  370. void X86API BE_outl(int port, u32 val)
  371. {
  372. if (DEBUG_IO())
  373. printk("%04X:%04X: outl.%04X <- %08X\n",M.x86.saved_cs, M.x86.saved_ip, (ushort)port, val);
  374. PM_outpd(port,val);
  375. }
  376. #endif