bios.S 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. /*
  2. * (C) Copyright 2002
  3. * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. /*
  24. * Based on msbios.c from rolo 1.6:
  25. *----------------------------------------------------------------------
  26. * (C) Copyright 2000
  27. * Sysgo Real-Time Solutions GmbH
  28. * Klein-Winternheim, Germany
  29. *----------------------------------------------------------------------
  30. */
  31. #include "bios.h"
  32. /*
  33. * During it's initialization phase, before switching to protected
  34. * mode, the Linux Kernel makes a few BIOS calls. This won't work
  35. * if the board does not have a BIOS.
  36. *
  37. * This is a very minimalisic BIOS that supplies just enough
  38. * functionality to keep the Linux Kernel happy. It is NOT
  39. * a general purpose replacement for a real BIOS !!
  40. */
  41. .section .bios, "ax"
  42. .code16
  43. .org 0
  44. /* a call to f000:0 should warmboot */
  45. jmp realmode_reset
  46. .globl rm_int00
  47. .hidden rm_int00
  48. .type rm_int00, @function
  49. rm_int00:
  50. pushw $0
  51. jmp any_interrupt16
  52. .globl rm_int01
  53. .hidden rm_int01
  54. .type rm_int01, @function
  55. rm_int01:
  56. pushw $1
  57. jmp any_interrupt16
  58. .globl rm_int02
  59. .hidden rm_int02
  60. .type rm_int02, @function
  61. rm_int02:
  62. pushw $2
  63. jmp any_interrupt16
  64. .globl rm_int03
  65. .hidden rm_int03
  66. .type rm_int03, @function
  67. rm_int03:
  68. pushw $3
  69. jmp any_interrupt16
  70. .globl rm_int04
  71. .hidden rm_int04
  72. .type rm_int04, @function
  73. rm_int04:
  74. pushw $4
  75. jmp any_interrupt16
  76. .globl rm_int05
  77. .hidden rm_int05
  78. .type rm_int05, @function
  79. rm_int05:
  80. pushw $5
  81. jmp any_interrupt16
  82. .globl rm_int06
  83. .hidden rm_int06
  84. .type rm_int06, @function
  85. rm_int06:
  86. pushw $6
  87. jmp any_interrupt16
  88. .globl rm_int07
  89. .hidden rm_int07
  90. .type rm_int07, @function
  91. rm_int07:
  92. pushw $7
  93. jmp any_interrupt16
  94. .globl rm_int08
  95. .hidden rm_int08
  96. .type rm_int08, @function
  97. rm_int08:
  98. pushw $8
  99. jmp any_interrupt16
  100. .globl rm_int09
  101. .hidden rm_int09
  102. .type rm_int09, @function
  103. rm_int09:
  104. pushw $9
  105. jmp any_interrupt16
  106. .globl rm_int0a
  107. .hidden rm_int0a
  108. .type rm_int0a, @function
  109. rm_int0a:
  110. pushw $10
  111. jmp any_interrupt16
  112. .globl rm_int0b
  113. .hidden rm_int0b
  114. .type rm_int0b, @function
  115. rm_int0b:
  116. pushw $11
  117. jmp any_interrupt16
  118. .globl rm_int0c
  119. .hidden rm_int0c
  120. .type rm_int0c, @function
  121. rm_int0c:
  122. pushw $12
  123. jmp any_interrupt16
  124. .globl rm_int0d
  125. .hidden rm_int0d
  126. .type rm_int0d, @function
  127. rm_int0d:
  128. pushw $13
  129. jmp any_interrupt16
  130. .globl rm_int0e
  131. .hidden rm_int0e
  132. .type rm_int0e, @function
  133. rm_int0e:
  134. pushw $14
  135. jmp any_interrupt16
  136. .globl rm_int0f
  137. .hidden rm_int0f
  138. .type rm_int0f, @function
  139. rm_int0f:
  140. pushw $15
  141. jmp any_interrupt16
  142. .globl rm_int10
  143. .hidden rm_int10
  144. .type rm_int10, @function
  145. rm_int10:
  146. pushw $16
  147. jmp any_interrupt16
  148. .globl rm_int11
  149. .hidden rm_int11
  150. .type rm_int11, @function
  151. rm_int11:
  152. pushw $17
  153. jmp any_interrupt16
  154. .globl rm_int12
  155. .hidden rm_int12
  156. .type rm_int12, @function
  157. rm_int12:
  158. pushw $18
  159. jmp any_interrupt16
  160. .globl rm_int13
  161. .hidden rm_int13
  162. .type rm_int13, @function
  163. rm_int13:
  164. pushw $19
  165. jmp any_interrupt16
  166. .globl rm_int14
  167. .hidden rm_int14
  168. .type rm_int14, @function
  169. rm_int14:
  170. pushw $20
  171. jmp any_interrupt16
  172. .globl rm_int15
  173. .hidden rm_int15
  174. .type rm_int15, @function
  175. rm_int15:
  176. pushw $21
  177. jmp any_interrupt16
  178. .globl rm_int16
  179. .hidden rm_int16
  180. .type rm_int16, @function
  181. rm_int16:
  182. pushw $22
  183. jmp any_interrupt16
  184. .globl rm_int17
  185. .hidden rm_int17
  186. .type rm_int17, @function
  187. rm_int17:
  188. pushw $23
  189. jmp any_interrupt16
  190. .globl rm_int18
  191. .hidden rm_int18
  192. .type rm_int18, @function
  193. rm_int18:
  194. pushw $24
  195. jmp any_interrupt16
  196. .globl rm_int19
  197. .hidden rm_int19
  198. .type rm_int19, @function
  199. rm_int19:
  200. pushw $25
  201. jmp any_interrupt16
  202. .globl rm_int1a
  203. .hidden rm_int1a
  204. .type rm_int1a, @function
  205. rm_int1a:
  206. pushw $26
  207. jmp any_interrupt16
  208. .globl rm_int1b
  209. .hidden rm_int1b
  210. .type rm_int1b, @function
  211. rm_int1b:
  212. pushw $27
  213. jmp any_interrupt16
  214. .globl rm_int1c
  215. .hidden rm_int1c
  216. .type rm_int1c, @function
  217. rm_int1c:
  218. pushw $28
  219. jmp any_interrupt16
  220. .globl rm_int1d
  221. .hidden rm_int1d
  222. .type rm_int1d, @function
  223. rm_int1d:
  224. pushw $29
  225. jmp any_interrupt16
  226. .globl rm_int1e
  227. .hidden rm_int1e
  228. .type rm_int1e, @function
  229. rm_int1e:
  230. pushw $30
  231. jmp any_interrupt16
  232. .globl rm_int1f
  233. .hidden rm_int1f
  234. .type rm_int1f, @function
  235. rm_int1f:
  236. pushw $31
  237. jmp any_interrupt16
  238. .globl rm_def_int
  239. .hidden rm_def_int
  240. .type rm_def_int, @function
  241. rm_def_int:
  242. iret
  243. /*
  244. * All interrupt jumptable entries jump to here after pushing the
  245. * interrupt vector number onto the stack.
  246. */
  247. any_interrupt16:
  248. MAKE_BIOS_STACK
  249. gs movw OFFS_VECTOR(%bp), %ax
  250. cmpw $0x10, %ax
  251. je Lint_10h
  252. cmpw $0x11, %ax
  253. je Lint_11h
  254. cmpw $0x12, %ax
  255. je Lint_12h
  256. cmpw $0x13, %ax
  257. je Lint_13h
  258. cmpw $0x15, %ax
  259. je Lint_15h
  260. cmpw $0x16, %ax
  261. je Lint_16h
  262. cmpw $0x1a, %ax
  263. je Lint_1ah
  264. movw $0xffff, %ax
  265. jmp Lout
  266. Lint_10h:
  267. /* VGA BIOS services */
  268. call bios_10h
  269. jmp Lout
  270. Lint_11h:
  271. call bios_11h
  272. jmp Lout
  273. Lint_12h:
  274. call bios_12h
  275. jmp Lout
  276. Lint_13h:
  277. /* BIOS disk services */
  278. call bios_13h
  279. jmp Lout
  280. Lint_15h:
  281. /* Misc. BIOS services */
  282. call bios_15h
  283. jmp Lout
  284. Lint_16h:
  285. /* keyboard services */
  286. call bios_16h
  287. jmp Lout
  288. Lint_1ah:
  289. /* PCI bios */
  290. call bios_1ah
  291. jmp Lout
  292. Lout:
  293. cmpw $0, %ax
  294. je Lhandeled
  295. /*
  296. * Insert code for unhandeled INTs here.
  297. *
  298. * ROLO prints a message to the console we could do that but then
  299. * we're in 16bit mode so we'll have to get back into 32bit mode
  300. * to use the console I/O routines (if we do this we should make
  301. * int 0x10 and int 0x16 work as well)
  302. */
  303. Lhandeled:
  304. RESTORE_CALLERS_STACK
  305. /* dump vector number */
  306. addw $2,%sp
  307. /* return from interrupt */
  308. iret
  309. /*
  310. ************************************************************
  311. * BIOS interrupt 10h -- VGA services
  312. ************************************************************
  313. */
  314. bios_10h:
  315. gs movw OFFS_AX(%bp), %ax
  316. shrw $8, %ax
  317. cmpw $0x3, %ax
  318. je Lcur_pos
  319. cmpw $0xf, %ax
  320. je Lvid_state
  321. cmpw $0x12, %ax
  322. je Lvid_cfg
  323. movw $0xffff, %ax
  324. ret
  325. Lcur_pos:
  326. /* Read Cursor Position and Size */
  327. gs movw $0, OFFS_CX(%bp)
  328. gs movw $0, OFFS_DX(%bp)
  329. xorw %ax, %ax
  330. ret
  331. Lvid_state:
  332. /* Get Video State - 80 columns, 80x25, 16 colors */
  333. gs movw $(80 << 8|0x03), OFFS_AX(%bp)
  334. gs movw $0, OFFS_BX(%bp)
  335. xorw %ax, %ax
  336. ret
  337. Lvid_cfg:
  338. /* Video Subsystem Configuration (EGA/VGA) - indicate CGA/MDA/HGA */
  339. gs movw $0x10, OFFS_BX(%bp)
  340. xorw %ax, %ax
  341. ret
  342. /*
  343. ************************************************************
  344. * BIOS interrupt 11h -- Equipment determination
  345. ************************************************************
  346. */
  347. bios_11h:
  348. cs movw bios_equipment, %ax
  349. gs movw %ax, OFFS_AX(%bp)
  350. xorw %ax, %ax
  351. ret
  352. /*
  353. ************************************************************
  354. * BIOS interrupt 12h -- Get Memory Size
  355. ************************************************************
  356. */
  357. bios_12h:
  358. cs movw ram_in_64kb_chunks, %ax
  359. cmpw $0xa, %ax
  360. ja b12_more_than_640k
  361. shlw $6, %ax
  362. jmp b12_return
  363. b12_more_than_640k:
  364. movw $0x280, %ax
  365. b12_return:
  366. /* return number of kilobytes in ax */
  367. gs movw %ax, OFFS_AX(%bp)
  368. gs movw OFFS_FLAGS(%bp), %ax
  369. /* clear carry -- function succeeded */
  370. andw $0xfffe, %ax
  371. gs movw %ax, OFFS_FLAGS(%bp)
  372. xorw %ax, %ax
  373. ret
  374. /*
  375. ************************************************************
  376. * BIOS interrupt 13h -- Disk services
  377. ************************************************************
  378. */
  379. bios_13h:
  380. gs movw OFFS_AX(%bp), %ax
  381. shrw $8, %ax
  382. cmpw $0x15, %ax
  383. je Lfunc_15h
  384. movw $0xffff, %ax
  385. ret
  386. Lfunc_15h:
  387. gs movw OFFS_AX(%bp), %ax
  388. /* return AH=0->drive not present */
  389. andw $0x00ff, %ax
  390. gs movw %ax, OFFS_AX(%bp)
  391. xorw %ax, %ax
  392. ret
  393. /*
  394. ***********************************************************
  395. * BIOS interrupt 15h -- Miscellaneous services
  396. ***********************************************************
  397. */
  398. bios_15h:
  399. gs movw OFFS_AX(%bp), %ax
  400. shrw $8, %ax
  401. cmpw $0xc0, %ax
  402. je Lfunc_c0h
  403. cmpw $0xe8, %ax
  404. je Lfunc_e8h
  405. cmpw $0x88, %ax
  406. je Lfunc_88h
  407. movw $0xffff, %ax
  408. ret
  409. Lfunc_c0h:
  410. /* Return System Configuration Parameters (PS2 only) */
  411. gs movw OFFS_FLAGS(%bp), %ax
  412. /* return carry -- function not supported */
  413. orw $1, %ax
  414. gs movw %ax, OFFS_FLAGS(%bp)
  415. xorw %ax, %ax
  416. ret
  417. Lfunc_e8h:
  418. gs movw OFFS_AX(%bp), %ax
  419. andw $0xff, %ax
  420. cmpw $1, %ax
  421. je Lfunc_e801h
  422. gs movw OFFS_FLAGS(%bp), %ax
  423. /* return carry -- function not supported */
  424. orw $1, %ax
  425. gs movw %ax, OFFS_FLAGS(%bp)
  426. xorw %ax, %ax
  427. ret
  428. Lfunc_e801h:
  429. /* Get memory size for >64M Configurations */
  430. cs movw ram_in_64kb_chunks, %ax
  431. cmpw $0x100, %ax
  432. ja e801_more_than_16mb
  433. /* multiply by 64 */
  434. shlw $6, %ax
  435. /* 1st meg does not count */
  436. subw $0x400, %ax
  437. /* return memory size between 1M and 16M in 1kb chunks in AX and CX */
  438. gs movw %ax, OFFS_AX(%bp)
  439. gs movw %ax, OFFS_CX(%bp)
  440. /* set BX and DX to 0*/
  441. gs movw $0, OFFS_BX(%bp)
  442. gs movw $0, OFFS_DX(%bp)
  443. gs movw OFFS_FLAGS(%bp), %ax
  444. /* clear carry -- function succeeded */
  445. andw $0xfffe, %ax
  446. gs movw %ax, OFFS_FLAGS(%bp)
  447. xorw %ax, %ax
  448. ret
  449. e801_more_than_16mb:
  450. /* subtract 16MB */
  451. subw $0x100, %ax
  452. /* return 0x3c00 (16MB-1MB) in AX and CX */
  453. gs movw $0x3c00, OFFS_AX(%bp)
  454. gs movw $0x3c00, OFFS_CX(%bp)
  455. /* set BX and DX to number of 64kb chunks above 16MB */
  456. gs movw %ax, OFFS_BX(%bp)
  457. gs movw %ax, OFFS_DX(%bp)
  458. gs movw OFFS_FLAGS(%bp), %ax
  459. /* clear carry -- function succeeded */
  460. andw $0xfffe, %ax
  461. gs movw %ax, OFFS_FLAGS(%bp)
  462. xorw %ax, %ax
  463. ret
  464. Lfunc_88h:
  465. cs movw ram_in_64kb_chunks, %ax
  466. cmpw $0x100, %ax
  467. jna b88_not_more_than16
  468. movw $0x100, %ax
  469. b88_not_more_than16:
  470. shlw $6, %ax
  471. /* 1st meg does not count */
  472. subw $0x400, %ax
  473. /* return number of kilobytes between 16MB and 16MB in ax */
  474. gs movw %ax, OFFS_AX(%bp)
  475. gs movw OFFS_FLAGS(%bp), %ax
  476. /* clear carry -- function succeeded */
  477. andw $0xfffe, %ax
  478. gs movw %ax, OFFS_FLAGS(%bp)
  479. xorw %ax, %ax
  480. ret
  481. /*
  482. ************************************************************
  483. * BIOS interrupt 16h -- keyboard services
  484. ************************************************************
  485. */
  486. bios_16h:
  487. gs movw OFFS_AX(%bp), %ax
  488. shrw $8, %ax
  489. cmpw $0x03, %ax
  490. je Lfunc_03h
  491. movw $0xffff, %ax
  492. ret
  493. Lfunc_03h:
  494. /* do nothing -- function not supported */
  495. xorw %ax, %ax
  496. ret
  497. /*
  498. ************************************************************
  499. * BIOS interrupt 1ah -- PCI bios
  500. ************************************************************
  501. */
  502. bios_1ah:
  503. gs movw OFFS_AX(%bp), %ax
  504. cmpb $0xb1, %ah
  505. je Lfunc_b1h
  506. movw $0xffff, %ax
  507. ret
  508. Lfunc_b1h:
  509. call realmode_pci_bios
  510. /* do nothing -- function not supported */
  511. xorw %ax, %ax
  512. ret
  513. .globl ram_in_64kb_chunks
  514. .hidden ram_in_64kb_chunks
  515. .type ram_in_64kb_chunks, @function
  516. ram_in_64kb_chunks:
  517. .word 0
  518. .globl bios_equipment
  519. .hidden bios_equipment
  520. .type bios_equipment, @function
  521. bios_equipment:
  522. .word 0