bios.S 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  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
  245. * after pushing the interrupt vector number onto the
  246. * stack.
  247. */
  248. any_interrupt16:
  249. MAKE_BIOS_STACK
  250. gs movw OFFS_VECTOR(%bp), %ax
  251. cmpw $0x10, %ax
  252. je Lint_10h
  253. cmpw $0x11, %ax
  254. je Lint_11h
  255. cmpw $0x12, %ax
  256. je Lint_12h
  257. cmpw $0x13, %ax
  258. je Lint_13h
  259. cmpw $0x15, %ax
  260. je Lint_15h
  261. cmpw $0x16, %ax
  262. je Lint_16h
  263. cmpw $0x1a, %ax
  264. je Lint_1ah
  265. movw $0xffff, %ax
  266. jmp Lout
  267. Lint_10h: /* 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: /* BIOS disk services */
  277. call bios_13h
  278. jmp Lout
  279. Lint_15h: /* Misc. BIOS services */
  280. call bios_15h
  281. jmp Lout
  282. Lint_16h: /* keyboard services */
  283. call bios_16h
  284. jmp Lout
  285. Lint_1ah: /* PCI bios */
  286. call bios_1ah
  287. jmp Lout
  288. Lout:
  289. cmpw $0, %ax
  290. je Lhandeled
  291. /* Insert code for unhandeled INTs here.
  292. *
  293. * ROLO prints a message to the console
  294. * (we could do that but then we're in 16bit mode
  295. * so we'll have to get back into 32bit mode
  296. * to use the console I/O routines (if we do this
  297. * we shuls make int 0x10 and int 0x16 work as well))
  298. */
  299. Lhandeled:
  300. RESTORE_CALLERS_STACK
  301. addw $2,%sp /* dump vector number */
  302. iret /* return from interrupt */
  303. /*
  304. ************************************************************
  305. * BIOS interrupt 10h -- VGA services
  306. ************************************************************
  307. */
  308. bios_10h:
  309. gs movw OFFS_AX(%bp), %ax
  310. shrw $8, %ax
  311. cmpw $0x3, %ax
  312. je Lcur_pos
  313. cmpw $0xf, %ax
  314. je Lvid_state
  315. cmpw $0x12, %ax
  316. je Lvid_cfg
  317. movw $0xffff, %ax
  318. ret
  319. Lcur_pos: /* Read Cursor Position and Size */
  320. gs movw $0, OFFS_CX(%bp)
  321. gs movw $0, OFFS_DX(%bp)
  322. xorw %ax, %ax
  323. ret
  324. Lvid_state: /* Get Video State */
  325. gs movw $(80 << 8|0x03), OFFS_AX(%bp) /* 80 columns, 80x25, 16 colors */
  326. gs movw $0, OFFS_BX(%bp)
  327. xorw %ax, %ax
  328. ret
  329. Lvid_cfg: /* Video Subsystem Configuration (EGA/VGA) */
  330. gs movw $0x10, OFFS_BX(%bp) /* indicate CGA/MDA/HGA */
  331. xorw %ax, %ax
  332. ret
  333. /*
  334. ************************************************************
  335. * BIOS interrupt 11h -- Equipment determination
  336. ************************************************************
  337. */
  338. bios_11h:
  339. cs movw bios_equipment, %ax
  340. gs movw %ax, OFFS_AX(%bp)
  341. xorw %ax, %ax
  342. ret
  343. /*
  344. ************************************************************
  345. * BIOS interrupt 12h -- Get Memory Size
  346. ************************************************************
  347. */
  348. bios_12h:
  349. cs movw ram_in_64kb_chunks, %ax
  350. cmpw $0xa, %ax
  351. ja b12_more_than_640k
  352. shlw $6, %ax
  353. jmp b12_return
  354. b12_more_than_640k:
  355. movw $0x280, %ax
  356. b12_return:
  357. gs movw %ax, OFFS_AX(%bp) /* return number of kilobytes in ax */
  358. gs movw OFFS_FLAGS(%bp), %ax
  359. andw $0xfffe, %ax /* clear carry -- function succeeded */
  360. gs movw %ax, OFFS_FLAGS(%bp)
  361. xorw %ax, %ax
  362. ret
  363. /*
  364. ************************************************************
  365. * BIOS interrupt 13h -- Disk services
  366. ************************************************************
  367. */
  368. bios_13h:
  369. gs movw OFFS_AX(%bp), %ax
  370. shrw $8, %ax
  371. cmpw $0x15, %ax
  372. je Lfunc_15h
  373. movw $0xffff, %ax
  374. ret
  375. Lfunc_15h:
  376. gs movw OFFS_AX(%bp), %ax
  377. andw $0xff, %ax /* return AH=0->drive not present */
  378. gs movw %ax, OFFS_AX(%bp)
  379. xorw %ax, %ax
  380. ret
  381. /*
  382. ***********************************************************
  383. * BIOS interrupt 15h -- Miscellaneous services
  384. ***********************************************************
  385. */
  386. bios_15h:
  387. gs movw OFFS_AX(%bp), %ax
  388. shrw $8, %ax
  389. cmpw $0xc0, %ax
  390. je Lfunc_c0h
  391. cmpw $0xe8, %ax
  392. je Lfunc_e8h
  393. cmpw $0x88, %ax
  394. je Lfunc_88h
  395. movw $0xffff, %ax
  396. ret
  397. Lfunc_c0h: /* Return System Configuration Parameters (PS2 only) */
  398. gs movw OFFS_FLAGS(%bp), %ax
  399. orw $1, %ax /* return carry -- function not supported */
  400. gs movw %ax, OFFS_FLAGS(%bp)
  401. xorw %ax, %ax
  402. ret
  403. Lfunc_e8h:
  404. gs movw OFFS_AX(%bp), %ax
  405. andw $0xff, %ax
  406. cmpw $1, %ax
  407. je Lfunc_e801h
  408. gs movw OFFS_FLAGS(%bp), %ax
  409. orw $1, %ax /* return carry -- function not supported */
  410. gs movw %ax, OFFS_FLAGS(%bp)
  411. xorw %ax, %ax
  412. ret
  413. Lfunc_e801h: /* Get memory size for >64M Configurations */
  414. cs movw ram_in_64kb_chunks, %ax
  415. cmpw $0x100, %ax
  416. ja e801_more_than_16mb
  417. shlw $6, %ax /* multiply by 64 */
  418. subw $0x400, %ax /* 1st meg does not count */
  419. gs movw %ax, OFFS_AX(%bp) /* return memory size between 1M and 16M in 1kb chunks in AX and CX */
  420. gs movw %ax, OFFS_CX(%bp)
  421. gs movw $0, OFFS_BX(%bp) /* set BX and DX to 0*/
  422. gs movw $0, OFFS_DX(%bp)
  423. gs movw OFFS_FLAGS(%bp), %ax
  424. andw $0xfffe, %ax /* clear carry -- function succeeded */
  425. gs movw %ax, OFFS_FLAGS(%bp)
  426. xorw %ax, %ax
  427. ret
  428. e801_more_than_16mb:
  429. subw $0x100, %ax /* subtract 16MB */
  430. gs movw $0x3c00, OFFS_AX(%bp) /* return 0x3c00 (16MB-1MB) in AX and CX */
  431. gs movw $0x3c00, OFFS_CX(%bp)
  432. gs movw %ax, OFFS_BX(%bp) /* set BX and DX to number of 64kb chunks above 16MB */
  433. gs movw %ax, OFFS_DX(%bp)
  434. gs movw OFFS_FLAGS(%bp), %ax
  435. andw $0xfffe, %ax /* clear carry -- function succeeded */
  436. gs movw %ax, OFFS_FLAGS(%bp)
  437. xorw %ax, %ax
  438. ret
  439. Lfunc_88h:
  440. cs movw ram_in_64kb_chunks, %ax
  441. cmpw $0x100, %ax
  442. jna b88_not_more_than16
  443. movw $0x100, %ax
  444. b88_not_more_than16:
  445. shlw $6, %ax
  446. subw $0x400, %ax /* 1st meg does not count */
  447. gs movw %ax, OFFS_AX(%bp) /* return number of kilobytes between 16MB and 16MB in ax */
  448. gs movw OFFS_FLAGS(%bp), %ax
  449. andw $0xfffe, %ax /* clear carry -- function succeeded */
  450. gs movw %ax, OFFS_FLAGS(%bp)
  451. xorw %ax, %ax
  452. ret
  453. /*
  454. ************************************************************
  455. * BIOS interrupt 16h -- keyboard services
  456. ************************************************************
  457. */
  458. bios_16h:
  459. gs movw OFFS_AX(%bp), %ax
  460. shrw $8, %ax
  461. cmpw $0x03, %ax
  462. je Lfunc_03h
  463. movw $0xffff, %ax
  464. ret
  465. Lfunc_03h:
  466. xorw %ax, %ax /* do nothing -- function not supported */
  467. ret
  468. /*
  469. ************************************************************
  470. * BIOS interrupt 1ah -- PCI bios
  471. ************************************************************
  472. */
  473. bios_1ah:
  474. gs movw OFFS_AX(%bp), %ax
  475. cmpb $0xb1, %ah
  476. je Lfunc_b1h
  477. movw $0xffff, %ax
  478. ret
  479. Lfunc_b1h:
  480. call realmode_pci_bios
  481. xorw %ax, %ax /* do nothing -- function not supported */
  482. ret
  483. .globl ram_in_64kb_chunks
  484. .hidden ram_in_64kb_chunks
  485. .type ram_in_64kb_chunks, @function
  486. ram_in_64kb_chunks:
  487. .word 0
  488. .globl bios_equipment
  489. .hidden bios_equipment
  490. .type bios_equipment, @function
  491. bios_equipment:
  492. .word 0