History

20060303

Charles.Forsyth committed 19 years ago

Commit 64418801 parent eea662d1386 files · +530669 −-6Browse files

Unified · Split

990 files
  1. os/NOTICE +31 −0
  2. os/README +32 −0
  3. os/boot/README +33 −0
  4. os/boot/arm1110/Mk +8 −0
  5. os/boot/arm1110/dat.h +1 −0
  6. os/boot/arm1110/donprint.c +332 −0
  7. os/boot/arm1110/fns.h +7 −0
  8. os/boot/arm1110/il.s +99 −0
  9. os/boot/arm1110/imain.c +48 −0
  10. os/boot/arm1110/inflate.c +208 −0
  11. os/boot/arm1110/io.h +261 −0
  12. os/boot/arm1110/l.s +454 −0
  13. os/boot/arm1110/lib.h +143 −0
  14. os/boot/arm1110/map +10 −0
  15. os/boot/arm1110/mem.h +215 −0
  16. os/boot/arm1110/mkfile +86 −0
  17. os/boot/arm1110/print.c +56 −0
  18. os/boot/arm1110/uart.c +69 −0
  19. os/boot/libflate/LICENCE +237 −0
  20. os/boot/libflate/NOTICE +8 −0
  21. os/boot/libflate/adler.c +71 −0
  22. os/boot/libflate/crc.c +39 −0
  23. os/boot/libflate/deflate.c +1358 −0
  24. os/boot/libflate/deflateblock.c +55 −0
  25. os/boot/libflate/deflatezlib.c +59 −0
  26. os/boot/libflate/deflatezlibblock.c +33 −0
  27. os/boot/libflate/flateerr.c +22 −0
  28. os/boot/libflate/inflate.c +692 −0
  29. os/boot/libflate/inflateblock.c +53 −0
  30. os/boot/libflate/inflatezlib.c +65 −0
  31. os/boot/libflate/inflatezlibblock.c +67 −0
  32. os/boot/libflate/mkfile +21 −0
  33. os/boot/libflate/zlib.h +11 −0
  34. os/boot/mpc/NOTICE +3 −0
  35. os/boot/mpc/alarm.c +123 −0
  36. os/boot/mpc/all.h +6 −0
  37. os/boot/mpc/archfads.c +355 −0
  38. os/boot/mpc/archfads.h +42 −0
  39. os/boot/mpc/archpaq.c +240 −0
  40. os/boot/mpc/archpaq.h +29 −0
  41. os/boot/mpc/boot.h +8 −0
  42. os/boot/mpc/bootp.c +507 −0
  43. os/boot/mpc/clock.c +71 −0
  44. os/boot/mpc/conf.c +173 −0
  45. os/boot/mpc/console.c +173 −0
  46. os/boot/mpc/cpm.c +162 −0
  47. os/boot/mpc/crc32.c +42 −0
  48. os/boot/mpc/dat.h +217 −0
  49. os/boot/mpc/defont0.c +216 −0
  50. os/boot/mpc/devether.c +157 −0
  51. os/boot/mpc/devuart.c +230 −0
  52. os/boot/mpc/dload.c +103 −0
  53. os/boot/mpc/donprint.c +332 −0
  54. os/boot/mpc/dosboot.c +614 −0
  55. os/boot/mpc/dosfs.h +110 −0
  56. os/boot/mpc/etherif.h +59 −0
  57. os/boot/mpc/etherscc.c +411 −0
  58. os/boot/mpc/fblt.c +531 −0
  59. os/boot/mpc/flash.c +212 −0
  60. os/boot/mpc/fns.h +117 −0
  61. os/boot/mpc/gbitbltclip.c +52 −0
  62. os/boot/mpc/gnot.h +71 −0
  63. os/boot/mpc/i2c.c +351 −0
  64. os/boot/mpc/initfads.c +187 −0
  65. os/boot/mpc/initpaq.c +101 −0
  66. os/boot/mpc/initrpcg.c +91 −0
  67. os/boot/mpc/io.h +463 −0
  68. os/boot/mpc/ip.h +98 −0
  69. os/boot/mpc/l.s +370 −0
  70. os/boot/mpc/lib.h +106 −0
  71. os/boot/mpc/main.c +524 −0
  72. os/boot/mpc/mem.c +0 −0
  73. os/boot/mpc/mem.h +95 −0
  74. os/boot/mpc/mkfile +116 −0
  75. os/boot/mpc/ms2.c +179 −0
  76. os/boot/mpc/plan9boot.c +96 −0
  77. os/boot/mpc/qio.c +128 −0
  78. os/boot/mpc/rmap.c +104 −0
  79. os/boot/mpc/screen.c +242 −0
  80. os/boot/mpc/sload.c +71 −0
  81. os/boot/mpc/squeeze.h +34 −0
  82. os/boot/mpc/trap.c +233 −0
  83. os/boot/mpc/uartboot.c +189 −0
  84. os/boot/mpc/ureg.h +43 −0
  85. os/boot/mpc/zqs.c +234 −0
  86. os/boot/pc/8250.c +308 −0
  87. os/boot/pc/LICENCE +237 −0
  88. os/boot/pc/NOTICE +4 −0
  89. os/boot/pc/alarm.c +123 −0
  90. os/boot/pc/apm.c +16 −0
  91. os/boot/pc/bcom.c +460 −0
  92. os/boot/pc/boot.c +451 −0
  93. os/boot/pc/bootld.c +108 −0
  94. os/boot/pc/bootp.c +652 −0
  95. os/boot/pc/cga.c +91 −0
  96. os/boot/pc/clock.c +305 −0
  97. os/boot/pc/conf.c +537 −0
  98. os/boot/pc/console.c +236 −0
  99. os/boot/pc/dat.h +212 −0
  100. os/boot/pc/devfloppy.c +853 −0
  101. os/boot/pc/devfloppy.h +196 −0
  102. os/boot/pc/devi82365.c +1205 −0
  103. os/boot/pc/devpccard.c +1957 −0
  104. os/boot/pc/devsd.c +617 −0
  105. os/boot/pc/dma.c +245 −0
  106. os/boot/pc/dosboot.c +582 −0
  107. os/boot/pc/dosfs.h +62 −0
  108. os/boot/pc/eipfmt.c +145 −0
  109. os/boot/pc/error.h +58 −0
  110. os/boot/pc/ether.c +282 −0
  111. os/boot/pc/ether2000.c +110 −0
  112. os/boot/pc/ether2114x.c +1652 −0
  113. os/boot/pc/ether589.c +211 −0
  114. os/boot/pc/ether79c970.c +539 −0
  115. os/boot/pc/ether8003.c +258 −0
  116. os/boot/pc/ether8139.c +614 −0
  117. os/boot/pc/ether8169.c +847 −0
  118. os/boot/pc/ether82557.c +881 −0
  119. os/boot/pc/ether83815.c +825 −0
  120. os/boot/pc/ether8390.c +715 −0
  121. os/boot/pc/ether8390.h +71 −0
  122. os/boot/pc/etherec2t.c +155 −0
  123. os/boot/pc/etherelnk3.c +1898 −0
  124. os/boot/pc/etherif.h +46 −0
  125. os/boot/pc/etherigbe.c +1706 −0
  126. os/boot/pc/ethermii.c +224 −0
  127. os/boot/pc/ethermii.h +116 −0
  128. os/boot/pc/etherrhine.c +676 −0
  129. os/boot/pc/fns.h +155 −0
  130. os/boot/pc/fs.c +94 −0
  131. os/boot/pc/fs.h +36 −0
  132. os/boot/pc/getcallerpc.c +8 −0
  133. os/boot/pc/ilock.c +24 −0
  134. os/boot/pc/inflate.c +199 −0
  135. os/boot/pc/io.h +201 −0
  136. os/boot/pc/ip.h +100 −0
  137. os/boot/pc/kbd.c +489 −0
  138. os/boot/pc/kfs.h +57 −0
  139. os/boot/pc/kfsboot.c +256 −0
  140. os/boot/pc/l.s +1079 −0
  141. os/boot/pc/lib.h +102 −0
  142. os/boot/pc/load.c +563 −0
  143. os/boot/pc/mbr.s +259 −0
  144. os/boot/pc/mem.h +114 −0
  145. os/boot/pc/memory.c +504 −0
  146. os/boot/pc/mkfile +241 −0
  147. os/boot/pc/noether.c +40 −0
  148. os/boot/pc/part.c +344 −0
  149. os/boot/pc/pbs.s +372 −0
  150. os/boot/pc/pbsdisk +0 −0
  151. os/boot/pc/pbsdisk.s +344 −0
  152. os/boot/pc/pbsdisklba +0 −0
  153. os/boot/pc/pbsdisklba.s +327 −0
  154. os/boot/pc/pbslba.s +362 −0
  155. os/boot/pc/pci.c +852 −0
  156. os/boot/pc/print.c +31 −0
  157. os/boot/pc/queue.c +44 −0
  158. os/boot/pc/sd.h +127 −0
  159. os/boot/pc/sd53c8xx.c +2120 −0
  160. os/boot/pc/sd53c8xx.i +769 −0
  161. os/boot/pc/sdata.c +1639 −0
  162. os/boot/pc/sdmylex.c +1294 −0
  163. os/boot/pc/sdscsi.c +376 −0
  164. os/boot/pc/trap.c +331 −0
  165. os/boot/pc/ureg.h +27 −0
  166. os/boot/pc/x16.h +159 −0
  167. os/boot/puma/8250.c +312 −0
  168. os/boot/puma/alarm.c +123 −0
  169. os/boot/puma/armv4.h +99 −0
  170. os/boot/puma/boot.h +12 −0
  171. os/boot/puma/bootp.c +502 −0
  172. os/boot/puma/cga.c +92 −0
  173. os/boot/puma/clock.c +154 −0
  174. os/boot/puma/conf.c +181 −0
  175. os/boot/puma/console.c +181 −0
  176. os/boot/puma/dat.h +205 −0
  177. os/boot/puma/div.s +122 −0
  178. os/boot/puma/donprint.c +332 −0
  179. os/boot/puma/dosboot.c +614 −0
  180. os/boot/puma/dosfs.h +110 −0
  181. os/boot/puma/ebsit.trap.c +206 −0
  182. os/boot/puma/ether.c +156 −0
  183. os/boot/puma/ether.h +82 −0
  184. os/boot/puma/ether8900.c +555 −0
  185. os/boot/puma/flash.c +226 −0
  186. os/boot/puma/fns.h +111 −0
  187. os/boot/puma/hard.c +773 −0
  188. os/boot/puma/io.h +3 −0
  189. os/boot/puma/ip.h +98 −0
  190. os/boot/puma/kbd.c +482 −0
  191. os/boot/puma/l.s +427 −0
  192. os/boot/puma/lib.h +107 −0
  193. os/boot/puma/main.c +552 −0
  194. os/boot/puma/mem.h +38 −0
  195. os/boot/puma/mkfile +71 −0
  196. os/boot/puma/outb.c +20 −0
  197. os/boot/puma/plan9boot.c +93 −0
  198. os/boot/puma/puma.c +123 −0
  199. os/boot/puma/puma.h +435 −0
  200. os/boot/puma/qio.c +128 −0
  201. os/boot/puma/rmap.c +104 −0
  202. os/boot/puma/squeeze.h +34 −0
  203. os/boot/puma/sum.c +13 −0
  204. os/boot/puma/trap.c +190 −0
  205. os/boot/puma/ureg.h +22 −0
  206. os/boot/puma/zqs.c +216 −0
  207. os/boot/rpcg/NOTICE +3 −0
  208. os/boot/rpcg/alarm.c +123 −0
  209. os/boot/rpcg/all.h +6 −0
  210. os/boot/rpcg/archrpcg.c +279 −0
  211. os/boot/rpcg/archrpcg.h +48 −0
  212. os/boot/rpcg/boot.h +8 −0
  213. os/boot/rpcg/bootp.c +509 −0
  214. os/boot/rpcg/clock.c +71 −0
  215. os/boot/rpcg/conf.c +173 −0
  216. os/boot/rpcg/console.c +173 −0
  217. os/boot/rpcg/cpm.c +162 −0
  218. os/boot/rpcg/crc32.c +42 −0
  219. os/boot/rpcg/dat.h +217 −0
  220. os/boot/rpcg/defont0.c +216 −0
  221. os/boot/rpcg/devether.c +157 −0
  222. os/boot/rpcg/devuart.c +230 −0
  223. os/boot/rpcg/dload.c +103 −0
  224. os/boot/rpcg/donprint.c +332 −0
  225. os/boot/rpcg/dosboot.c +614 −0
  226. os/boot/rpcg/dosfs.h +110 −0
  227. os/boot/rpcg/etherif.h +59 −0
  228. os/boot/rpcg/etherscc.c +411 −0
  229. os/boot/rpcg/fblt.c +531 −0
  230. os/boot/rpcg/flash.c +212 −0
  231. os/boot/rpcg/fns.h +118 −0
  232. os/boot/rpcg/g.mx +1987 −0
  233. os/boot/rpcg/gbitbltclip.c +52 −0
  234. os/boot/rpcg/gnot.h +71 −0
  235. os/boot/rpcg/i2c.c +360 −0
  236. os/boot/rpcg/initfads.c +187 −0
  237. os/boot/rpcg/initpaq.c +101 −0
  238. os/boot/rpcg/initrpcg.c +91 −0
  239. os/boot/rpcg/io.h +463 −0
  240. os/boot/rpcg/ip.h +98 −0
  241. os/boot/rpcg/l.s +388 −0
  242. os/boot/rpcg/lib.h +106 −0
  243. os/boot/rpcg/libg.h +418 −0
  244. os/boot/rpcg/main.c +527 −0
  245. os/boot/rpcg/mem.c +0 −0
  246. os/boot/rpcg/mem.h +94 −0
  247. os/boot/rpcg/mkfile +120 −0
  248. os/boot/rpcg/ms2.c +179 −0
  249. os/boot/rpcg/plan9boot.c +96 −0
  250. os/boot/rpcg/qbromrpcg +0 −0
  251. os/boot/rpcg/qio.c +128 −0
  252. os/boot/rpcg/rmap.c +104 −0
  253. os/boot/rpcg/screen.c +242 −0
  254. os/boot/rpcg/sload +0 −0
  255. os/boot/rpcg/sload.c +71 −0
  256. os/boot/rpcg/squeeze.h +34 −0
  257. os/boot/rpcg/trap.c +233 −0
  258. os/boot/rpcg/uartboot.c +189 −0
  259. os/boot/rpcg/ureg.h +43 −0
  260. os/boot/rpcg/zqs.c +234 −0
  261. os/cerf1110/Mk +8 −0
  262. os/cerf1110/NOTICE +2 −0
  263. os/cerf1110/README +22 −0
  264. os/cerf1110/archcerf.c +177 −0
  265. os/cerf1110/cerf +159 −0
  266. os/cerf1110/dat.h +135 −0
  267. os/cerf1110/devata.c +1200 −0
  268. os/cerf1110/devcerf.c +128 −0
  269. os/cerf1110/ether8900.c +702 −0
  270. os/cerf1110/fns.h +179 −0
  271. os/cerf1110/io.h +1 −0
  272. os/cerf1110/main.c +255 −0
  273. os/cerf1110/mem.h +200 −0
  274. os/cerf1110/mkfile +101 −0
  275. os/cerf250/NOTICE +2 −0
  276. os/cerf250/README +44 −0
  277. os/cerf250/archcerf.c +266 −0
  278. os/cerf250/cerf +163 −0
  279. os/cerf250/dat.h +135 −0
  280. os/cerf250/devpcf8563.c +371 −0
  281. os/cerf250/ether91c111.c +1056 −0
  282. os/cerf250/fns.h +168 −0
  283. os/cerf250/io.h +1 −0
  284. os/cerf250/main.c +351 −0
  285. os/cerf250/mem.h +174 −0
  286. os/cerf250/mkfile +102 −0
  287. os/cerf250/uart.h +118 −0
  288. os/cerf405/NOTICE +3 −0
  289. os/cerf405/README +45 −0
  290. os/cerf405/cerf +139 −0
  291. os/cerf405/clock.c +159 −0
  292. os/cerf405/compile.c +34 −0
  293. os/cerf405/dat.h +159 −0
  294. os/cerf405/devboot.c +132 −0
  295. os/cerf405/devether.c +617 −0
  296. os/cerf405/devrtc.c +369 −0
  297. os/cerf405/devuart.c +1064 −0
  298. os/cerf405/etheremac.c +829 −0
  299. os/cerf405/etherif.h +37 −0
  300. os/cerf405/fns.h +147 −0
  301. os/cerf405/fpi.h +61 −0
  302. os/cerf405/fpipower.c +970 −0
  303. os/cerf405/gpio.c +106 −0
  304. os/cerf405/iic.c +605 −0
  305. os/cerf405/inb.s +127 −0
  306. os/cerf405/io.h +301 −0
  307. os/cerf405/l.s +795 −0
  308. os/cerf405/main.c +719 −0
  309. os/cerf405/mal.c +334 −0
  310. os/cerf405/mem.h +147 −0
  311. os/cerf405/mkfile +104 −0
  312. os/cerf405/mmu.c +122 −0
  313. os/cerf405/nand.c +96 −0
  314. os/cerf405/nofp.s +31 −0
  315. os/cerf405/pci.c +981 −0
  316. os/cerf405/physmem.h +22 −0
  317. os/cerf405/powerbreak.c +123 −0
  318. os/cerf405/rmap.c +106 −0
  319. os/cerf405/tlb.s +30 −0
  320. os/cerf405/trap.c +581 −0
  321. os/cerf405/uart.c +139 −0
  322. os/cerf405/uart.h +101 −0
  323. os/fads/NOTICE +4 −0
  324. os/fads/archfads.c +619 −0
  325. os/fads/archfads.h +33 −0
  326. os/fads/dat.h +162 −0
  327. os/fads/fads +121 −0
  328. os/fads/fns.h +117 −0
  329. os/fads/io.h +1 −0
  330. os/fads/main.c +392 −0
  331. os/fads/mem.h +157 −0
  332. os/fads/mkfile +107 −0
  333. os/fads/mmu.c +20 −0
  334. os/fads/tlb.s +23 −0
  335. os/init/README +5 −0
  336. os/init/bootinit.b +628 −0
  337. os/init/cerf405.b +598 −0
  338. os/init/cerfinit.b +612 −0
  339. os/init/evalinit.b +119 −0
  340. os/init/geninit.b +93 −0
  341. os/init/i4e.b +210 −0
  342. os/init/init.b +613 −0
  343. os/init/ipaqinit.b +697 −0
  344. os/init/ipeinit.b +620 −0
  345. os/init/jsinit.b +213 −0
  346. os/init/mkfile +27 −0
  347. os/init/mpcinit.b +383 −0
  348. os/init/pcdemo.b +273 −0
  349. os/init/pcinit.b +405 −0
  350. os/init/reminit.b +239 −0
  351. os/init/rpcginit.b +610 −0
  352. os/init/shell.b +97 −0
  353. os/init/soeinit.b +613 −0
  354. os/init/srvinit.b +209 −0
  355. os/init/wminit.b +231 −0
  356. os/ip/arp.c +681 −0
  357. os/ip/bootp.c +231 −0
  358. os/ip/compress.c +520 −0
  359. os/ip/devip.c +1419 −0
  360. os/ip/dhcp.c +447 −0
  361. os/ip/eipconvtest.c +152 −0
  362. os/ip/esp.c +866 −0
  363. os/ip/ethermedium.c +792 −0
  364. os/ip/gre.c +282 −0
  365. os/ip/icmp.c +490 −0
  366. os/ip/icmp6.c +917 −0
  367. os/ip/igmp.c +291 −0
  368. os/ip/ihbootp.c +323 −0
  369. os/ip/il.c +1408 −0
  370. os/ip/ip.c +805 −0
  371. os/ip/ip.h +673 −0
  372. os/ip/ipaux.c +730 −0
  373. os/ip/ipifc.c +1721 −0
  374. os/ip/ipmux.c +857 −0
  375. os/ip/iproute.c +852 −0
  376. os/ip/iprouter.c +56 −0
  377. os/ip/ipv6.c +747 −0
  378. os/ip/ipv6.h +185 −0
  379. os/ip/kernel.h +10 −0
  380. os/ip/loopbackmedium.c +121 −0
  381. os/ip/netdevmedium.c +153 −0
  382. os/ip/netlog.c +263 −0
  383. os/ip/nullmedium.c +39 −0
  384. os/ip/pktmedium.c +79 −0
  385. os/ip/plan9.c +36 −0
  386. os/ip/ppp.c +1656 −0
  387. os/ip/ppp.h +258 −0
  388. os/ip/pppmedium.c +192 −0
  389. os/ip/ptclbsum.c +72 −0
  390. os/ip/rudp.c +1085 −0
  391. os/ip/tcp.c +3177 −0
  392. os/ip/udp.c +649 −0
  393. os/ipaq1110/Mk +8 −0
  394. os/ipaq1110/NOTICE +6 −0
  395. os/ipaq1110/README +65 −0
  396. os/ipaq1110/archipaq.c +376 −0
  397. os/ipaq1110/dat.h +135 −0
  398. os/ipaq1110/defont.c +290 −0
  399. os/ipaq1110/devaudio.c +1056 −0
  400. os/ipaq1110/devipaq.c +762 −0
  401. os/ipaq1110/etherwavelan.c +1307 −0
  402. os/ipaq1110/fns.h +179 −0
  403. os/ipaq1110/inflate +0 −0
  404. os/ipaq1110/io.h +60 −0
  405. os/ipaq1110/ipaq +172 −0
  406. os/ipaq1110/lcd.c +185 −0
  407. os/ipaq1110/main.c +255 −0
  408. os/ipaq1110/mem.h +200 −0
  409. os/ipaq1110/mkfile +103 −0
  410. os/ipaq1110/screen.c +917 −0
  411. os/ipaq1110/screen.h +64 −0
  412. os/ipaq1110/tstdraw.b +107 −0
  413. os/ipaq1110/upd +4 −0
  414. os/ipengine/NOTICE +4 −0
  415. os/ipengine/README +40 −0
  416. os/ipengine/archipe.c +488 −0
  417. os/ipengine/archipe.h +32 −0
  418. os/ipengine/dat.h +162 −0
  419. os/ipengine/devfpga.c +389 −0
  420. os/ipengine/flash28f320b3b.c +43 −0
  421. os/ipengine/fns.h +120 −0
  422. os/ipengine/io.h +1 −0
  423. os/ipengine/ipe +109 −0
  424. os/ipengine/main.c +348 −0
  425. os/ipengine/mem.h +156 −0
  426. os/ipengine/mkfile +105 −0
  427. os/ipengine/mmu.c +20 −0
  428. os/ipengine/tlb.s +21 −0
  429. os/js/README +10 −0
  430. os/js/audio.h +9 −0
  431. os/js/clock.c +104 −0
  432. os/js/cs4231.h +20 −0
  433. os/js/dat.h +163 −0
  434. os/js/devcs4231.c +1186 −0
  435. os/js/devrtc.c +413 −0
  436. os/js/fns.h +110 −0
  437. os/js/fsv.c +198 −0
  438. os/js/io.h +224 −0
  439. os/js/iob.c +13 −0
  440. os/js/js +104 −0
  441. os/js/kbd.c +482 −0
  442. os/js/l.s +560 −0
  443. os/js/main.c +564 −0
  444. os/js/mem.h +149 −0
  445. os/js/mkfile +77 −0
  446. os/js/mmu.c +252 −0
  447. os/js/ns16552.h +81 −0
  448. os/js/rom.c +103 −0
  449. os/js/rom.h +57 −0
  450. os/js/screen.c +483 −0
  451. os/js/screen.h +49 −0
  452. os/js/softcursor.h +13 −0
  453. os/js/superio.c +216 −0
  454. os/js/trap.c +472 −0
  455. os/js/ureg.h +45 −0
  456. os/ks32/Mk +7 −0
  457. os/ks32/NOTICE +2 −0
  458. os/ks32/archevaluator7t.c +161 −0
  459. os/ks32/armv7.h +19 −0
  460. os/ks32/clock.c +287 −0
  461. os/ks32/dat.h +218 −0
  462. os/ks32/devuart.c +719 −0
  463. os/ks32/download.ps +1040 −0
  464. os/ks32/evaluator7t +110 −0
  465. os/ks32/fns.h +145 −0
  466. os/ks32/fpi.h +61 −0
  467. os/ks32/fpiarm.c +483 −0
  468. os/ks32/io.h +168 −0
  469. os/ks32/l.s +205 −0
  470. os/ks32/main.c +289 −0
  471. os/ks32/mem.h +54 −0
  472. os/ks32/mkfile +115 −0
  473. os/ks32/not.c +3 −0
  474. os/ks32/squirt +2 −0
  475. os/ks32/trap.c +525 −0
  476. os/manga/Mk +8 −0
  477. os/manga/archmanga.c +164 −0
  478. os/manga/clock.c +166 −0
  479. os/manga/dat.h +128 −0
  480. os/manga/devether.c +765 −0
  481. os/manga/devusb.c +931 −0
  482. os/manga/eswnotes +41 −0
  483. os/manga/ether8139.c +744 −0
  484. os/manga/etherif.h +44 −0
  485. os/manga/etherks8695.c +1169 −0
  486. os/manga/flashif.h +82 −0
  487. os/manga/fns.h +163 −0
  488. os/manga/fpi.h +61 −0
  489. os/manga/fpiarm.c +483 −0
  490. os/manga/gpio.c +75 −0
  491. os/manga/inb.c +85 −0
  492. os/manga/io.h +320 −0
  493. os/manga/ioring.c +72 −0
  494. os/manga/l.s +404 −0
  495. os/manga/main.c +317 −0
  496. os/manga/manga +137 −0
  497. os/manga/mem.h +133 −0
  498. os/manga/mkfile +89 −0
  499. os/manga/mmu.c +244 −0
  500. os/manga/pci.c +1007 −0
  501. os/manga/pinflate +0 −0
  502. os/manga/trap.c +498 −0
  503. os/manga/uartks8695.c +629 −0
  504. os/manga/usb.h +160 −0
  505. os/manga/usbuhci.c +1556 −0
  506. os/mpc/800io.h +666 −0
  507. os/mpc/NOTICE +3 −0
  508. os/mpc/clock.c +145 −0
  509. os/mpc/cpm.c +695 −0
  510. os/mpc/cpmtimer.c +179 −0
  511. os/mpc/devata.c +1194 −0
  512. os/mpc/devbench.c +243 −0
  513. os/mpc/devboot.c +132 −0
  514. os/mpc/devether.c +617 −0
  515. os/mpc/devpcmcia.c +1076 −0
  516. os/mpc/devrtc.c +258 −0
  517. os/mpc/devtouch.c +497 −0
  518. os/mpc/devuart.c +1450 −0
  519. os/mpc/dsp.c +289 −0
  520. os/mpc/dsp.h +62 −0
  521. os/mpc/etherif.h +37 −0
  522. os/mpc/etherscc.c +528 −0
  523. os/mpc/faultpower.c +49 −0
  524. os/mpc/fp.s +205 −0
  525. os/mpc/fpi.h +61 −0
  526. os/mpc/fpipower.c +970 −0
  527. os/mpc/i2c.c +439 −0
  528. os/mpc/i2c_spi.srx +149 −0
  529. os/mpc/inb.s +120 −0
  530. os/mpc/kbd.c +20 −0
  531. os/mpc/l.s +685 −0
  532. os/mpc/nofp.s +31 −0
  533. os/mpc/pcmcia.h +19 −0
  534. os/mpc/pit.c +68 −0
  535. os/mpc/powerbreak.c +123 −0
  536. os/mpc/rmap.c +106 −0
  537. os/mpc/screen.c +832 −0
  538. os/mpc/screen.h +60 −0
  539. os/mpc/spi.c +243 −0
  540. os/mpc/trap.c +554 −0
  541. os/mpc/usb.h +62 −0
  542. os/omap/README +4 −0
  543. os/pc/NOTICE +8 −0
  544. os/pc/README +9 −0
  545. os/pc/apbootstrap.h +15 −0
  546. os/pc/apbootstrap.s +110 −0
  547. os/pc/apic.c +378 −0
  548. os/pc/apm.c +151 −0
  549. os/pc/apmjump.s +98 −0
  550. os/pc/archmp.c +138 −0
  551. os/pc/audio.h +15 −0
  552. os/pc/cga.c +127 −0
  553. os/pc/cgamemscr.c +203 −0
  554. os/pc/crystal.h +1118 −0
  555. os/pc/dat.h +258 −0
  556. os/pc/devarch.c +940 −0
  557. os/pc/devds1620.c +368 −0
  558. os/pc/devether.c +539 −0
  559. os/pc/devfloppy.c +1082 −0
  560. os/pc/devi82365.c +1044 −0
  561. os/pc/devlm78.c +346 −0
  562. os/pc/devlpt.c +245 −0
  563. os/pc/devmouse.c +672 −0
  564. os/pc/devmpeg.c +1063 −0
  565. os/pc/devpccard.c +1949 −0
  566. os/pc/devpnp.c +652 −0
  567. os/pc/devrtc.c +461 −0
  568. os/pc/devtv.c +1826 −0
  569. os/pc/devusb.c +951 −0
  570. os/pc/devvga.c +620 −0
  571. os/pc/devzt5512.c +308 −0
  572. os/pc/dma.c +237 −0
  573. os/pc/ether2000.c +230 −0
  574. os/pc/ether2114x.c +1828 −0
  575. os/pc/ether589.c +214 −0
  576. os/pc/ether79c960.c +523 −0
  577. os/pc/ether79c970.c +640 −0
  578. os/pc/ether8003.c +271 −0
  579. os/pc/ether8139.c +755 −0
  580. os/pc/ether82543gc.c +1367 −0
  581. os/pc/ether82557.c +1325 −0
  582. os/pc/ether83815.c +994 −0
  583. os/pc/ether8390.c +812 −0
  584. os/pc/ether8390.h +74 −0
  585. os/pc/etherec2t.c +173 −0
  586. os/pc/etherelnk3.c +2132 −0
  587. os/pc/etherga620.c +1224 −0
  588. os/pc/etherga620fw.h +4858 −0
  589. os/pc/etherif.h +39 −0
  590. os/pc/etherigbe.c +1968 −0
  591. os/pc/etherrhine.c +734 −0
  592. os/pc/ethersmc.c +780 −0
  593. os/pc/etherwavelan.c +196 −0
  594. os/pc/flashif.h +82 −0
  595. os/pc/flashzpc.c +371 −0
  596. os/pc/floppy.h +183 −0
  597. os/pc/fns.h +162 −0
  598. os/pc/fpi.h +61 −0
  599. os/pc/fpi387.c +743 −0
  600. os/pc/fpsave.s +9 −0
  601. os/pc/i8250.c +328 −0
  602. os/pc/i8253.c +314 −0
  603. os/pc/i8259.c +199 −0
  604. os/pc/io.h +323 −0
  605. os/pc/kbd.c +477 −0
  606. os/pc/l.s +953 −0
  607. os/pc/main.c +457 −0
  608. os/pc/mem.h +144 −0
  609. os/pc/memory.c +570 −0
  610. os/pc/mkfile +83 −0
  611. os/pc/mmu.c +321 −0
  612. os/pc/mouse.c +84 −0
  613. os/pc/mp.c +815 −0
  614. os/pc/mp.h +225 −0
  615. os/pc/pc +139 −0
  616. os/pc/pc4e +145 −0
  617. os/pc/pcdisk +154 −0
  618. os/pc/pci.acid +252 −0
  619. os/pc/pci.c +1341 −0
  620. os/pc/pcidb.acid +2848 −0
  621. os/pc/pcmciamodem.c +75 −0
  622. os/pc/piix4smbus.c +213 −0
  623. os/pc/pix +153 −0
  624. os/pc/ps2mouse.c +84 −0
  625. os/pc/ptclbsum386.s +126 −0
  626. os/pc/screen.c +410 −0
  627. os/pc/screen.h +173 −0
  628. os/pc/sd53c8xx.c +2138 −0
  629. os/pc/sd53c8xx.i +773 −0
  630. os/pc/sd53c8xx.n +448 −0
  631. os/pc/sdata.c +2206 −0
  632. os/pc/sdmylex.c +1249 −0
  633. os/pc/sdscsi.c +394 −0
  634. os/pc/trap.c +571 −0
  635. os/pc/tv.h +15 −0
  636. os/pc/uarti8250.c +740 −0
  637. os/pc/uartisa.c +98 −0
  638. os/pc/uartpci.c +137 −0
  639. os/pc/usb.h +160 −0
  640. os/pc/usbuhci.c +1538 −0
  641. os/pc/vga.c +241 −0
  642. os/pc/vga.h +75 −0
  643. os/pc/vga3dfx.c +258 −0
  644. os/pc/vgaark2000pv.c +190 −0
  645. os/pc/vgabt485.c +245 −0
  646. os/pc/vgaclgd542x.c +291 −0
  647. os/pc/vgaclgd546x.c +277 −0
  648. os/pc/vgact65545.c +149 −0
  649. os/pc/vgacyber938x.c +225 −0
  650. os/pc/vgaet4000.c +270 −0
  651. os/pc/vgahiqvideo.c +274 −0
  652. os/pc/vgai81x.c +282 −0
  653. os/pc/vgamach64xx.c +1250 −0
  654. os/pc/vgamga2164w.c +289 −0
  655. os/pc/vgamga4xx.c +603 −0
  656. os/pc/vganeomagic.c +541 −0
  657. os/pc/vganvidia.c +373 −0
  658. os/pc/vgargb524.c +236 −0
  659. os/pc/vgas3.c +620 −0
  660. os/pc/vgasavage.c +571 −0
  661. os/pc/vgat2r4.c +586 −0
  662. os/pc/vgatvp3020.c +216 −0
  663. os/pc/vgatvp3026.c +189 −0
  664. os/pc/vgavmware.c +386 −0
  665. os/pc/vgax.c +102 −0
  666. os/pc/wavelan.c +1268 −0
  667. os/pc/wavelan.h +327 −0
  668. os/pc/x86break.c +138 −0
  669. os/pc/zoran.h +907 −0
  670. os/port/NOTICE +18 −0
  671. os/port/alarm.c +41 −0
  672. os/port/alloc.c +963 −0
  673. os/port/allocb.c +159 −0
  674. os/port/chan.c +1431 −0
  675. os/port/cis.c +539 −0
  676. os/port/dev.c +434 −0
  677. os/port/devXXX.c +147 −0
  678. os/port/devaudio.c +947 −0
  679. os/port/devbench.c +1165 −0
  680. os/port/devboot.c +150 −0
  681. os/port/devbridge.c +1206 −0
  682. os/port/devcap.c +248 −0
  683. os/port/devcons.c +1274 −0
  684. os/port/devdbg.c +1000 −0
  685. os/port/devdraw.c +2088 −0
  686. os/port/devds.c +605 −0
  687. os/port/devdup.c +151 −0
  688. os/port/devdynld.c +365 −0
  689. os/port/devenv.c +338 −0
  690. os/port/devflash.c +641 −0
  691. os/port/devftl.c +1365 −0
  692. os/port/devi2c.c +227 −0
  693. os/port/devindir.c +40 −0
  694. os/port/devkprof.c +230 −0
  695. os/port/devlogfs.c +1531 −0
  696. os/port/devloopback.c +743 −0
  697. os/port/devmnt.c +1204 −0
  698. os/port/devns16552.c +1090 −0
  699. os/port/devpci.c +227 −0
  700. os/port/devpipe.c +464 −0
  701. os/port/devpointer.c +279 −0
  702. os/port/devprof.c +722 −0
  703. os/port/devprog.c +1510 −0
  704. os/port/devroot.c +153 −0
  705. os/port/devsd.c +1474 −0
  706. os/port/devsign.c +446 −0
  707. os/port/devsrv.c +726 −0
  708. os/port/devssl.c +1436 −0
  709. os/port/devtest.c +125 −0
  710. os/port/devtinyfs.c +915 −0
  711. os/port/devtk.c +180 −0
  712. os/port/devuart.c +748 −0
  713. os/port/dial.c +417 −0
  714. os/port/dis.c +1125 −0
  715. os/port/discall.c +185 −0
  716. os/port/dynld.c +75 −0
  717. os/port/edf.c +626 −0
  718. os/port/edf.h +53 −0
  719. os/port/error.h +64 −0
  720. os/port/ethermii.c +238 −0
  721. os/port/ethermii.h +116 −0
  722. os/port/ethersink.c +65 −0
  723. os/port/exception.c +216 −0
  724. os/port/exportfs.c +1325 −0
  725. os/port/flashamd29f0x0.c +167 −0
  726. os/port/flashcfi16.c +134 −0
  727. os/port/flashcfi8.c +143 −0
  728. os/port/flashif.h +147 −0
  729. os/port/flashintel +179 −0
  730. os/port/flashnand.c +337 −0
  731. os/port/fpi.c +304 −0
  732. os/port/fpimem.c +136 −0
  733. os/port/inferno.c +1030 −0
  734. os/port/latin1.c +76 −0
  735. os/port/latin1.h +100 −0
  736. os/port/lib.h +211 −0
  737. os/port/log.c +186 −0
  738. os/port/master +89 −0
  739. os/port/master.local +10 −0
  740. os/port/mkdevc +216 −0
  741. os/port/mkdevlist +86 −0
  742. os/port/mkroot +119 −0
  743. os/port/mul64fract.c +39 −0
  744. os/port/netaux.c +67 −0
  745. os/port/netif.c +671 −0
  746. os/port/netif.h +134 −0
  747. os/port/nocache.c +49 −0
  748. os/port/nodynld.c +48 −0
  749. os/port/noenv.c +33 −0
  750. os/port/noscreen.c +9 −0
  751. os/port/parse.c +114 −0
  752. os/port/pgrp.c +278 −0
  753. os/port/portbreak.c +161 −0
  754. os/port/portclock.c +277 −0
  755. os/port/portdat.h +673 −0
  756. os/port/portfns.h +319 −0
  757. os/port/portmkfile +152 −0
  758. os/port/print.c +31 −0
  759. os/port/proc.c +788 −0
  760. os/port/qio.c +1529 −0
  761. os/port/qlock.c +111 −0
  762. os/port/random.c +156 −0
  763. os/port/rdb.c +112 −0
  764. os/port/sd.h +132 −0
  765. os/port/swcursor.c +358 −0
  766. os/port/sysfile.c +1125 −0
  767. os/port/taslock.c +126 −0
  768. os/port/tod.c +283 −0
  769. os/port/uart.h +104 −0
  770. os/port/xalloc.c +246 −0
  771. os/pxa/NOTICE +2 −0
  772. os/pxa/clock.c +318 −0
  773. os/pxa/devether.c +617 −0
  774. os/pxa/devrtc.c +169 −0
  775. os/pxa/devuart.c +1070 −0
  776. os/pxa/dma.c +244 −0
  777. os/pxa/etherif.h +41 −0
  778. os/pxa/fpi.h +61 −0
  779. os/pxa/fpiarm.c +483 −0
  780. os/pxa/gpio.c +88 −0
  781. os/pxa/i2c.c +561 −0
  782. os/pxa/l.s +548 −0
  783. os/pxa/mmu.c +252 −0
  784. os/pxa/pxaio.h +383 −0
  785. os/pxa/sa1110break.c +360 −0
  786. os/pxa/trap.c +587 −0
  787. os/rpcg/NOTICE +4 −0
  788. os/rpcg/archrpcg.c +428 −0
  789. os/rpcg/archrpcg.h +48 −0
  790. os/rpcg/clock.c +145 −0
  791. os/rpcg/dat.h +162 −0
  792. os/rpcg/fns.h +119 −0
  793. os/rpcg/io.h +1 −0
  794. os/rpcg/main.c +392 −0
  795. os/rpcg/mem.h +157 −0
  796. os/rpcg/mkfile +108 −0
  797. os/rpcg/mmu.c +20 −0
  798. os/rpcg/rpcg +122 −0
  799. os/rpcg/tlb.s +24 −0
  800. os/sa1110/clock.c +317 −0
  801. os/sa1110/devether.c +617 −0
  802. os/sa1110/devgpio.c +165 −0
  803. os/sa1110/devpcmcia.c +761 −0
  804. os/sa1110/devpower.c +377 −0
  805. os/sa1110/devrtc.c +169 −0
  806. os/sa1110/devuart.c +781 −0
  807. os/sa1110/dma.c +233 −0
  808. os/sa1110/etherif.h +41 −0
  809. os/sa1110/fpi.h +61 −0
  810. os/sa1110/fpiarm.c +483 −0
  811. os/sa1110/gscreen.c +587 −0
  812. os/sa1110/gscreen.h +87 −0
  813. os/sa1110/i2c.h +16 −0
  814. os/sa1110/i2cgpio.c +274 −0
  815. os/sa1110/l.s +530 −0
  816. os/sa1110/l3gpio.c +246 −0
  817. os/sa1110/mmu.c +140 −0
  818. os/sa1110/sa1110break.c +360 −0
  819. os/sa1110/sa1110io.h +500 −0
  820. os/sa1110/softcursor.c +365 −0
  821. os/sa1110/suspend.c +161 −0
  822. os/sa1110/trap.c +601 −0
  823. utils/0a/a.h +183 −0
  824. utils/0a/a.y +588 −0
  825. utils/0a/l.s +703 −0
  826. utils/0a/lex.c +697 −0
  827. utils/0a/mkfile +30 −0
  828. utils/0c/cgen.c +1148 −0
  829. utils/0c/enam.c +118 −0
  830. utils/0c/gc.h +332 −0
  831. utils/0c/list.c +244 −0
  832. utils/0c/mkenam +15 −0
  833. utils/0c/mkfile +30 −0
  834. utils/0c/mul.c +608 −0
  835. utils/0c/peep.c +694 −0
  836. utils/0c/reg.c +1151 −0
  837. utils/0c/sgen.c +569 −0
  838. utils/0c/swt.c +727 −0
  839. utils/0c/txt.c +1483 −0
  840. utils/0c/v.out.h +201 −0
  841. utils/0l/Nt.c +77 −0
  842. utils/0l/Plan9.c +57 −0
  843. utils/0l/Posix.c +80 −0
  844. utils/0l/asm.c +1433 −0
  845. utils/0l/enam.c +122 −0
  846. utils/0l/l.h +329 −0
  847. utils/0l/list.c +277 −0
  848. utils/0l/mkfile +30 −0
  849. utils/0l/noop.c +420 −0
  850. utils/0l/obj.c +1384 −0
  851. utils/0l/optab.c +221 −0
  852. utils/0l/pass.c +498 −0
  853. utils/0l/sched.c +709 −0
  854. utils/0l/span.c +628 −0
  855. utils/1a/a.h +198 −0
  856. utils/1a/a.y +402 −0
  857. utils/1a/l.s +479 −0
  858. utils/1a/lex.c +925 −0
  859. utils/1a/mkfile +30 −0
  860. utils/1c/cgen.c +1396 −0
  861. utils/1c/enam.c +425 −0
  862. utils/1c/gc.h +339 −0
  863. utils/1c/list.c +319 −0
  864. utils/1c/mkfile +29 −0
  865. utils/1c/mul.c +174 −0
  866. utils/1c/peep.c +1060 −0
  867. utils/1c/reg.c +1221 −0
  868. utils/1c/sgen.c +694 −0
  869. utils/1c/swt.c +964 −0
  870. utils/1c/txt.c +903 −0
  871. utils/1l/Nt.c +77 −0
  872. utils/1l/Plan9.c +57 −0
  873. utils/1l/Posix.c +80 −0
  874. utils/1l/asm.c +1534 −0
  875. utils/1l/l.h +268 −0
  876. utils/1l/list.c +334 −0
  877. utils/1l/mkfile +32 −0
  878. utils/1l/obj.c +1380 −0
  879. utils/1l/optab.c +444 −0
  880. utils/1l/pass.c +673 −0
  881. utils/1l/span.c +515 −0
  882. utils/2a/a.h +200 −0
  883. utils/2a/a.y +540 −0
  884. utils/2a/l.s +479 −0
  885. utils/2a/lex.c +935 −0
  886. utils/2a/mkfile +30 −0
  887. utils/2c/2.out.h +523 −0
  888. utils/2c/Update +7 −0
  889. utils/2c/cgen.c +1404 −0
  890. utils/2c/enam.c +425 −0
  891. utils/2c/gc.h +357 −0
  892. utils/2c/list.c +384 −0
  893. utils/2c/mkfile +30 −0
  894. utils/2c/mul.c +174 −0
  895. utils/2c/peep.c +1076 −0
  896. utils/2c/reg.c +1275 −0
  897. utils/2c/sgen.c +819 −0
  898. utils/2c/swt.c +1046 −0
  899. utils/2c/txt.c +940 −0
  900. utils/2l/Nt.c +77 −0
  901. utils/2l/Plan9.c +57 −0
  902. utils/2l/Posix.c +80 −0
  903. utils/2l/asm.c +1569 −0
  904. utils/2l/l.h +263 −0
  905. utils/2l/list.c +395 −0
  906. utils/2l/mkfile +26 −0
  907. utils/2l/obj.c +1402 −0
  908. utils/2l/optab.c +444 −0
  909. utils/2l/pass.c +538 −0
  910. utils/2l/span.c +551 −0
  911. utils/5a/a.h +182 −0
  912. utils/5a/a.y +673 −0
  913. utils/5a/lex.c +689 −0
  914. utils/5a/mkfile +30 −0
  915. utils/5c/5.out.h +197 −0
  916. utils/5c/cgen.c +1156 −0
  917. utils/5c/enam.c +98 −0
  918. utils/5c/gc.h +349 −0
  919. utils/5c/list.c +304 −0
  920. utils/5c/mkenam +15 −0
  921. utils/5c/mkfile +30 −0
  922. utils/5c/mul.c +609 −0
  923. utils/5c/peep.c +1440 −0
  924. utils/5c/reg.c +1157 −0
  925. utils/5c/sgen.c +613 −0
  926. utils/5c/swt.c +757 −0
  927. utils/5c/txt.c +1249 −0
  928. utils/5coff/5coff.c +316 −0
  929. utils/5coff/NOTICE +27 −0
  930. utils/5coff/auxi.c +251 −0
  931. utils/5coff/auxi.h +46 −0
  932. utils/5coff/coff.c +642 −0
  933. utils/5coff/mkfile +23 −0
  934. utils/5coff/readcoff.c +298 −0
  935. utils/5cv/5cv.c +353 −0
  936. utils/5cv/mkfile +18 −0
  937. utils/5l/Nt.c +77 −0
  938. utils/5l/Plan9.c +57 −0
  939. utils/5l/Posix.c +80 −0
  940. utils/5l/asm.c +1793 −0
  941. utils/5l/l.h +444 −0
  942. utils/5l/list.c +360 −0
  943. utils/5l/mkfile +32 −0
  944. utils/5l/noop.c +894 −0
  945. utils/5l/obj.c +1557 −0
  946. utils/5l/optab.c +253 −0
  947. utils/5l/pass.c +942 −0
  948. utils/5l/span.c +1262 −0
  949. utils/5l/thumb.c +1637 −0
  950. utils/6c/6.out.h +820 −0
  951. utils/8a/a.h +194 −0
  952. utils/8a/a.y +520 −0
  953. utils/8a/l.s +704 −0
  954. utils/8a/lex.c +895 −0
  955. utils/8a/mkfile +30 −0
  956. utils/8c/8.out.h +445 −0
  957. utils/8c/cgen.c +1821 −0
  958. utils/8c/cgen64.c +2711 −0
  959. utils/8c/div.c +206 −0
  960. utils/8c/enam.c +337 −0
  961. utils/8c/gc.h +374 −0
  962. utils/8c/list.c +282 −0
  963. utils/8c/machcap.c +86 −0
  964. utils/8c/mkenam +15 −0
  965. utils/8c/mkfile +35 −0
  966. utils/8c/mul.c +428 −0
  967. utils/8c/peep.c +757 −0
  968. utils/8c/reg.c +1255 −0
  969. utils/8c/sgen.c +842 −0
  970. utils/8c/swt.c +647 −0
  971. utils/8c/txt.c +1410 −0
  972. utils/8l/Nt.c +77 −0
  973. utils/8l/Plan9.c +57 −0
  974. utils/8l/Posix.c +80 −0
  975. utils/8l/asm.c +502 −0
  976. utils/8l/l.h +349 −0
  977. utils/8l/list.c +292 −0
  978. utils/8l/mkfile +29 −0
  979. utils/8l/obj.c +1492 −0
  980. utils/8l/optab.c +654 −0
  981. utils/8l/pass.c +763 −0
  982. utils/8l/span.c +1387 −0
  983. utils/NOTICE +34 −0
  984. utils/acid/386 +146 −0
  985. utils/acid/B.sh +7 −0
  986. utils/acid/acid.h +317 −0
  987. utils/acid/arm +1 −0
  988. utils/acid/builtin.c +1285 −0
  989. utils/acid/dbg.y +402 −0
  990. utils/acid/dot.c +152 −0
os/NOTICE+31−0
@@ -0,0 +1,31 @@
1This copyright NOTICE applies to all files in this directory and
2subdirectories, unless another copyright notice appears in a given
3file or subdirectory. If you take substantial code from this software to use in
4other programs, you must somehow include with it an appropriate
5copyright notice that includes the copyright notice and the other
6notices below. It is fine (and often tidier) to do that in a separate
7file such as NOTICE, LICENCE or COPYING.
8
9 Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
10 Portions Copyright © 1997-1999 Vita Nuova Limited
11 Portions Copyright © 2000-2006 Vita Nuova Holdings Limited (www.vitanuova.com)
12 Revisions Copyright © 2000-2006 Lucent Technologies Inc. and others
13
14Permission is hereby granted, free of charge, to any person obtaining a copy
15of this software and associated documentation files (the "Software"), to deal
16in the Software without restriction, including without limitation the rights
17to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18copies of the Software, and to permit persons to whom the Software is
19furnished to do so, subject to the following conditions:
20
21The above copyright notice and this permission notice shall be included in
22all copies or substantial portions of the Software.
23
24THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30THE SOFTWARE.
31
os/README+32−0
@@ -0,0 +1,32 @@
1# a few sample native ports for different architectures
2
3cerf1110 arm Intrinsyc SA-1110 Cerf Cube
4ipaq1110 arm Strongarm SA1110 native kernel for Compaq iPAQ 36xx
5sa1110 arm SA1110 code common to most/all SA1110 platforms (eg, ipaq, cerf)
6
7cerf250 arm Intrinsyc Cerfboard250 (PXA250)
8gum arm Gumstix PXA255
9pxa arm general PXA support
10
11js sparc original port to Javastation-1, not recently tested
12
13ks32 arm ARM Evaluator 7t demo
14
15manga arm Micrel KS8695P ARM922 core with 4-port switch and PCI support
16
17cerf405 power Cerfcube 405EP (based on IBM 405EP processor)
18
19ipengine power Bright Star Engineering (www.brightstareng.com) ipEngine-1 (MPC823)
20rpcg power RPCG-Lite MPC823/850 board
21fads power MPC8xx FADS development board
22mpc power code common to ports to Motorola MPC8xx boards
23
24pc 386 basis for ports to various PC-based platforms
25
26# basic Inferno native kernel components
27port common native operating system components
28ip common Internet protocol stack, Ether and PPP media
29init common Limbo initialisation program (run by native kernel on startup)
30
31# sample bootstraps
32boot - directory of several bootstrap programs; see README there
os/boot/README+33−0
@@ -0,0 +1,33 @@
1Often the devices we use now come with some
2form of bootstrap (often annoyingly complicated,
3which gets in the way). Older boards were sometimes
4bare, and we had to provide something (often annoyingly
5complicated...). On the PC it's currently helpful to
6have something that can boot from disc or ether;
7since it's a thankless task to write such a thing, we
8use Plan 9's, and thank its authors.
9
10The current scheme on newer devices is to have a simple
11program that can put a stripped-down Inferno kernel into
12flash, and use that to boot from other devices (including over the net)
13as required during development.
14
15There are two distinct models for bootstrap in this directory.
16
17 Model I
18
19Each member of the first model is represented by a self-contained directory.
20They are derived from various ages of Plan 9's /sys/src/boot/pc.
21
22arm1110 arm a prefix to a gzip'd kernel to decompress it (runs after basic bootloader)
23pc 386 pc-specific bootstrap essentially identical to current Plan 9
24 and covered by the Lucent Public License; it uses
25libflate - zlib-style inflate/deflate library
26mpc power PowerPC bootstrap for FADS board derived from an older version
27 of Plan 9 but covered by our Inferno licence (because it came with Inferno)
28puma arm SA110 bootstrap for Teralogics Puma, also covered by the Inferno licence
29
30 Model II
31omap purpose-built bootstrap for the OMAP processor
32
33Not all of these are being distributed.
os/boot/arm1110/Mk+8−0
@@ -0,0 +1,8 @@
1#!/bin/rc
2rfork ne
3ROOT=/usr/inferno
4fn cd
5NPROC=3
6path=(/usr/inferno/Plan9/$cputype/bin $path)
7#bind /usr/inferno/mkconfig.dist /usr/inferno/mkconfig
8exec mk $*
os/boot/arm1110/dat.h+1−0
@@ -0,0 +1 @@
1/* deliberately empty */
os/boot/arm1110/donprint.c+332−0
@@ -0,0 +1,332 @@
1#include "u.h"
2#include "lib.h"
3
4#define PTR sizeof(char*)
5#define SHORT sizeof(int)
6#define INT sizeof(int)
7#define LONG sizeof(long)
8#define IDIGIT 30
9#define MAXCON 30
10
11#define FLONG (1<<0)
12#define FSHORT (1<<1)
13#define FUNSIGN (1<<2)
14
15typedef struct Op Op;
16struct Op
17{
18 char *p;
19 char *ep;
20 void *argp;
21 int f1;
22 int f2;
23 int f3;
24};
25
26static int noconv(Op*);
27static int cconv(Op*);
28static int dconv(Op*);
29static int hconv(Op*);
30static int lconv(Op*);
31static int oconv(Op*);
32static int sconv(Op*);
33static int uconv(Op*);
34static int xconv(Op*);
35static int Xconv(Op*);
36static int percent(Op*);
37
38static
39int (*fmtconv[MAXCON])(Op*) =
40{
41 noconv,
42 cconv, dconv, hconv, lconv,
43 oconv, sconv, uconv, xconv,
44 Xconv, percent,
45};
46static
47char fmtindex[128] =
48{
49 ['c'] 1,
50 ['d'] 2,
51 ['h'] 3,
52 ['l'] 4,
53 ['o'] 5,
54 ['s'] 6,
55 ['u'] 7,
56 ['x'] 8,
57 ['X'] 9,
58 ['%'] 10,
59};
60
61static int convcount = { 11 };
62static int ucase;
63
64static void
65PUT(Op *o, int c)
66{
67 static int pos;
68 int opos;
69
70 if(c == '\t'){
71 opos = pos;
72 pos = (opos+8) & ~7;
73 while(opos++ < pos && o->p < o->ep)
74 *o->p++ = ' ';
75 return;
76 }
77 if(o->p < o->ep){
78 *o->p++ = c;
79 pos++;
80 }
81 if(c == '\n')
82 pos = 0;
83}
84
85int
86fmtinstall(char c, int (*f)(Op*))
87{
88
89 c &= 0177;
90 if(fmtindex[c] == 0) {
91 if(convcount >= MAXCON)
92 return 1;
93 fmtindex[c] = convcount++;
94 }
95 fmtconv[fmtindex[c]] = f;
96 return 0;
97}
98
99char*
100donprint(char *p, char *ep, char *fmt, void *argp)
101{
102 int sf1, c;
103 Op o;
104
105 o.p = p;
106 o.ep = ep;
107 o.argp = argp;
108
109loop:
110 c = *fmt++;
111 if(c != '%') {
112 if(c == 0) {
113 if(o.p < o.ep)
114 *o.p = 0;
115 return o.p;
116 }
117 PUT(&o, c);
118 goto loop;
119 }
120 o.f1 = 0;
121 o.f2 = -1;
122 o.f3 = 0;
123 c = *fmt++;
124 sf1 = 0;
125 if(c == '-') {
126 sf1 = 1;
127 c = *fmt++;
128 }
129 while(c >= '0' && c <= '9') {
130 o.f1 = o.f1*10 + c-'0';
131 c = *fmt++;
132 }
133 if(sf1)
134 o.f1 = -o.f1;
135 if(c != '.')
136 goto l1;
137 c = *fmt++;
138 while(c >= '0' && c <= '9') {
139 if(o.f2 < 0)
140 o.f2 = 0;
141 o.f2 = o.f2*10 + c-'0';
142 c = *fmt++;
143 }
144l1:
145 if(c == 0)
146 fmt--;
147 c = (*fmtconv[fmtindex[c&0177]])(&o);
148 if(c < 0) {
149 o.f3 |= -c;
150 c = *fmt++;
151 goto l1;
152 }
153 o.argp = (char*)o.argp + c;
154 goto loop;
155}
156
157void
158strconv(char *o, Op *op, int f1, int f2)
159{
160 int n, c;
161 char *p;
162
163 n = strlen(o);
164 if(f1 >= 0)
165 while(n < f1) {
166 PUT(op, ' ');
167 n++;
168 }
169 for(p=o; c = *p++;)
170 if(f2 != 0) {
171 PUT(op, c);
172 f2--;
173 }
174 if(f1 < 0) {
175 f1 = -f1;
176 while(n < f1) {
177 PUT(op, ' ');
178 n++;
179 }
180 }
181}
182
183int
184numbconv(Op *op, int base)
185{
186 char b[IDIGIT];
187 int i, f, n, r;
188 long v;
189 short h;
190
191 f = 0;
192 switch(op->f3 & (FLONG|FSHORT|FUNSIGN)) {
193 case FLONG:
194 v = *(long*)op->argp;
195 r = LONG;
196 break;
197
198 case FUNSIGN|FLONG:
199 v = *(ulong*)op->argp;
200 r = LONG;
201 break;
202
203 case FSHORT:
204 h = *(int*)op->argp;
205 v = h;
206 r = SHORT;
207 break;
208
209 case FUNSIGN|FSHORT:
210 h = *(int*)op->argp;
211 v = (ushort)h;
212 r = SHORT;
213 break;
214
215 default:
216 v = *(int*)op->argp;
217 r = INT;
218 break;
219
220 case FUNSIGN:
221 v = *(unsigned*)op->argp;
222 r = INT;
223 break;
224 }
225 if(!(op->f3 & FUNSIGN) && v < 0) {
226 v = -v;
227 f = 1;
228 }
229 b[IDIGIT-1] = 0;
230 for(i = IDIGIT-2;; i--) {
231 n = (ulong)v % base;
232 n += '0';
233 if(n > '9'){
234 n += 'a' - ('9'+1);
235 if(ucase)
236 n += 'A'-'a';
237 }
238 b[i] = n;
239 if(i < 2)
240 break;
241 v = (ulong)v / base;
242 if(op->f2 >= 0 && i >= IDIGIT-op->f2)
243 continue;
244 if(v <= 0)
245 break;
246 }
247 if(f)
248 b[--i] = '-';
249 strconv(b+i, op, op->f1, -1);
250 return r;
251}
252
253static int
254noconv(Op *op)
255{
256
257 strconv("***", op, 0, -1);
258 return 0;
259}
260
261static int
262cconv(Op *op)
263{
264 char b[2];
265
266 b[0] = *(int*)op->argp;
267 b[1] = 0;
268 strconv(b, op, op->f1, -1);
269 return INT;
270}
271
272static int
273dconv(Op *op)
274{
275 return numbconv(op, 10);
276}
277
278static int
279hconv(Op*)
280{
281 return -FSHORT;
282}
283
284static int
285lconv(Op*)
286{
287 return -FLONG;
288}
289
290static int
291oconv(Op *op)
292{
293 return numbconv(op, 8);
294}
295
296static int
297sconv(Op *op)
298{
299 strconv(*(char**)op->argp, op, op->f1, op->f2);
300 return PTR;
301}
302
303static int
304uconv(Op*)
305{
306 return -FUNSIGN;
307}
308
309static int
310xconv(Op *op)
311{
312 return numbconv(op, 16);
313}
314
315static int
316Xconv(Op *op)
317{
318 int r;
319
320 ucase = 1;
321 r = numbconv(op, 16);
322 ucase = 0;
323 return r;
324}
325
326static int
327percent(Op *op)
328{
329
330 PUT(op, '%');
331 return 0;
332}
os/boot/arm1110/fns.h+7−0
@@ -0,0 +1,7 @@
1/*
2 * functions defined locally
3 */
4extern int gunzip(uchar *out, int outn, uchar *in, int inn);
5extern void delay(int ms);
6extern void serialputs(char *str, int n);
7extern void draincache(void);
os/boot/arm1110/il.s+99−0
@@ -0,0 +1,99 @@
1#include "mem.h"
2/*
3 * Entered here from Compaq's bootldr. First relocate to
4 * the location we're linked for and then copy back the
5 * decompressed kernel.
6 *
7 * All
8 */
9TEXT _start(SB), $-4
10 MOVW $setR12(SB), R12 /* load the SB */
11 MOVW $1, R0 /* dance to make 5l think that the magic */
12 MOVW $1, R1 /* numbers in WORDs below are being used */
13 CMP.S R0, R1 /* and to align them to where bootldr wants */
14 BEQ _start2
15 WORD $0x016f2818 /* magic number to say we are a kernel */
16 WORD $0xc0008000 /* entry point address */
17 WORD $0 /* size?, or end of data? */
18
19_start2:
20
21 /* SVC mode, interrupts disabled */
22 MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1
23 MOVW R1, CPSR
24
25 /* disable the MMU */
26 MOVW $0x130, R1
27 MCR CpMMU, 0, R1, C(CpControl), C(0x0)
28
29 /* enable caches */
30 MRC CpMMU, 0, R0, C(CpControl), C(0x0)
31 ORR $(CpCdcache|CpCicache|CpCwb), R0
32 MCR CpMMU, 0, R0, C(CpControl), C(0x0)
33
34 /* flush caches */
35 MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0
36 /* drain prefetch */
37 MOVW R0,R0
38 MOVW R0,R0
39 MOVW R0,R0
40 MOVW R0,R0
41
42 /* drain write buffer */
43 MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4
44
45 /* relocate to where we expect to be */
46 MOVW $(FLATESIZE),R3
47 MOVW $0xC0008000,R1
48 MOVW $0xC0200000,R2
49 ADD R1,R3
50_relloop:
51 MOVW (R1),R0
52 MOVW R0,(R2)
53 ADD $4,R1
54 ADD $4,R2
55 CMP.S R1,R3
56 BNE _relloop
57
58 MOVW $(MACHADDR+BY2PG), R13 /* stack */
59 SUB $4, R13 /* link */
60
61 /* jump to where we've been relocated */
62 MOVW $_relocated(SB),R15
63
64TEXT _relocated(SB),$-4
65 BL main(SB)
66 BL exit(SB)
67 /* we shouldn't get here */
68_mainloop:
69 B _mainloop
70 BL _div(SB) /* hack to get _div etc loaded */
71
72TEXT mypc(SB),$-4
73 MOVW R14,R0
74 RET
75
76TEXT draincache(SB),$-4
77 /* write back any dirty data */
78 MOVW $0xe0000000,R0
79 ADD $(8*1024),R0,R1
80_cfloop:
81 MOVW.P 32(R0),R2
82 CMP.S R0,R1
83 BNE _cfloop
84
85 /* drain write buffer and invalidate i&d cache contents */
86 MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4
87 MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0
88
89 /* drain prefetch */
90 MOVW R0,R0
91 MOVW R0,R0
92 MOVW R0,R0
93 MOVW R0,R0
94
95 /* disable caches */
96 MRC CpMMU, 0, R0, C(CpControl), C(0x0)
97 BIC $(CpCdcache|CpCicache|CpCwb), R0
98 MCR CpMMU, 0, R0, C(CpControl), C(0x0)
99 RET
os/boot/arm1110/imain.c+48−0
@@ -0,0 +1,48 @@
1#include "u.h"
2#include "lib.h"
3#include "fns.h"
4#include "dat.h"
5#include "mem.h"
6
7void
8main(void)
9{
10 void (*f)(void);
11 ulong *kernel;
12
13 print("inflating kernel\n");
14
15 kernel = (ulong*)(0xc0200000+20*1024);
16 if(gunzip((uchar*)0xc0008000, 2*1024*1024, (uchar*)kernel, FLATESIZE) > 0){
17 f = (void (*)(void))0xc0008010;
18 draincache();
19 } else {
20 print("inflation failed\n");
21 f = nil;
22 }
23 (*f)();
24}
25
26void
27exit(void)
28{
29
30 void (*f)(void);
31
32 delay(1000);
33
34 print("it's a wonderful day to die\n");
35 f = nil;
36 (*f)();
37}
38
39void
40delay(int ms)
41{
42 int i;
43
44 while(ms-- > 0){
45 for(i = 0; i < 1000; i++)
46 ;
47 }
48}
os/boot/arm1110/inflate.c+208−0
@@ -0,0 +1,208 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7#include <flate.h>
8
9typedef struct Biobuf Biobuf;
10
11struct Biobuf
12{
13 uchar *bp;
14 uchar *p;
15 uchar *ep;
16};
17
18static int header(Biobuf*);
19static int trailer(Biobuf*, Biobuf*);
20static int getc(void*);
21static ulong offset(Biobuf*);
22static int crcwrite(void *out, void *buf, int n);
23static ulong get4(Biobuf *b);
24static ulong Boffset(Biobuf *bp);
25
26/* GZIP flags */
27enum {
28 Ftext= (1<<0),
29 Fhcrc= (1<<1),
30 Fextra= (1<<2),
31 Fname= (1<<3),
32 Fcomment= (1<<4),
33
34 GZCRCPOLY = 0xedb88320UL,
35};
36
37static ulong *crctab;
38static ulong crc;
39
40int
41gunzip(uchar *out, int outn, uchar *in, int inn)
42{
43 Biobuf bin, bout;
44 int err;
45
46 crc = 0;
47 crctab = mkcrctab(GZCRCPOLY);
48 err = inflateinit();
49 if(err != FlateOk)
50 print("inflateinit failed: %s\n", flateerr(err));
51
52 bin.bp = bin.p = in;
53 bin.ep = in+inn;
54 bout.bp = bout.p = out;
55 bout.ep = out+outn;
56
57 err = header(&bin);
58 if(err != FlateOk)
59 return err;
60
61 err = inflate(&bout, crcwrite, &bin, getc);
62 if(err != FlateOk)
63 print("inflate failed: %s\n", flateerr(err));
64
65 err = trailer(&bout, &bin);
66 if(err != FlateOk)
67 return err;
68
69 return Boffset(&bout);
70}
71
72static int
73header(Biobuf *bin)
74{
75 int i, flag;
76
77 if(getc(bin) != 0x1f || getc(bin) != 0x8b){
78 print("bad magic\n");
79 return FlateCorrupted;
80 }
81 if(getc(bin) != 8){
82 print("unknown compression type\n");
83 return FlateCorrupted;
84 }
85
86 flag = getc(bin);
87
88 /* mod time */
89 get4(bin);
90
91 /* extra flags */
92 getc(bin);
93
94 /* OS type */
95 getc(bin);
96
97 if(flag & Fextra)
98 for(i=getc(bin); i>0; i--)
99 getc(bin);
100
101 /* name */
102 if(flag&Fname)
103 while(getc(bin) != 0)
104 ;
105
106 /* comment */
107 if(flag&Fcomment)
108 while(getc(bin) != 0)
109 ;
110
111 /* crc16 */
112 if(flag&Fhcrc) {
113 getc(bin);
114 getc(bin);
115 }
116
117 return FlateOk;
118}
119
120static int
121trailer(Biobuf *bout, Biobuf *bin)
122{
123 /* crc32 */
124 ulong x;
125
126 x = get4(bin);
127 if(crc != x){
128 print("crc mismatch %lux %lux\n", crc, x);
129 return FlateCorrupted;
130 }
131
132 /* length */
133 if(get4(bin) != Boffset(bout)){
134 print("bad output len\n");
135 return FlateCorrupted;
136 }
137 return FlateOk;
138}
139
140static ulong
141get4(Biobuf *b)
142{
143 ulong v;
144 int i, c;
145
146 v = 0;
147 for(i = 0; i < 4; i++){
148 c = getc(b);
149 v |= c << (i * 8);
150 }
151 return v;
152}
153
154static int
155getc(void *in)
156{
157 Biobuf *bp = in;
158
159 if((bp->p - bp->bp) % 10000 == 0)
160 print(".");
161 if(bp->p >= bp->ep)
162 return -1;
163 return *bp->p++;
164}
165
166static ulong
167Boffset(Biobuf *bp)
168{
169 return bp->p - bp->bp;
170}
171
172static int
173crcwrite(void *out, void *buf, int n)
174{
175 Biobuf *bp;
176
177 crc = blockcrc(crctab, crc, buf, n);
178 bp = out;
179 if(n > bp->ep-bp->p)
180 n = bp->ep-bp->p;
181 memmove(bp->p, buf, n);
182 bp->p += n;
183 return n;
184}
185
186#undef malloc
187#undef free
188
189static ulong ibrkp = ~0;
190
191void *
192malloc(ulong n)
193{
194 ulong rv;
195
196 if(ibrkp == ~0)
197 ibrkp = ((ulong)end)+1024*1024;
198 n = (n+3)>>2;
199 n <<= 2;
200 rv = ibrkp;
201 ibrkp += n;
202 return (void*)rv;
203}
204
205void
206free(void *)
207{
208}
os/boot/arm1110/io.h+261−0
@@ -0,0 +1,261 @@
1/*
2 * Definitions for IO devices. Used only in C.
3 */
4
5enum
6{
7 /* hardware counter frequency */
8 ClockFreq= 3686400,
9};
10
11/*
12 * IRQ's defined by SA1100
13 */
14enum
15{
16 IRQgpio0= 0,
17 IRQgpio1= 1,
18 IRQgpio2= 2,
19 IRQgpio3= 3,
20 IRQgpio4= 4,
21 IRQgpio5= 5,
22 IRQgpio6= 6,
23 IRQgpio7= 7,
24 IRQgpio8= 8,
25 IRQgpio9= 9,
26 IRQgpio10= 10,
27 IRQgpiohi= 11,
28 IRQlcd= 12,
29 IRQudc= 13,
30 IRQuart1b= 15,
31 IRQuart2= 16,
32 IRQuart3= 17,
33 IRQmcp= 18,
34 IRQssp= 19,
35 IRQdma0= 20,
36 IRQdma1= 21,
37 IRQdma2= 22,
38 IRQdma3= 23,
39 IRQdma4= 24,
40 IRQdma5= 25,
41 IRQtimer0= 26,
42 IRQtimer1= 27,
43 IRQtimer2= 28,
44 IRQtimer3= 29,
45 IRQsecond= 30,
46 IRQrtc= 31,
47};
48
49/*
50 * GPIO lines (signal names from compaq document). _i indicates input
51 * and _o output.
52 */
53enum
54{
55 GPIO_PWR_ON_i= 1<<0, /* power button */
56 GPIO_UP_IRQ_i= 1<<1, /* microcontroller interrupts */
57 GPIO_LDD8_o= 1<<2, /* LCD data 8-15 */
58 GPIO_LDD9_o= 1<<3,
59 GPIO_LDD10_o= 1<<4,
60 GPIO_LDD11_o= 1<<5,
61 GPIO_LDD12_o= 1<<6,
62 GPIO_LDD13_o= 1<<7,
63 GPIO_LDD14_o= 1<<8,
64 GPIO_LDD15_o= 1<<9,
65 GPIO_CARD_IND1_i= 1<<10, /* card inserted in PCMCIA socket 1 */
66 GPIO_CARD_IRQ1_i= 1<<11, /* PCMCIA socket 1 interrupt */
67 GPIO_CLK_SET0_o= 1<<12, /* clock selects for audio codec */
68 GPIO_CLK_SET1_o= 1<<13,
69 GPIO_L3_SDA_io= 1<<14, /* UDA1341 interface */
70 GPIO_L3_MODE_o= 1<<15,
71 GPIO_L3_SCLK_o= 1<<16,
72 GPIO_CARD_IND0_i= 1<<17, /* card inserted in PCMCIA socket 0 */
73 GPIO_KEY_ACT_i= 1<<18, /* hot key from cradle */
74 GPIO_SYS_CLK_i= 1<<19, /* clock from codec */
75 GPIO_BAT_FAULT_i= 1<<20, /* battery fault */
76 GPIO_CARD_IRQ0_i= 1<<21, /* PCMCIA socket 0 interrupt */
77 GPIO_LOCK_i= 1<<22, /* expansion pack lock/unlock */
78 GPIO_COM_DCD_i= 1<<23, /* DCD from UART3 */
79 GPIO_OPT_IRQ_i= 1<<24, /* expansion pack IRQ */
80 GPIO_COM_CTS_i= 1<<25, /* CTS from UART3 */
81 GPIO_COM_RTS_o= 1<<26, /* RTS to UART3 */
82 GPIO_OPT_IND_i= 1<<27, /* expansion pack inserted */
83
84/* Peripheral Unit GPIO pin assignments: alternate functions */
85 GPIO_SSP_TXD_o= 1<<10, /* SSP Transmit Data */
86 GPIO_SSP_RXD_i= 1<<11, /* SSP Receive Data */
87 GPIO_SSP_SCLK_o= 1<<12, /* SSP Sample CLocK */
88 GPIO_SSP_SFRM_o= 1<<13, /* SSP Sample FRaMe */
89 /* ser. port 1: */
90 GPIO_UART_TXD_o= 1<<14, /* UART Transmit Data */
91 GPIO_UART_RXD_i= 1<<15, /* UART Receive Data */
92 GPIO_SDLC_SCLK_io= 1<<16, /* SDLC Sample CLocK (I/O) */
93 GPIO_SDLC_AAF_o= 1<<17, /* SDLC Abort After Frame */
94 GPIO_UART_SCLK1_i= 1<<18, /* UART Sample CLocK 1 */
95 /* ser. port 4: */
96 GPIO_SSP_CLK_i= 1<<19, /* SSP external CLocK */
97 /* ser. port 3: */
98 GPIO_UART_SCLK3_i= 1<<20, /* UART Sample CLocK 3 */
99 /* ser. port 4: */
100 GPIO_MCP_CLK_i= 1<<21, /* MCP CLocK */
101 /* test controller: */
102 GPIO_TIC_ACK_o= 1<<21, /* TIC ACKnowledge */
103 GPIO_MBGNT_o= 1<<21, /* Memory Bus GraNT */
104 GPIO_TREQA_i= 1<<22, /* TIC REQuest A */
105 GPIO_MBREQ_i= 1<<22, /* Memory Bus REQuest */
106 GPIO_TREQB_i= 1<<23, /* TIC REQuest B */
107 GPIO_1Hz_o= 1<<25, /* 1 Hz clock */
108 GPIO_RCLK_o= 1<<26, /* internal (R) CLocK (O, fcpu/2) */
109 GPIO_32_768kHz_o= 1<<27, /* 32.768 kHz clock (O, RTC) */
110};
111
112/*
113 * types of interrupts
114 */
115enum
116{
117 GPIOrising,
118 GPIOfalling,
119 GPIOboth,
120 IRQ,
121};
122
123/* hardware registers */
124typedef struct Uartregs Uartregs;
125struct Uartregs
126{
127 ulong ctl[4];
128 ulong dummya;
129 ulong data;
130 ulong dummyb;
131 ulong status[2];
132};
133Uartregs *uart3regs;
134
135/* general purpose I/O lines control registers */
136typedef struct GPIOregs GPIOregs;
137struct GPIOregs
138{
139 ulong level; /* 1 == high */
140 ulong direction; /* 1 == output */
141 ulong set; /* a 1 sets the bit, 0 leaves it alone */
142 ulong clear; /* a 1 clears the bit, 0 leaves it alone */
143 ulong rising; /* rising edge detect enable */
144 ulong falling; /* falling edge detect enable */
145 ulong edgestatus; /* writing a 1 bit clears */
146 ulong altfunc; /* turn on alternate function for any set bits */
147};
148
149extern GPIOregs *gpioregs;
150
151/* extra general purpose I/O bits, output only */
152enum
153{
154 EGPIO_prog_flash= 1<<0,
155 EGPIO_pcmcia_reset= 1<<1,
156 EGPIO_exppack_reset= 1<<2,
157 EGPIO_codec_reset= 1<<3,
158 EGPIO_exp_nvram_power= 1<<4,
159 EGPIO_exp_full_power= 1<<5,
160 EGPIO_lcd_3v= 1<<6,
161 EGPIO_rs232_power= 1<<7,
162 EGPIO_lcd_ic_power= 1<<8,
163 EGPIO_ir_power= 1<<9,
164 EGPIO_audio_power= 1<<10,
165 EGPIO_audio_ic_power= 1<<11,
166 EGPIO_audio_mute= 1<<12,
167 EGPIO_fir= 1<<13, /* not set is sir */
168 EGPIO_lcd_5v= 1<<14,
169 EGPIO_lcd_9v= 1<<15,
170};
171extern ulong *egpioreg;
172
173/* Peripheral pin controller registers */
174typedef struct PPCregs PPCregs;
175struct PPCregs {
176 ulong direction;
177 ulong state;
178 ulong assignment;
179 ulong sleepdir;
180 ulong flags;
181};
182extern PPCregs *ppcregs;
183
184/* Synchronous Serial Port controller registers */
185typedef struct SSPregs SSPregs;
186struct SSPregs {
187 ulong control0;
188 ulong control1;
189 ulong dummy0;
190 ulong data;
191 ulong dummy1;
192 ulong status;
193};
194extern SSPregs *sspregs;
195
196/* Multimedia Communications Port controller registers */
197typedef struct MCPregs MCPregs;
198struct MCPregs {
199 ulong control0;
200 ulong reserved0;
201 ulong data0;
202 ulong data1;
203 ulong data2;
204 ulong reserved1;
205 ulong status;
206 ulong reserved[11];
207 ulong control1;
208};
209extern MCPregs *mcpregs;
210
211/*
212 * memory configuration
213 */
214enum
215{
216 /* bit shifts for pcmcia access time counters */
217 MECR_io0= 0,
218 MECR_attr0= 5,
219 MECR_mem0= 10,
220 MECR_fast0= 11,
221 MECR_io1= MECR_io0+16,
222 MECR_attr1= MECR_attr0+16,
223 MECR_mem1= MECR_mem0+16,
224 MECR_fast1= MECR_fast0+16,
225};
226
227typedef struct MemConfRegs MemConfRegs;
228struct MemConfRegs
229{
230 ulong mdcnfg; /* dram */
231 ulong mdcas00; /* dram banks 0/1 */
232 ulong mdcas01;
233 ulong mdcas02;
234 ulong msc0; /* static */
235 ulong msc1;
236 ulong mecr; /* pcmcia */
237 ulong mdrefr; /* dram refresh */
238 ulong mdcas20; /* dram banks 2/3 */
239 ulong mdcas21;
240 ulong mdcas22;
241 ulong msc2; /* static */
242 ulong smcnfg; /* SMROM config */
243};
244extern MemConfRegs *memconfregs;
245
246/*
247 * power management
248 */
249typedef struct PowerRegs PowerRegs;
250struct PowerRegs
251{
252 ulong pmcr; /* Power manager control register */
253 ulong pssr; /* Power manager sleep status register */
254 ulong pspr; /* Power manager scratch pad register */
255 ulong pwer; /* Power manager wakeup enable register */
256 ulong pcfr; /* Power manager general configuration register */
257 ulong ppcr; /* Power manager PPL configuration register */
258 ulong pgsr; /* Power manager GPIO sleep state register */
259 ulong posr; /* Power manager oscillator status register */
260};
261extern PowerRegs *powerregs;
os/boot/arm1110/l.s+454−0
@@ -0,0 +1,454 @@
1#include "mem.h"
2
3/*
4 * Entered here from Compaq's bootldr with MMU disabled.
5 */
6TEXT _start(SB), $-4
7 MOVW $setR12(SB), R12 /* load the SB */
8_main:
9 /* SVC mode, interrupts disabled */
10 MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1
11 MOVW R1, CPSR
12
13 /* disable the MMU */
14 MOVW $0x130, R1
15 MCR CpMMU, 0, R1, C(CpControl), C(0x0)
16
17 /* flush caches */
18 MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0
19 /* drain prefetch */
20 MOVW R0,R0
21 MOVW R0,R0
22 MOVW R0,R0
23 MOVW R0,R0
24
25 /* drain write buffer */
26 MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4
27
28 MOVW $(MACHADDR+BY2PG), R13 /* stack */
29 SUB $4, R13 /* link */
30 BL main(SB)
31 BL exit(SB)
32 /* we shouldn't get here */
33_mainloop:
34 B _mainloop
35 BL _div(SB) /* hack to get _div etc loaded */
36
37/* flush tlb's */
38TEXT mmuinvalidate(SB), $-4
39 MCR CpMMU, 0, R0, C(CpTLBFlush), C(0x7)
40 RET
41
42/* flush tlb's */
43TEXT mmuinvalidateaddr(SB), $-4
44 MCR CpMMU, 0, R0, C(CpTLBFlush), C(0x6), 1
45 RET
46
47/* write back and invalidate i and d caches */
48TEXT cacheflush(SB), $-4
49 /* write back any dirty data */
50 MOVW $0xe0000000,R0
51 ADD $(8*1024),R0,R1
52_cfloop:
53 MOVW.P 32(R0),R2
54 CMP.S R0,R1
55 BNE _cfloop
56
57 /* drain write buffer and invalidate i&d cache contents */
58 MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4
59 MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0
60
61 /* drain prefetch */
62 MOVW R0,R0
63 MOVW R0,R0
64 MOVW R0,R0
65 MOVW R0,R0
66 RET
67
68/* write back d cache */
69TEXT cachewb(SB), $-4
70 /* write back any dirty data */
71_cachewb:
72 MOVW $0xe0000000,R0
73 ADD $(8*1024),R0,R1
74_cwbloop:
75 MOVW.P 32(R0),R2
76 CMP.S R0,R1
77 BNE _cwbloop
78
79 /* drain write buffer */
80 MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4
81 RET
82
83/* write back a single cache line */
84TEXT cachewbaddr(SB), $-4
85 BIC $31,R0
86 MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 1
87 B _wbflush
88
89/* write back a region of cache lines */
90TEXT cachewbregion(SB), $-4
91 MOVW 4(FP),R1
92 CMP.S $(4*1024),R1
93 BGT _cachewb
94 ADD R0,R1
95 BIC $31,R0
96_cwbrloop:
97 MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 1
98 ADD $32,R0
99 CMP.S R0,R1
100 BGT _cwbrloop
101 B _wbflush
102
103/* invalidate the dcache */
104TEXT dcacheinvalidate(SB), $-4
105 MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x6)
106 RET
107
108/* invalidate the icache */
109TEXT icacheinvalidate(SB), $-4
110 MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x9)
111 RET
112
113/* drain write buffer */
114TEXT wbflush(SB), $-4
115_wbflush:
116 MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4
117 RET
118
119/* return cpu id */
120TEXT getcpuid(SB), $-4
121 MRC CpMMU, 0, R0, C(CpCPUID), C(0x0)
122 RET
123
124/* return fault status */
125TEXT getfsr(SB), $-4
126 MRC CpMMU, 0, R0, C(CpFSR), C(0x0)
127 RET
128
129/* return fault address */
130TEXT getfar(SB), $-4
131 MRC CpMMU, 0, R0, C(CpFAR), C(0x0)
132 RET
133
134/* return fault address */
135TEXT putfar(SB), $-4
136 MRC CpMMU, 0, R0, C(CpFAR), C(0x0)
137 RET
138
139/* set the translation table base */
140TEXT putttb(SB), $-4
141 MCR CpMMU, 0, R0, C(CpTTB), C(0x0)
142 RET
143
144/*
145 * enable mmu, i and d caches
146 */
147TEXT mmuenable(SB), $-4
148 MRC CpMMU, 0, R0, C(CpControl), C(0x0)
149 ORR $(CpCmmuena|CpCdcache|CpCicache|CpCwb), R0
150 MCR CpMMU, 0, R0, C(CpControl), C(0x0)
151 RET
152
153TEXT mmudisable(SB), $-4
154 MRC CpMMU, 0, R0, C(CpControl), C(0x0)
155 BIC $(CpCmmuena|CpCdcache|CpCicache|CpCwb|CpCvivec), R0
156 MCR CpMMU, 0, R0, C(CpControl), C(0x0)
157 RET
158
159/*
160 * use exception vectors at 0xffff0000
161 */
162TEXT mappedIvecEnable(SB), $-4
163 MRC CpMMU, 0, R0, C(CpControl), C(0x0)
164 ORR $(CpCvivec), R0
165 MCR CpMMU, 0, R0, C(CpControl), C(0x0)
166 RET
167TEXT mappedIvecDisable(SB), $-4
168 MRC CpMMU, 0, R0, C(CpControl), C(0x0)
169 BIC $(CpCvivec), R0
170 MCR CpMMU, 0, R0, C(CpControl), C(0x0)
171 RET
172
173/* set the translation table base */
174TEXT putdac(SB), $-4
175 MCR CpMMU, 0, R0, C(CpDAC), C(0x0)
176 RET
177
178/* set address translation pid */
179TEXT putpid(SB), $-4
180 MCR CpMMU, 0, R0, C(CpPID), C(0x0)
181 RET
182
183/*
184 * set the stack value for the mode passed in R0
185 */
186TEXT setr13(SB), $-4
187 MOVW 4(FP), R1
188
189 MOVW CPSR, R2
190 BIC $PsrMask, R2, R3
191 ORR R0, R3
192 MOVW R3, CPSR
193
194 MOVW R13, R0
195 MOVW R1, R13
196
197 MOVW R2, CPSR
198 RET
199
200/*
201 * exception vectors, copied by trapinit() to somewhere useful
202 */
203
204TEXT vectors(SB), $-4
205 MOVW 0x18(R15), R15 /* reset */
206 MOVW 0x18(R15), R15 /* undefined */
207 MOVW 0x18(R15), R15 /* SWI */
208 MOVW 0x18(R15), R15 /* prefetch abort */
209 MOVW 0x18(R15), R15 /* data abort */
210 MOVW 0x18(R15), R15 /* reserved */
211 MOVW 0x18(R15), R15 /* IRQ */
212 MOVW 0x18(R15), R15 /* FIQ */
213
214TEXT vtable(SB), $-4
215 WORD $_vsvc(SB) /* reset, in svc mode already */
216 WORD $_vund(SB) /* undefined, switch to svc mode */
217 WORD $_vsvc(SB) /* swi, in svc mode already */
218 WORD $_vpabt(SB) /* prefetch abort, switch to svc mode */
219 WORD $_vdabt(SB) /* data abort, switch to svc mode */
220 WORD $_vsvc(SB) /* reserved */
221 WORD $_virq(SB) /* IRQ, switch to svc mode */
222 WORD $_vfiq(SB) /* FIQ, switch to svc mode */
223
224TEXT _vrst(SB), $-4
225 BL resettrap(SB)
226
227TEXT _vsvc(SB), $-4 /* SWI */
228 MOVW.W R14, -4(R13) /* ureg->pc = interupted PC */
229 MOVW SPSR, R14 /* ureg->psr = SPSR */
230 MOVW.W R14, -4(R13) /* ... */
231 MOVW $PsrMsvc, R14 /* ureg->type = PsrMsvc */
232 MOVW.W R14, -4(R13) /* ... */
233 MOVM.DB.W.S [R0-R14], (R13) /* save user level registers, at end r13 points to ureg */
234 MOVW $setR12(SB), R12 /* Make sure we've got the kernel's SB loaded */
235 MOVW R13, R0 /* first arg is pointer to ureg */
236 SUB $8, R13 /* space for argument+link */
237
238 BL syscall(SB)
239
240 ADD $(8+4*15), R13 /* make r13 point to ureg->type */
241 MOVW 8(R13), R14 /* restore link */
242 MOVW 4(R13), R0 /* restore SPSR */
243 MOVW R0, SPSR /* ... */
244 MOVM.DB.S (R13), [R0-R14] /* restore registers */
245 ADD $8, R13 /* pop past ureg->{type+psr} */
246 RFE /* MOVM.IA.S.W (R13), [R15] */
247
248TEXT _vund(SB), $-4 /* undefined */
249 MOVM.IA [R0-R4], (R13) /* free some working space */
250 MOVW $PsrMund, R0
251 B _vswitch
252
253TEXT _vpabt(SB), $-4 /* prefetch abort */
254 MOVM.IA [R0-R4], (R13) /* free some working space */
255 MOVW $PsrMabt, R0 /* r0 = type */
256 B _vswitch
257
258TEXT _vdabt(SB), $-4 /* prefetch abort */
259 MOVM.IA [R0-R4], (R13) /* free some working space */
260 MOVW $(PsrMabt+1), R0 /* r0 = type */
261 B _vswitch
262
263TEXT _virq(SB), $-4 /* IRQ */
264 MOVM.IA [R0-R4], (R13) /* free some working space */
265 MOVW $PsrMirq, R0 /* r0 = type */
266 B _vswitch
267
268 /*
269 * come here with type in R0 and R13 pointing above saved [r0-r4]
270 * and type in r0. we'll switch to SVC mode and then call trap.
271 */
272_vswitch:
273 MOVW SPSR, R1 /* save SPSR for ureg */
274 MOVW R14, R2 /* save interrupted pc for ureg */
275 MOVW R13, R3 /* save pointer to where the original [R0-R3] are */
276
277 /* switch to svc mode */
278 MOVW CPSR, R14
279 BIC $PsrMask, R14
280 ORR $(PsrDirq|PsrDfiq|PsrMsvc), R14
281 MOVW R14, CPSR
282
283 /* interupted code kernel or user? */
284 AND.S $0xf, R1, R4
285 BEQ _userexcep
286
287 /* here for trap from SVC mode */
288 MOVM.DB.W [R0-R2], (R13) /* set ureg->{type, psr, pc}; r13 points to ureg->type */
289 MOVM.IA (R3), [R0-R4] /* restore [R0-R4] from previous mode's stack */
290 MOVM.DB.W [R0-R14], (R13) /* save kernel level registers, at end r13 points to ureg */
291 MOVW $setR12(SB), R12 /* Make sure we've got the kernel's SB loaded */
292 MOVW R13, R0 /* first arg is pointer to ureg */
293 SUB $8, R13 /* space for argument+link (for debugger) */
294 MOVW $0xdeaddead,R11 /* marker */
295
296 BL trap(SB)
297
298 ADD $(8+4*15), R13 /* make r13 point to ureg->type */
299 MOVW 8(R13), R14 /* restore link */
300 MOVW 4(R13), R0 /* restore SPSR */
301 MOVW R0, SPSR /* ... */
302 MOVM.DB (R13), [R0-R14] /* restore registers */
303 ADD $8, R13 /* pop past ureg->{type+psr} */
304 RFE /* MOVM.IA.S.W (R13), [R15] */
305
306 /* here for trap from USER mode */
307_userexcep:
308 MOVM.DB.W [R0-R2], (R13) /* set ureg->{type, psr, pc}; r13 points to ureg->type */
309 MOVM.IA (R3), [R0-R4] /* restore [R0-R4] from previous mode's stack */
310 MOVM.DB.W.S [R0-R14], (R13) /* save kernel level registers, at end r13 points to ureg */
311 MOVW $setR12(SB), R12 /* Make sure we've got the kernel's SB loaded */
312 MOVW R13, R0 /* first arg is pointer to ureg */
313 SUB $8, R13 /* space for argument+link (for debugger) */
314
315 BL trap(SB)
316
317 ADD $(8+4*15), R13 /* make r13 point to ureg->type */
318 MOVW 8(R13), R14 /* restore link */
319 MOVW 4(R13), R0 /* restore SPSR */
320 MOVW R0, SPSR /* ... */
321 MOVM.DB.S (R13), [R0-R14] /* restore registers */
322 ADD $8, R13 /* pop past ureg->{type+psr} */
323 RFE /* MOVM.IA.S.W (R13), [R15] */
324
325TEXT _vfiq(SB), $-4 /* FIQ */
326 RFE /* FIQ is special, ignore it for now */
327
328/*
329 * This is the first jump from kernel to user mode.
330 * Fake a return from interrupt.
331 *
332 * Enter with R0 containing the user stack pointer.
333 * UTZERO + 0x20 is always the entry point.
334 *
335 */
336TEXT touser(SB),$-4
337 /* store the user stack pointer into the USR_r13 */
338 MOVM.DB.W [R0], (R13)
339 MOVM.S.IA.W (R13),[R13]
340
341 /* set up a PSR for user level */
342 MOVW $(PsrMusr), R0
343 MOVW R0,SPSR
344
345 /* save the PC on the stack */
346 MOVW $(UTZERO+0x20), R0
347 MOVM.DB.W [R0],(R13)
348
349 /* return from interrupt */
350 RFE /* MOVM.IA.S.W (R13), [R15] */
351
352/*
353 * here to jump to a newly forked process
354 */
355TEXT forkret(SB),$-4
356 ADD $(4*15), R13 /* make r13 point to ureg->type */
357 MOVW 8(R13), R14 /* restore link */
358 MOVW 4(R13), R0 /* restore SPSR */
359 MOVW R0, SPSR /* ... */
360 MOVM.DB.S (R13), [R0-R14] /* restore registers */
361 ADD $8, R13 /* pop past ureg->{type+psr} */
362 RFE /* MOVM.IA.S.W (R13), [R15] */
363
364TEXT splhi(SB), $-4
365 /* save caller pc in Mach */
366 MOVW $(MACHADDR+0x04),R2
367 MOVW R14,0(R2)
368 /* turn off interrupts */
369 MOVW CPSR, R0
370 ORR $(PsrDfiq|PsrDirq), R0, R1
371 MOVW R1, CPSR
372 RET
373
374TEXT spllo(SB), $-4
375 MOVW CPSR, R0
376 BIC $(PsrDfiq|PsrDirq), R0, R1
377 MOVW R1, CPSR
378 RET
379
380TEXT splx(SB), $-4
381 /* save caller pc in Mach */
382 MOVW $(MACHADDR+0x04),R2
383 MOVW R14,0(R2)
384 /* reset interrupt level */
385 MOVW R0, R1
386 MOVW CPSR, R0
387 MOVW R1, CPSR
388 RET
389
390TEXT splxpc(SB), $-4 /* for iunlock */
391 MOVW R0, R1
392 MOVW CPSR, R0
393 MOVW R1, CPSR
394 RET
395
396TEXT spldone(SB), $0
397 RET
398
399TEXT islo(SB), $-4
400 MOVW CPSR, R0
401 AND $(PsrDfiq|PsrDirq), R0
402 EOR $(PsrDfiq|PsrDirq), R0
403 RET
404
405TEXT cpsrr(SB), $-4
406 MOVW CPSR, R0
407 RET
408
409TEXT spsrr(SB), $-4
410 MOVW SPSR, R0
411 RET
412
413TEXT getcallerpc(SB), $-4
414 MOVW 0(R13), R0
415 RET
416
417TEXT tas(SB), $-4
418 MOVW R0, R1
419 MOVW $0xDEADDEAD, R2
420 SWPW R2, (R1), R0
421 RET
422
423TEXT setlabel(SB), $-4
424 MOVW R13, 0(R0) /* sp */
425 MOVW R14, 4(R0) /* pc */
426 MOVW $0, R0
427 RET
428
429TEXT gotolabel(SB), $-4
430 MOVW 0(R0), R13 /* sp */
431 MOVW 4(R0), R14 /* pc */
432 MOVW $1, R0
433 RET
434
435
436/* The first MCR instruction of this function needs to be on a cache-line
437 * boundary; to make this happen, it will be copied (in trap.c).
438 *
439 * Doze puts the machine into idle mode. Any interrupt will get it out
440 * at the next instruction (the RET, to be precise).
441 */
442TEXT _doze(SB), $-4
443 MOVW $UCDRAMZERO, R1
444 MOVW R0,R0
445 MOVW R0,R0
446 MOVW R0,R0
447 MOVW R0,R0
448 MOVW R0,R0
449 MOVW R0,R0
450 MOVW R0,R0
451 MCR CpPWR, 0, R0, C(CpTest), C(0x2), 2
452 MOVW (R1), R0
453 MCR CpPWR, 0, R0, C(CpTest), C(0x8), 2
454 RET
os/boot/arm1110/lib.h+143−0
@@ -0,0 +1,143 @@
1/*
2 * functions (possibly) linked in, complete, from libc.
3 */
4
5/*
6 * mem routines
7 */
8extern void *memccpy(void*, void*, int, long);
9extern void *memset(void*, int, long);
10extern int memcmp(void*, void*, long);
11extern void *memmove(void*, void*, long);
12extern void *memchr(void*, int, long);
13
14/*
15 * string routines
16 */
17extern char *strcat(char*, char*);
18extern char *strchr(char*, char);
19extern char *strrchr(char*, char);
20extern int strcmp(char*, char*);
21extern char *strcpy(char*, char*);
22extern char *strncat(char*, char*, long);
23extern char *strncpy(char*, char*, long);
24extern int strncmp(char*, char*, long);
25extern long strlen(char*);
26extern char* strstr(char*, char*);
27extern int atoi(char*);
28
29enum
30{
31 UTFmax = 3, /* maximum bytes per rune */
32 Runesync = 0x80, /* cannot represent part of a UTF sequence */
33 Runeself = 0x80, /* rune and UTF sequences are the same (<) */
34 Runeerror = 0x80, /* decoding error in UTF */
35};
36
37/*
38 * rune routines
39 */
40extern int runetochar(char*, Rune*);
41extern int chartorune(Rune*, char*);
42extern char* utfrune(char*, long);
43extern int utflen(char*);
44extern int runelen(long);
45
46extern int abs(int);
47
48/*
49 * print routines
50 */
51typedef struct Cconv Fconv;
52extern char* donprint(char*, char*, char*, void*);
53extern int sprint(char*, char*, ...);
54extern char* seprint(char*, char*, char*, ...);
55extern int snprint(char*, int, char*, ...);
56extern int print(char*, ...);
57
58/*
59 * one-of-a-kind
60 */
61extern char* cleanname(char*);
62extern ulong getcallerpc(void*);
63extern long strtol(char*, char**, int);
64extern ulong strtoul(char*, char**, int);
65extern vlong strtoll(char*, char**, int);
66extern uvlong strtoull(char*, char**, int);
67extern char etext[];
68extern char edata[];
69extern char end[];
70extern int getfields(char*, char**, int, int, char*);
71
72/*
73 * Syscall data structures
74 */
75#define MORDER 0x0003 /* mask for bits defining order of mounting */
76#define MREPL 0x0000 /* mount replaces object */
77#define MBEFORE 0x0001 /* mount goes before others in union directory */
78#define MAFTER 0x0002 /* mount goes after others in union directory */
79#define MCREATE 0x0004 /* permit creation in mounted directory */
80#define MCACHE 0x0010 /* cache some data */
81#define MMASK 0x001F /* all bits on */
82
83#define OREAD 0 /* open for read */
84#define OWRITE 1 /* write */
85#define ORDWR 2 /* read and write */
86#define OEXEC 3 /* execute, == read but check execute permission */
87#define OTRUNC 16 /* or'ed in (except for exec), truncate file first */
88#define OCEXEC 32 /* or'ed in, close on exec */
89#define ORCLOSE 64 /* or'ed in, remove on close */
90
91#define NCONT 0 /* continue after note */
92#define NDFLT 1 /* terminate after note */
93#define NSAVE 2 /* clear note but hold state */
94#define NRSTR 3 /* restore saved state */
95
96typedef struct Qid Qid;
97typedef struct Dir Dir;
98typedef struct Waitmsg Waitmsg;
99
100#define ERRLEN 64
101#define DIRLEN 116
102#define NAMELEN 28
103
104struct Qid
105{
106 ulong path;
107 ulong vers;
108};
109
110struct Dir
111{
112 char name[NAMELEN];
113 char uid[NAMELEN];
114 char gid[NAMELEN];
115 Qid qid;
116 ulong mode;
117 long atime;
118 long mtime;
119 vlong length;
120 short type;
121 short dev;
122};
123
124struct Waitmsg
125{
126 char pid[12]; /* of loved one */
127 char time[3*12]; /* of loved one and descendants */
128 char msg[ERRLEN];
129};
130
131/*
132 * locks
133 */
134typedef
135struct Lock {
136 int val;
137} Lock;
138
139extern int _tas(int*);
140
141extern void lock(Lock*);
142extern void unlock(Lock*);
143extern int canlock(Lock*);
os/boot/arm1110/map+10−0
@@ -0,0 +1,10 @@
1defn acidmap()
2{
3 local dfoffset;
4
5 dfoffset = map()[1][3];
6 map({"text", _start, etext, 0x20});
7 map({"data", etext+1, edata, dfoffset});
8 print("Set map for plan 9 kernel image\n");
9 print("btext ", _start, " etext ", etext, "\n");
10}
os/boot/arm1110/mem.h+215−0
@@ -0,0 +1,215 @@
1/*
2 * Memory and machine-specific definitions. Used in C and assembler.
3 */
4
5/*
6 * Sizes
7 */
8#define BI2BY 8 /* bits per byte */
9#define BI2WD 32 /* bits per word */
10#define BY2WD 4 /* bytes per word */
11#define BY2V 8 /* bytes per double word */
12#define BY2PG 4096 /* bytes per page */
13#define WD2PG (BY2PG/BY2WD) /* words per page */
14#define PGSHIFT 12 /* log(BY2PG) */
15#define ROUND(s, sz) (((s)+(sz-1))&~(sz-1))
16#define PGROUND(s) ROUND(s, BY2PG)
17#define BLOCKALIGN 8
18
19#define MAXMACH 1 /* max # cpus system can run */
20
21/*
22 * Time
23 */
24#define HZ (20) /* clock frequency */
25#define MS2HZ (1000/HZ) /* millisec per clock tick */
26#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */
27#define TK2MS(t) ((((ulong)(t))*1000)/HZ) /* ticks to milliseconds */
28#define MS2TK(t) ((((ulong)(t))*HZ)/1000) /* milliseconds to ticks */
29
30/*
31 * Virtual addresses:
32 *
33 * We direct map all discovered DRAM and the area twixt 0xe0000000 and
34 * 0xe8000000 used to provide zeros for cache flushing.
35 *
36 * Flash is mapped to 0xb0000000 and special registers are mapped
37 * on demand to areas starting at 0xa0000000.
38 *
39 * The direct mapping is convenient but not necessary. It means
40 * that we don't have to turn on the MMU till well into the
41 * kernel. This can be changed by providing a mapping in l.s
42 * before calling main.
43 */
44#define UZERO 0 /* base of user address space */
45#define UTZERO (UZERO+BY2PG) /* first address in user text */
46#define KZERO 0xC0000000 /* base of kernel address space */
47#define KTZERO 0xC0008000 /* first address in kernel text */
48#define EMEMZERO 0x90000000 /* 256 meg for add on memory */
49#define EMEMTOP 0xA0000000 /* ... */
50#define REGZERO 0xA0000000 /* 128 meg for mapspecial regs */
51#define REGTOP 0xA8000000 /* ... */
52#define FLASHZERO 0xB0000000 /* 128 meg for flash */
53#define FLASHTOP 0xB8000000 /* ... */
54#define DRAMZERO 0xC0000000 /* 128 meg for dram */
55#define DRAMTOP 0xC8000000 /* ... */
56#define UCDRAMZERO 0xC8000000 /* 128 meg for dram (uncached/unbuffered) */
57#define UCDRAMTOP 0xD0000000 /* ... */
58#define NULLZERO 0xE0000000 /* 128 meg for cache flush zeroes */
59#define NULLTOP 0xE8000000 /* ... */
60#define USTKTOP 0x2000000 /* byte just beyond user stack */
61#define USTKSIZE (8*1024*1024) /* size of user stack */
62#define TSTKTOP (USTKTOP-USTKSIZE) /* end of new stack in sysexec */
63#define TSTKSIZ 100
64#define MACHADDR (KZERO+0x00001000)
65#define EVECTORS 0xFFFF0000 /* virt base of exception vectors */
66
67#define KSTACK (16*1024) /* Size of kernel stack */
68
69#define FLATESIZE (700*1024) /* maximum size of compressed image */
70
71/*
72 * Offsets into flash
73 */
74#define Flash_bootldr (FLASHZERO+0x0) /* boot loader */
75#define Flash_kernel (FLASHZERO+0x10000) /* boot kernel */
76#define Flash_tar (FLASHZERO+0x100000) /* tar file containing fs.sac */
77
78/*
79 * virtual MMU
80 */
81#define PTEMAPMEM (1024*1024)
82#define PTEPERTAB (PTEMAPMEM/BY2PG)
83#define SEGMAPSIZE 1984
84#define SSEGMAPSIZE 16
85#define PPN(x) ((x)&~(BY2PG-1))
86
87/*
88 * SA1110 definitions
89 */
90
91/*
92 * memory physical addresses
93 */
94#define PHYSFLASH0 0x00000000
95#define PHYSDRAM0 0xC0000000
96#define PHYSNULL0 0xE0000000
97
98/*
99 * peripheral control module physical addresses
100 */
101#define USBREGS 0x80000000 /* serial port 0 - USB */
102#define UART1REGS 0x80010000 /* serial port 1 - UART */
103#define GPCLKREGS 0x80020060 /* serial port 1 - general purpose clock */
104#define UART2REGS 0x80030000 /* serial port 2 - low speed IR */
105#define HSSPREGS 0x80040060 /* serial port 2 - high speed IR */
106#define UART3REGS 0x80050000 /* serial port 3 - RS232 UART */
107#define MCPREGS 0x80060000 /* serial port 4 - multimedia comm port */
108#define SSPREGS 0x80070060 /* serial port 4 - synchronous serial port */
109#define OSTIMERREGS 0x90000000 /* operating system timer registers */
110#define POWERREGS 0x90020000 /* power management */
111#define GPIOREGS 0x90040000 /* 28 general purpose IO pins */
112#define INTRREGS 0x90050000 /* interrupt registers */
113#define PPCREGS 0x90060000 /* peripheral pin controller */
114#define MEMCONFREGS 0xA0000000 /* memory configuration */
115#define LCDREGS 0xB0100000 /* display */
116
117/*
118 * PCMCIA addresses
119 */
120#define PHYSPCM0REGS 0x20000000
121#define PYHSPCM0ATTR 0x28000000
122#define PYHSPCM0MEM 0x2C000000
123#define PHYSPCM1REGS 0x30000000
124#define PYHSPCM1ATTR 0x38000000
125#define PYHSPCM1MEM 0x3C000000
126
127/*
128 * Program Status Registers
129 */
130#define PsrMusr 0x00000010 /* mode */
131#define PsrMfiq 0x00000011
132#define PsrMirq 0x00000012
133#define PsrMsvc 0x00000013
134#define PsrMabt 0x00000017
135#define PsrMund 0x0000001B
136#define PsrMask 0x0000001F
137
138#define PsrDfiq 0x00000040 /* disable FIQ interrupts */
139#define PsrDirq 0x00000080 /* disable IRQ interrupts */
140
141#define PsrV 0x10000000 /* overflow */
142#define PsrC 0x20000000 /* carry/borrow/extend */
143#define PsrZ 0x40000000 /* zero */
144#define PsrN 0x80000000 /* negative/less than */
145
146/*
147 * Coprocessors
148 */
149#define CpMMU 15
150#define CpPWR 15
151
152/*
153 * Internal MMU coprocessor registers
154 */
155#define CpCPUID 0 /* R: */
156#define CpControl 1 /* R: */
157#define CpTTB 2 /* RW: translation table base */
158#define CpDAC 3 /* RW: domain access control */
159#define CpFSR 5 /* RW: fault status */
160#define CpFAR 6 /* RW: fault address */
161#define CpCacheFlush 7 /* W: cache flushing, wb draining*/
162#define CpTLBFlush 8 /* W: TLB flushing */
163#define CpRBFlush 9 /* W: Read Buffer ops */
164#define CpPID 13 /* RW: PID for virtual mapping */
165#define CpBpt 14 /* W: Breakpoint register */
166#define CpTest 15 /* W: Test, Clock and Idle Control */
167
168/*
169 * CpControl
170 */
171#define CpCmmuena 0x00000001 /* M: MMU enable */
172#define CpCalign 0x00000002 /* A: alignment fault enable */
173#define CpCdcache 0x00000004 /* C: data cache on */
174#define CpCwb 0x00000008 /* W: write buffer turned on */
175#define CpCi32 0x00000010 /* P: 32-bit program space */
176#define CpCd32 0x00000020 /* D: 32-bit data space */
177#define CpCbe 0x00000080 /* B: big-endian operation */
178#define CpCsystem 0x00000100 /* S: system permission */
179#define CpCrom 0x00000200 /* R: ROM permission */
180#define CpCicache 0x00001000 /* I: instruction cache on */
181#define CpCvivec 0x00002000 /* X: virtual interrupt vector adjust */
182
183/*
184 * fault codes
185 */
186#define FCterm 0x2 /* terminal */
187#define FCvec 0x0 /* vector */
188#define FCalignf 0x1 /* unaligned full word data access */
189#define FCalignh 0x3 /* unaligned half word data access */
190#define FCl1abort 0xc /* level 1 external abort on translation */
191#define FCl2abort 0xe /* level 2 external abort on translation */
192#define FCtransSec 0x5 /* section translation */
193#define FCtransPage 0x7 /* page translation */
194#define FCdomainSec 0x9 /* section domain */
195#define FCdomainPage 0x11 /* page domain */
196#define FCpermSec 0x9 /* section permissions */
197#define FCpermPage 0x11 /* page permissions */
198#define FCabortLFSec 0x4 /* external abort on linefetch for section */
199#define FCabortLFPage 0x6 /* external abort on linefetch for page */
200#define FCabortNLFSec 0x8 /* external abort on non-linefetch for section */
201#define FCabortNLFPage 0xa /* external abort on non-linefetch for page */
202
203/*
204 * PTE bits used by fault.h. mmu.c translates them to real values.
205 */
206#define PTEVALID (1<<0)
207#define PTERONLY 0 /* this is implied by the absence of PTEWRITE */
208#define PTEWRITE (1<<1)
209#define PTEUNCACHED (1<<2)
210#define PTEKERNEL (1<<3) /* no user access */
211
212/*
213 * H3650 specific definitions
214 */
215#define EGPIOREGS 0x49000000 /* Additional GPIO register */
os/boot/arm1110/mkfile+86−0
@@ -0,0 +1,86 @@
1<../../../mkconfig
2objtype=arm
3SYSTARG=$OSTARG
4OBJTYPE=arm
5BIN=$ROOT/Inferno/$OBJTYPE
6LIBDIR=$ROOT/Inferno/$OBJTYPE/lib
7LIBDIRS=../libflate $ROOT/libkern
8LIBS=\
9 libflate\
10 libkern\
11
12LIBFILES=${LIBS:%=$LIBDIR/%.a}
13<$ROOT/mkfiles/mkfile-$SYSTARG-$OBJTYPE
14
15BIN=$ROOT/Inferno/$OBJTYPE
16
17TARG=\
18 inflate\
19
20INFLATE=\
21 il.$O\
22 imain.$O\
23
24CORE=\
25 uart.$O\
26 inflate.$O\
27 donprint.$O\
28 print.$O\
29
30HFILES=\
31 mem.h\
32
33CFLAGS=-FVw -I. -I$ROOT/Inferno/$OBJTYPE/include -I$ROOT/include
34
35all:V: $TARG
36
37install:V: $BIN/$TARG
38
39$BIN/%: %
40 cp $stem $BIN/$stem
41
42inflate: $INFLATE $CORE $LIBFILES
43 $LD -o s$target -R4 -T0xC0200010 -l $prereq
44 $LD -o _$target -H5 -R4 -T0xC0200010 -l $prereq
45 dd -conv sync -ibs 20k -if _$target -of $target
46
47%.$O: %.s
48 $AS $stem.s
49
50%.$O: %.c
51 $CC $CFLAGS $stem.c
52
53%.$O: $HFILES
54
55clean:
56 rm -f *.[$OS] [$OS].out y.tab.? y.debug y.output $TARG _$TARG s$TARG
57
58
59# added to cause libflate to be made automatically:
60
61$ROOT/Inferno/$OBJTYPE/lib/lib%.a:Q: all-$SHELLTYPE
62 #
63
64rc-lib%.a nt-lib%.a:VQ:
65 echo '@{builtin cd ' $ROOT/lib$stem ';mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE install}'
66 @{builtin cd $ROOT/lib$stem ;mk 'SHELLTYPE='$SHELLTYPE 'SYSTARG='$SYSTARG 'OBJTYPE='$OBJTYPE install}
67
68sh-lib%.a:VQ:
69 echo "(cd $ROOT/lib$stem ; mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE install)"
70 (cd $ROOT/lib$stem ; mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE install)
71
72%-sh:QV:
73 for i in $LIBDIRS
74 do
75 echo "(cd $i ; mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE $stem)"
76 (cd $i; mk 'SHELLTYPE='$SHELLTYPE 'SYSTARG='$SYSTARG 'OBJTYPE='$OBJTYPE $stem)
77 done
78
79%-rc %-nt:QV:
80 for (i in $LIBDIRS)
81 {
82 echo '@{cd $i ; mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE $stem}'
83 @{cd $i; mk 'SHELLTYPE='$SHELLTYPE 'SYSTARG='$SYSTARG 'OBJTYPE='$OBJTYPE $stem}
84 }
85
86nuke:V: clean nuke-$SHELLTYPE
os/boot/arm1110/print.c+56−0
@@ -0,0 +1,56 @@
1#include "u.h"
2#include "lib.h"
3#include "fns.h"
4#include "dat.h"
5
6
7#define SIZE 1024
8
9int
10print(char *fmt, ...)
11{
12 char buf[SIZE], *out;
13 va_list arg;
14
15 va_start(arg, fmt);
16 out = donprint(buf, buf+SIZE, fmt, arg);
17 va_end(arg);
18 serialputs(buf, out-buf);
19 return out-buf;
20}
21
22int
23sprint(char *buf, char *fmt, ...)
24{
25 char *out;
26 va_list arg;
27
28 va_start(arg, fmt);
29 out = donprint(buf, buf+SIZE, fmt, arg);
30 va_end(arg);
31 return out-buf;
32}
33
34int
35snprint(char *buf, int len, char *fmt, ...)
36{
37 char *out;
38 va_list arg;
39
40 va_start(arg, fmt);
41 out = donprint(buf, buf+len, fmt, arg);
42 va_end(arg);
43 return out-buf;
44}
45
46char*
47seprint(char *buf, char *e, char *fmt, ...)
48{
49 char *out;
50 va_list arg;
51
52 va_start(arg, fmt);
53 out = donprint(buf, e, fmt, arg);
54 va_end(arg);
55 return out;
56}
os/boot/arm1110/uart.c+69−0
@@ -0,0 +1,69 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7
8enum
9{
10 /* ctl[0] bits */
11 Parity= 1<<0,
12 Even= 1<<1,
13 Stop2= 1<<2,
14 Bits8= 1<<3,
15 SCE= 1<<4, /* synchronous clock enable */
16 RCE= 1<<5, /* rx on falling edge of clock */
17 TCE= 1<<6, /* tx on falling edge of clock */
18
19 /* ctl[3] bits */
20 Rena= 1<<0, /* receiver enable */
21 Tena= 1<<1, /* transmitter enable */
22 Break= 1<<2, /* force TXD3 low */
23 Rintena= 1<<3, /* enable receive interrupt */
24 Tintena= 1<<4, /* enable transmitter interrupt */
25 Loopback= 1<<5, /* loop back data */
26
27 /* data bits */
28 DEparity= 1<<8, /* parity error */
29 DEframe= 1<<9, /* framing error */
30 DEoverrun= 1<<10, /* overrun error */
31
32 /* status[0] bits */
33 Tint= 1<<0, /* transmit fifo half full interrupt */
34 Rint0= 1<<1, /* receiver fifo 1/3-2/3 full */
35 Rint1= 1<<2, /* receiver fifo not empty and receiver idle */
36 Breakstart= 1<<3,
37 Breakend= 1<<4,
38 Fifoerror= 1<<5, /* fifo error */
39
40 /* status[1] bits */
41 Tbusy= 1<<0, /* transmitting */
42 Rnotempty= 1<<1, /* receive fifo not empty */
43 Tnotfull= 1<<2, /* transmit fifo not full */
44 ParityError= 1<<3,
45 FrameError= 1<<4,
46 Overrun= 1<<5,
47};
48
49Uartregs *uart3regs = UART3REGS;
50
51
52/*
53 * for iprint, just write it
54 */
55void
56serialputs(char *str, int n)
57{
58 Uartregs *ur;
59
60 ur = uart3regs;
61 while(n-- > 0){
62 /* wait for output ready */
63 while((ur->status[1] & Tnotfull) == 0)
64 ;
65 ur->data = *str++;
66 }
67 while((ur->status[1] & Tbusy))
68 ;
69}
os/boot/libflate/LICENCE+237−0
@@ -0,0 +1,237 @@
1Lucent Public License Version 1.02
2
3THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS PUBLIC
4LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE
5PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
6
71. DEFINITIONS
8
9"Contribution" means:
10
11 a. in the case of Lucent Technologies Inc. ("LUCENT"), the Original
12 Program, and
13 b. in the case of each Contributor,
14
15 i. changes to the Program, and
16 ii. additions to the Program;
17
18 where such changes and/or additions to the Program were added to the
19 Program by such Contributor itself or anyone acting on such
20 Contributor's behalf, and the Contributor explicitly consents, in
21 accordance with Section 3C, to characterization of the changes and/or
22 additions as Contributions.
23
24"Contributor" means LUCENT and any other entity that has Contributed a
25Contribution to the Program.
26
27"Distributor" means a Recipient that distributes the Program,
28modifications to the Program, or any part thereof.
29
30"Licensed Patents" mean patent claims licensable by a Contributor
31which are necessarily infringed by the use or sale of its Contribution
32alone or when combined with the Program.
33
34"Original Program" means the original version of the software
35accompanying this Agreement as released by LUCENT, including source
36code, object code and documentation, if any.
37
38"Program" means the Original Program and Contributions or any part
39thereof
40
41"Recipient" means anyone who receives the Program under this
42Agreement, including all Contributors.
43
442. GRANT OF RIGHTS
45
46 a. Subject to the terms of this Agreement, each Contributor hereby
47 grants Recipient a non-exclusive, worldwide, royalty-free copyright
48 license to reproduce, prepare derivative works of, publicly display,
49 publicly perform, distribute and sublicense the Contribution of such
50 Contributor, if any, and such derivative works, in source code and
51 object code form.
52
53 b. Subject to the terms of this Agreement, each Contributor hereby
54 grants Recipient a non-exclusive, worldwide, royalty-free patent
55 license under Licensed Patents to make, use, sell, offer to sell,
56 import and otherwise transfer the Contribution of such Contributor, if
57 any, in source code and object code form. The patent license granted
58 by a Contributor shall also apply to the combination of the
59 Contribution of that Contributor and the Program if, at the time the
60 Contribution is added by the Contributor, such addition of the
61 Contribution causes such combination to be covered by the Licensed
62 Patents. The patent license granted by a Contributor shall not apply
63 to (i) any other combinations which include the Contribution, nor to
64 (ii) Contributions of other Contributors. No hardware per se is
65 licensed hereunder.
66
67 c. Recipient understands that although each Contributor grants the
68 licenses to its Contributions set forth herein, no assurances are
69 provided by any Contributor that the Program does not infringe the
70 patent or other intellectual property rights of any other entity. Each
71 Contributor disclaims any liability to Recipient for claims brought by
72 any other entity based on infringement of intellectual property rights
73 or otherwise. As a condition to exercising the rights and licenses
74 granted hereunder, each Recipient hereby assumes sole responsibility
75 to secure any other intellectual property rights needed, if any. For
76 example, if a third party patent license is required to allow
77 Recipient to distribute the Program, it is Recipient's responsibility
78 to acquire that license before distributing the Program.
79
80 d. Each Contributor represents that to its knowledge it has sufficient
81 copyright rights in its Contribution, if any, to grant the copyright
82 license set forth in this Agreement.
83
843. REQUIREMENTS
85
86A. Distributor may choose to distribute the Program in any form under
87this Agreement or under its own license agreement, provided that:
88
89 a. it complies with the terms and conditions of this Agreement;
90
91 b. if the Program is distributed in source code or other tangible
92 form, a copy of this Agreement or Distributor's own license agreement
93 is included with each copy of the Program; and
94
95 c. if distributed under Distributor's own license agreement, such
96 license agreement:
97
98 i. effectively disclaims on behalf of all Contributors all warranties
99 and conditions, express and implied, including warranties or
100 conditions of title and non-infringement, and implied warranties or
101 conditions of merchantability and fitness for a particular purpose;
102 ii. effectively excludes on behalf of all Contributors all liability
103 for damages, including direct, indirect, special, incidental and
104 consequential damages, such as lost profits; and
105 iii. states that any provisions which differ from this Agreement are
106 offered by that Contributor alone and not by any other party.
107
108B. Each Distributor must include the following in a conspicuous
109 location in the Program:
110
111 Copyright (C) 2003, Lucent Technologies Inc. and others. All Rights
112 Reserved.
113
114C. In addition, each Contributor must identify itself as the
115originator of its Contribution in a manner that reasonably allows
116subsequent Recipients to identify the originator of the Contribution.
117Also, each Contributor must agree that the additions and/or changes
118are intended to be a Contribution. Once a Contribution is contributed,
119it may not thereafter be revoked.
120
1214. COMMERCIAL DISTRIBUTION
122
123Commercial distributors of software may accept certain
124responsibilities with respect to end users, business partners and the
125like. While this license is intended to facilitate the commercial use
126of the Program, the Distributor who includes the Program in a
127commercial product offering should do so in a manner which does not
128create potential liability for Contributors. Therefore, if a
129Distributor includes the Program in a commercial product offering,
130such Distributor ("Commercial Distributor") hereby agrees to defend
131and indemnify every Contributor ("Indemnified Contributor") against
132any losses, damages and costs (collectively"Losses") arising from
133claims, lawsuits and other legal actions brought by a third party
134against the Indemnified Contributor to the extent caused by the acts
135or omissions of such Commercial Distributor in connection with its
136distribution of the Program in a commercial product offering. The
137obligations in this section do not apply to any claims or Losses
138relating to any actual or alleged intellectual property infringement.
139In order to qualify, an Indemnified Contributor must: a) promptly
140notify the Commercial Distributor in writing of such claim, and b)
141allow the Commercial Distributor to control, and cooperate with the
142Commercial Distributor in, the defense and any related settlement
143negotiations. The Indemnified Contributor may participate in any such
144claim at its own expense.
145
146For example, a Distributor might include the Program in a commercial
147product offering, Product X. That Distributor is then a Commercial
148Distributor. If that Commercial Distributor then makes performance
149claims, or offers warranties related to Product X, those performance
150claims and warranties are such Commercial Distributor's responsibility
151alone. Under this section, the Commercial Distributor would have to
152defend claims against the Contributors related to those performance
153claims and warranties, and if a court requires any Contributor to pay
154any damages as a result, the Commercial Distributor must pay those
155damages.
156
1575. NO WARRANTY
158
159EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
160PROVIDED ON AN"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
161KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
162WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
163OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
164responsible for determining the appropriateness of using and
165distributing the Program and assumes all risks associated with its
166exercise of rights under this Agreement, including but not limited to
167the risks and costs of program errors, compliance with applicable
168laws, damage to or loss of data, programs or equipment, and
169unavailability or interruption of operations.
170
1716. DISCLAIMER OF LIABILITY
172
173EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
174ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
175INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
176WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
177LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
178NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
179DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
180HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
181
1827. EXPORT CONTROL
183
184Recipient agrees that Recipient alone is responsible for compliance
185with the United States export administration regulations (and the
186export control laws and regulation of any other countries).
187
1888. GENERAL
189
190If any provision of this Agreement is invalid or unenforceable under
191applicable law, it shall not affect the validity or enforceability of
192the remainder of the terms of this Agreement, and without further
193action by the parties hereto, such provision shall be reformed to the
194minimum extent necessary to make such provision valid and enforceable.
195
196If Recipient institutes patent litigation against a Contributor with
197respect to a patent applicable to software (including a cross-claim or
198counterclaim in a lawsuit), then any patent licenses granted by that
199Contributor to such Recipient under this Agreement shall terminate as
200of the date such litigation is filed. In addition, if Recipient
201institutes patent litigation against any entity (including a
202cross-claim or counterclaim in a lawsuit) alleging that the Program
203itself (excluding combinations of the Program with other software or
204hardware) infringes such Recipient's patent(s), then such Recipient's
205rights granted under Section 2(b) shall terminate as of the date such
206litigation is filed.
207
208All Recipient's rights under this Agreement shall terminate if it
209fails to comply with any of the material terms or conditions of this
210Agreement and does not cure such failure in a reasonable period of
211time after becoming aware of such noncompliance. If all Recipient's
212rights under this Agreement terminate, Recipient agrees to cease use
213and distribution of the Program as soon as reasonably practicable.
214However, Recipient's obligations under this Agreement and any licenses
215granted by Recipient relating to the Program shall continue and
216survive.
217
218LUCENT may publish new versions (including revisions) of this
219Agreement from time to time. Each new version of the Agreement will be
220given a distinguishing version number. The Program (including
221Contributions) may always be distributed subject to the version of the
222Agreement under which it was received. In addition, after a new
223version of the Agreement is published, Contributor may elect to
224distribute the Program (including its Contributions) under the new
225version. No one other than LUCENT has the right to modify this
226Agreement. Except as expressly stated in Sections 2(a) and 2(b) above,
227Recipient receives no rights or licenses to the intellectual property
228of any Contributor under this Agreement, whether expressly, by
229implication, estoppel or otherwise. All rights in the Program not
230expressly granted under this Agreement are reserved.
231
232This Agreement is governed by the laws of the State of New York and
233the intellectual property laws of the United States of America. No
234party to this Agreement will bring a legal action under this Agreement
235more than one year after the cause of action arose. Each party waives
236its rights to a jury trial in any resulting litigation.
237
os/boot/libflate/NOTICE+8−0
@@ -0,0 +1,8 @@
1Copyright © 2002 Lucent Technologies Inc.
2All Rights Reserved
3
4This software was originally developed for Plan 9.
5It is provided under the terms of the Lucent Public License, Version 1.02.
6
7Trivial modifications have been made to make it compile for Inferno.
8 Vita Nuova Holdings Limited.
os/boot/libflate/adler.c+71−0
@@ -0,0 +1,71 @@
1#include "lib9.h"
2#include <flate.h>
3
4enum
5{
6 ADLERITERS = 5552, /* max iters before can overflow 32 bits */
7 ADLERBASE = 65521 /* largest prime smaller than 65536 */
8};
9
10ulong
11adler32(ulong adler, void *vbuf, int n)
12{
13 ulong s1, s2;
14 uchar *buf, *ebuf;
15 int m;
16
17 buf = vbuf;
18 s1 = adler & 0xffff;
19 s2 = (adler >> 16) & 0xffff;
20 for(; n >= 16; n -= m){
21 m = n;
22 if(m > ADLERITERS)
23 m = ADLERITERS;
24 m &= ~15;
25 for(ebuf = buf + m; buf < ebuf; buf += 16){
26 s1 += buf[0];
27 s2 += s1;
28 s1 += buf[1];
29 s2 += s1;
30 s1 += buf[2];
31 s2 += s1;
32 s1 += buf[3];
33 s2 += s1;
34 s1 += buf[4];
35 s2 += s1;
36 s1 += buf[5];
37 s2 += s1;
38 s1 += buf[6];
39 s2 += s1;
40 s1 += buf[7];
41 s2 += s1;
42 s1 += buf[8];
43 s2 += s1;
44 s1 += buf[9];
45 s2 += s1;
46 s1 += buf[10];
47 s2 += s1;
48 s1 += buf[11];
49 s2 += s1;
50 s1 += buf[12];
51 s2 += s1;
52 s1 += buf[13];
53 s2 += s1;
54 s1 += buf[14];
55 s2 += s1;
56 s1 += buf[15];
57 s2 += s1;
58 }
59 s1 %= ADLERBASE;
60 s2 %= ADLERBASE;
61 }
62 if(n){
63 for(ebuf = buf + n; buf < ebuf; buf++){
64 s1 += buf[0];
65 s2 += s1;
66 }
67 s1 %= ADLERBASE;
68 s2 %= ADLERBASE;
69 }
70 return (s2 << 16) + s1;
71}
os/boot/libflate/crc.c+39−0
@@ -0,0 +1,39 @@
1#include "lib9.h"
2#include <flate.h>
3
4ulong*
5mkcrctab(ulong poly)
6{
7 ulong *crctab;
8 ulong crc;
9 int i, j;
10
11 crctab = malloc(256 * sizeof(ulong));
12 if(crctab == nil)
13 return nil;
14
15 for(i = 0; i < 256; i++){
16 crc = i;
17 for(j = 0; j < 8; j++){
18 if(crc & 1)
19 crc = (crc >> 1) ^ poly;
20 else
21 crc >>= 1;
22 }
23 crctab[i] = crc;
24 }
25 return crctab;
26}
27
28ulong
29blockcrc(ulong *crctab, ulong crc, void *vbuf, int n)
30{
31 uchar *buf, *ebuf;
32
33 crc ^= 0xffffffff;
34 buf = vbuf;
35 ebuf = buf + n;
36 while(buf < ebuf)
37 crc = crctab[(crc & 0xff) ^ *buf++] ^ (crc >> 8);
38 return crc ^ 0xffffffff;
39}
os/boot/libflate/deflate.c+1358−0
@@ -0,0 +1,1358 @@
1#include "lib9.h"
2#include <flate.h>
3
4typedef struct Chain Chain;
5typedef struct Chains Chains;
6typedef struct Dyncode Dyncode;
7typedef struct Huff Huff;
8typedef struct LZblock LZblock;
9typedef struct LZstate LZstate;
10
11enum
12{
13 /*
14 * deflate format paramaters
15 */
16 DeflateUnc = 0, /* uncompressed block */
17 DeflateFix = 1, /* fixed huffman codes */
18 DeflateDyn = 2, /* dynamic huffman codes */
19
20 DeflateEob = 256, /* end of block code in lit/len book */
21 DeflateMaxBlock = 64*1024-1, /* maximum size of uncompressed block */
22
23 DeflateMaxExp = 10, /* maximum expansion for a block */
24
25 LenStart = 257, /* start of length codes in litlen */
26 Nlitlen = 288, /* number of litlen codes */
27 Noff = 30, /* number of offset codes */
28 Nclen = 19, /* number of codelen codes */
29
30 MaxOff = 32*1024,
31 MinMatch = 3, /* shortest match possible */
32 MaxMatch = 258, /* longest match possible */
33
34 /*
35 * huffman code paramaters
36 */
37 MaxLeaf = Nlitlen,
38 MaxHuffBits = 16, /* max bits in a huffman code */
39 ChainMem = 2 * (MaxHuffBits - 1) * MaxHuffBits,
40
41 /*
42 * coding of the lz parse
43 */
44 LenFlag = 1 << 3,
45 LenShift = 4, /* leaves enough space for MinMatchMaxOff */
46 MaxLitRun = LenFlag - 1,
47
48 /*
49 * internal lz paramaters
50 */
51 DeflateOut = 4096, /* output buffer size */
52 BlockSize = 8192, /* attempted input read quanta */
53 DeflateBlock = DeflateMaxBlock & ~(BlockSize - 1),
54 MinMatchMaxOff = 4096, /* max profitable offset for small match;
55 * assumes 8 bits for len, 5+10 for offset
56 * DONT CHANGE WITHOUT CHANGING LZPARSE CONSTANTS
57 */
58 HistSlop = 512, /* must be at lead MaxMatch */
59 HistBlock = 64*1024,
60 HistSize = HistBlock + HistSlop,
61
62 HashLog = 13,
63 HashSize = 1<<HashLog,
64
65 MaxOffCode = 256, /* biggest offset looked up in direct table */
66
67 EstLitBits = 8,
68 EstLenBits = 4,
69 EstOffBits = 5,
70};
71
72/*
73 * knuth vol. 3 multiplicative hashing
74 * each byte x chosen according to rules
75 * 1/4 < x < 3/10, 1/3 x < < 3/7, 4/7 < x < 2/3, 7/10 < x < 3/4
76 * with reasonable spread between the bytes & their complements
77 *
78 * the 3 byte value appears to be as almost good as the 4 byte value,
79 * and might be faster on some machines
80 */
81/*
82#define hashit(c) (((ulong)(c) * 0x6b43a9) >> (24 - HashLog))
83*/
84#define hashit(c) ((((ulong)(c) & 0xffffff) * 0x6b43a9b5) >> (32 - HashLog))
85
86/*
87 * lempel-ziv style compression state
88 */
89struct LZstate
90{
91 uchar hist[HistSize];
92 ulong pos; /* current location in history buffer */
93 ulong avail; /* data available after pos */
94 int eof;
95 ushort hash[HashSize]; /* hash chains */
96 ushort nexts[MaxOff];
97 int now; /* pos in hash chains */
98 int dot; /* dawn of time in history */
99 int prevlen; /* lazy matching state */
100 int prevoff;
101 int maxcheck; /* compressor tuning */
102
103 uchar obuf[DeflateOut];
104 uchar *out; /* current position in the output buffer */
105 uchar *eout;
106 ulong bits; /* bit shift register */
107 int nbits;
108 int rbad; /* got an error reading the buffer */
109 int wbad; /* got an error writing the buffer */
110 int (*w)(void*, void*, int);
111 void *wr;
112
113 ulong totr; /* total input size */
114 ulong totw; /* total output size */
115 int debug;
116};
117
118struct LZblock
119{
120 ushort parse[DeflateMaxBlock / 2 + 1];
121 int lastv; /* value being constucted for parse */
122 ulong litlencount[Nlitlen];
123 ulong offcount[Noff];
124 ushort *eparse; /* limit for parse table */
125 int bytes; /* consumed from the input */
126 int excost; /* cost of encoding extra len & off bits */
127};
128
129/*
130 * huffman code table
131 */
132struct Huff
133{
134 short bits; /* length of the code */
135 ushort encode; /* the code */
136};
137
138/*
139 * encoding of dynamic huffman trees
140 */
141struct Dyncode
142{
143 int nlit;
144 int noff;
145 int nclen;
146 int ncode;
147 Huff codetab[Nclen];
148 uchar codes[Nlitlen+Noff];
149 uchar codeaux[Nlitlen+Noff];
150};
151
152static int deflateb(LZstate *lz, LZblock *lzb, void *rr, int (*r)(void*, void*, int));
153static int lzcomp(LZstate*, LZblock*, uchar*, ushort*, int finish);
154static void wrblock(LZstate*, int, ushort*, ushort*, Huff*, Huff*);
155static int bitcost(Huff*, ulong*, int);
156static int huffcodes(Dyncode*, Huff*, Huff*);
157static void wrdyncode(LZstate*, Dyncode*);
158static void lzput(LZstate*, ulong bits, int nbits);
159static void lzflushbits(LZstate*);
160static void lzflush(LZstate *lz);
161static void lzwrite(LZstate *lz, void *buf, int n);
162
163static int hufftabinit(Huff*, int, ulong*, int);
164static int mkgzprecode(Huff*, ulong *, int, int);
165
166static int mkprecode(Huff*, ulong *, int, int, ulong*);
167static void nextchain(Chains*, int);
168static void leafsort(ulong*, ushort*, int, int);
169
170/* conversion from len to code word */
171static int lencode[MaxMatch];
172
173/*
174 * conversion from off to code word
175 * off <= MaxOffCode ? offcode[off] : bigoffcode[off >> 7]
176*/
177static int offcode[MaxOffCode];
178static int bigoffcode[256];
179
180/* litlen code words LenStart-285 extra bits */
181static int litlenbase[Nlitlen-LenStart];
182static int litlenextra[Nlitlen-LenStart] =
183{
184/* 257 */ 0, 0, 0,
185/* 260 */ 0, 0, 0, 0, 0, 1, 1, 1, 1, 2,
186/* 270 */ 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
187/* 280 */ 4, 5, 5, 5, 5, 0, 0, 0
188};
189
190/* offset code word extra bits */
191static int offbase[Noff];
192static int offextra[] =
193{
194 0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
195 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
196 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
197 0, 0,
198};
199
200/* order code lengths */
201static int clenorder[Nclen] =
202{
203 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
204};
205
206/* static huffman tables */
207static Huff litlentab[Nlitlen];
208static Huff offtab[Noff];
209static Huff hofftab[Noff];
210
211/* bit reversal for brain dead endian swap in huffman codes */
212static uchar revtab[256];
213static ulong nlits;
214static ulong nmatches;
215
216int
217deflateinit(void)
218{
219 ulong bitcount[MaxHuffBits];
220 int i, j, ci, n;
221
222 /* byte reverse table */
223 for(i=0; i<256; i++)
224 for(j=0; j<8; j++)
225 if(i & (1<<j))
226 revtab[i] |= 0x80 >> j;
227
228 /* static Litlen bit lengths */
229 for(i=0; i<144; i++)
230 litlentab[i].bits = 8;
231 for(i=144; i<256; i++)
232 litlentab[i].bits = 9;
233 for(i=256; i<280; i++)
234 litlentab[i].bits = 7;
235 for(i=280; i<Nlitlen; i++)
236 litlentab[i].bits = 8;
237
238 memset(bitcount, 0, sizeof(bitcount));
239 bitcount[8] += 144 - 0;
240 bitcount[9] += 256 - 144;
241 bitcount[7] += 280 - 256;
242 bitcount[8] += Nlitlen - 280;
243
244 if(!hufftabinit(litlentab, Nlitlen, bitcount, 9))
245 return FlateInternal;
246
247 /* static offset bit lengths */
248 for(i = 0; i < Noff; i++)
249 offtab[i].bits = 5;
250
251 memset(bitcount, 0, sizeof(bitcount));
252 bitcount[5] = Noff;
253
254 if(!hufftabinit(offtab, Noff, bitcount, 5))
255 return FlateInternal;
256
257 bitcount[0] = 0;
258 bitcount[1] = 0;
259 if(!mkgzprecode(hofftab, bitcount, 2, MaxHuffBits))
260 return FlateInternal;
261
262 /* conversion tables for lens & offs to codes */
263 ci = 0;
264 for(i = LenStart; i < 286; i++){
265 n = ci + (1 << litlenextra[i - LenStart]);
266 litlenbase[i - LenStart] = ci;
267 for(; ci < n; ci++)
268 lencode[ci] = i;
269 }
270 /* patch up special case for len MaxMatch */
271 lencode[MaxMatch-MinMatch] = 285;
272 litlenbase[285-LenStart] = MaxMatch-MinMatch;
273
274 ci = 0;
275 for(i = 0; i < 16; i++){
276 n = ci + (1 << offextra[i]);
277 offbase[i] = ci;
278 for(; ci < n; ci++)
279 offcode[ci] = i;
280 }
281
282 ci = ci >> 7;
283 for(; i < 30; i++){
284 n = ci + (1 << (offextra[i] - 7));
285 offbase[i] = ci << 7;
286 for(; ci < n; ci++)
287 bigoffcode[ci] = i;
288 }
289 return FlateOk;
290}
291
292static void
293deflatereset(LZstate *lz, int level, int debug)
294{
295 memset(lz->nexts, 0, sizeof lz->nexts);
296 memset(lz->hash, 0, sizeof lz->hash);
297 lz->totr = 0;
298 lz->totw = 0;
299 lz->pos = 0;
300 lz->avail = 0;
301 lz->out = lz->obuf;
302 lz->eout = &lz->obuf[DeflateOut];
303 lz->prevlen = MinMatch - 1;
304 lz->prevoff = 0;
305 lz->now = MaxOff + 1;
306 lz->dot = lz->now;
307 lz->bits = 0;
308 lz->nbits = 0;
309 lz->maxcheck = (1 << level);
310 lz->maxcheck -= lz->maxcheck >> 2;
311 if(lz->maxcheck < 2)
312 lz->maxcheck = 2;
313 else if(lz->maxcheck > 1024)
314 lz->maxcheck = 1024;
315
316 lz->debug = debug;
317}
318
319int
320deflate(void *wr, int (*w)(void*, void*, int), void *rr, int (*r)(void*, void*, int), int level, int debug)
321{
322 LZstate *lz;
323 LZblock *lzb;
324 int ok;
325
326 lz = malloc(sizeof *lz + sizeof *lzb);
327 if(lz == nil)
328 return FlateNoMem;
329 lzb = (LZblock*)&lz[1];
330
331 deflatereset(lz, level, debug);
332 lz->w = w;
333 lz->wr = wr;
334 lz->wbad = 0;
335 lz->rbad = 0;
336 lz->eof = 0;
337 ok = FlateOk;
338 while(!lz->eof || lz->avail){
339 ok = deflateb(lz, lzb, rr, r);
340 if(ok != FlateOk)
341 break;
342 }
343 if(ok == FlateOk && lz->rbad)
344 ok = FlateInputFail;
345 if(ok == FlateOk && lz->wbad)
346 ok = FlateOutputFail;
347 free(lz);
348 return ok;
349}
350
351static int
352deflateb(LZstate *lz, LZblock *lzb, void *rr, int (*r)(void*, void*, int))
353{
354 Dyncode dyncode, hdyncode;
355 Huff dlitlentab[Nlitlen], dofftab[Noff], hlitlentab[Nlitlen];
356 ulong litcount[Nlitlen];
357 long nunc, ndyn, nfix, nhuff;
358 uchar *slop, *hslop;
359 ulong ep;
360 int i, n, m, mm, nslop;
361
362 memset(lzb->litlencount, 0, sizeof lzb->litlencount);
363 memset(lzb->offcount, 0, sizeof lzb->offcount);
364 lzb->litlencount[DeflateEob]++;
365
366 lzb->bytes = 0;
367 lzb->eparse = lzb->parse;
368 lzb->lastv = 0;
369 lzb->excost = 0;
370
371 slop = &lz->hist[lz->pos];
372 n = lz->avail;
373 while(n < DeflateBlock && (!lz->eof || lz->avail)){
374 /*
375 * fill the buffer as much as possible,
376 * while leaving room for MaxOff history behind lz->pos,
377 * and not reading more than we can handle.
378 *
379 * make sure we read at least HistSlop bytes.
380 */
381 if(!lz->eof){
382 ep = lz->pos + lz->avail;
383 if(ep >= HistBlock)
384 ep -= HistBlock;
385 m = HistBlock - MaxOff - lz->avail;
386 if(m > HistBlock - n)
387 m = HistBlock - n;
388 if(m > (HistBlock + HistSlop) - ep)
389 m = (HistBlock + HistSlop) - ep;
390 if(m & ~(BlockSize - 1))
391 m &= ~(BlockSize - 1);
392
393 /*
394 * be nice to the caller: stop reads that are too small.
395 * can only get here when we've already filled the buffer some
396 */
397 if(m < HistSlop){
398 if(!m || !lzb->bytes)
399 return FlateInternal;
400 break;
401 }
402
403 mm = (*r)(rr, &lz->hist[ep], m);
404 if(mm > 0){
405 /*
406 * wrap data to end if we're read it from the beginning
407 * this way, we don't have to wrap searches.
408 *
409 * wrap reads past the end to the beginning.
410 * this way, we can guarantee minimum size reads.
411 */
412 if(ep < HistSlop)
413 memmove(&lz->hist[ep + HistBlock], &lz->hist[ep], HistSlop - ep);
414 else if(ep + mm > HistBlock)
415 memmove(&lz->hist[0], &lz->hist[HistBlock], ep + mm - HistBlock);
416
417 lz->totr += mm;
418 n += mm;
419 lz->avail += mm;
420 }else{
421 if(mm < 0)
422 lz->rbad = 1;
423 lz->eof = 1;
424 }
425 }
426 ep = lz->pos + lz->avail;
427 if(ep > HistSize)
428 ep = HistSize;
429 if(lzb->bytes + ep - lz->pos > DeflateMaxBlock)
430 ep = lz->pos + DeflateMaxBlock - lzb->bytes;
431 m = lzcomp(lz, lzb, &lz->hist[ep], lzb->eparse, lz->eof);
432 lzb->bytes += m;
433 lz->pos = (lz->pos + m) & (HistBlock - 1);
434 lz->avail -= m;
435 }
436 if(lzb->lastv)
437 *lzb->eparse++ = lzb->lastv;
438 if(lzb->eparse > lzb->parse + nelem(lzb->parse))
439 return FlateInternal;
440 nunc = lzb->bytes;
441
442 if(!mkgzprecode(dlitlentab, lzb->litlencount, Nlitlen, MaxHuffBits)
443 || !mkgzprecode(dofftab, lzb->offcount, Noff, MaxHuffBits))
444 return FlateInternal;
445
446 ndyn = huffcodes(&dyncode, dlitlentab, dofftab);
447 if(ndyn < 0)
448 return FlateInternal;
449 ndyn += bitcost(dlitlentab, lzb->litlencount, Nlitlen)
450 + bitcost(dofftab, lzb->offcount, Noff)
451 + lzb->excost;
452
453 memset(litcount, 0, sizeof litcount);
454
455 nslop = nunc;
456 if(nslop > &lz->hist[HistSize] - slop)
457 nslop = &lz->hist[HistSize] - slop;
458
459 for(i = 0; i < nslop; i++)
460 litcount[slop[i]]++;
461 hslop = &lz->hist[HistSlop - nslop];
462 for(; i < nunc; i++)
463 litcount[hslop[i]]++;
464 litcount[DeflateEob]++;
465
466 if(!mkgzprecode(hlitlentab, litcount, Nlitlen, MaxHuffBits))
467 return FlateInternal;
468 nhuff = huffcodes(&hdyncode, hlitlentab, hofftab);
469 if(nhuff < 0)
470 return FlateInternal;
471 nhuff += bitcost(hlitlentab, litcount, Nlitlen);
472
473 nfix = bitcost(litlentab, lzb->litlencount, Nlitlen)
474 + bitcost(offtab, lzb->offcount, Noff)
475 + lzb->excost;
476
477 lzput(lz, lz->eof && !lz->avail, 1);
478
479 if(lz->debug){
480 fprint(2, "block: bytes=%lud entries=%ld extra bits=%d\n\tuncompressed=%lud fixed=%lud dynamic=%lud huffman=%lud\n",
481 nunc, lzb->eparse - lzb->parse, lzb->excost, (nunc + 4) * 8, nfix, ndyn, nhuff);
482 fprint(2, "\tnlit=%lud matches=%lud eof=%d\n", nlits, nmatches, lz->eof && !lz->avail);
483 }
484
485 if((nunc + 4) * 8 < ndyn && (nunc + 4) * 8 < nfix && (nunc + 4) * 8 < nhuff){
486 lzput(lz, DeflateUnc, 2);
487 lzflushbits(lz);
488
489 lzput(lz, nunc & 0xff, 8);
490 lzput(lz, (nunc >> 8) & 0xff, 8);
491 lzput(lz, ~nunc & 0xff, 8);
492 lzput(lz, (~nunc >> 8) & 0xff, 8);
493 lzflush(lz);
494
495 lzwrite(lz, slop, nslop);
496 lzwrite(lz, &lz->hist[HistSlop], nunc - nslop);
497 }else if(ndyn < nfix && ndyn < nhuff){
498 lzput(lz, DeflateDyn, 2);
499
500 wrdyncode(lz, &dyncode);
501 wrblock(lz, slop - lz->hist, lzb->parse, lzb->eparse, dlitlentab, dofftab);
502 lzput(lz, dlitlentab[DeflateEob].encode, dlitlentab[DeflateEob].bits);
503 }else if(nhuff < nfix){
504 lzput(lz, DeflateDyn, 2);
505
506 wrdyncode(lz, &hdyncode);
507
508 m = 0;
509 for(i = nunc; i > MaxLitRun; i -= MaxLitRun)
510 lzb->parse[m++] = MaxLitRun;
511 lzb->parse[m++] = i;
512
513 wrblock(lz, slop - lz->hist, lzb->parse, lzb->parse + m, hlitlentab, hofftab);
514 lzput(lz, hlitlentab[DeflateEob].encode, hlitlentab[DeflateEob].bits);
515 }else{
516 lzput(lz, DeflateFix, 2);
517
518 wrblock(lz, slop - lz->hist, lzb->parse, lzb->eparse, litlentab, offtab);
519 lzput(lz, litlentab[DeflateEob].encode, litlentab[DeflateEob].bits);
520 }
521
522 if(lz->eof && !lz->avail){
523 lzflushbits(lz);
524 lzflush(lz);
525 }
526 return FlateOk;
527}
528
529static void
530lzwrite(LZstate *lz, void *buf, int n)
531{
532 int nw;
533
534 if(n && lz->w){
535 nw = (*lz->w)(lz->wr, buf, n);
536 if(nw != n){
537 lz->w = nil;
538 lz->wbad = 1;
539 }else
540 lz->totw += n;
541 }
542}
543
544static void
545lzflush(LZstate *lz)
546{
547 lzwrite(lz, lz->obuf, lz->out - lz->obuf);
548 lz->out = lz->obuf;
549}
550
551static void
552lzput(LZstate *lz, ulong bits, int nbits)
553{
554 bits = (bits << lz->nbits) | lz->bits;
555 for(nbits += lz->nbits; nbits >= 8; nbits -= 8){
556 *lz->out++ = bits;
557 if(lz->out == lz->eout)
558 lzflush(lz);
559 bits >>= 8;
560 }
561 lz->bits = bits;
562 lz->nbits = nbits;
563}
564
565static void
566lzflushbits(LZstate *lz)
567{
568 if(lz->nbits)
569 lzput(lz, 0, 8 - (lz->nbits & 7));
570}
571
572/*
573 * write out a block of n samples,
574 * given lz encoding and counts for huffman tables
575 */
576static void
577wrblock(LZstate *out, int litoff, ushort *soff, ushort *eoff, Huff *litlentab, Huff *offtab)
578{
579 ushort *off;
580 int i, run, offset, lit, len, c;
581
582 if(out->debug > 2){
583 for(off = soff; off < eoff; ){
584 offset = *off++;
585 run = offset & MaxLitRun;
586 if(run){
587 for(i = 0; i < run; i++){
588 lit = out->hist[litoff & (HistBlock - 1)];
589 litoff++;
590 fprint(2, "\tlit %.2ux %c\n", lit, lit);
591 }
592 if(!(offset & LenFlag))
593 continue;
594 len = offset >> LenShift;
595 offset = *off++;
596 }else if(offset & LenFlag){
597 len = offset >> LenShift;
598 offset = *off++;
599 }else{
600 len = 0;
601 offset >>= LenShift;
602 }
603 litoff += len + MinMatch;
604 fprint(2, "\t<%d, %d>\n", offset + 1, len + MinMatch);
605 }
606 }
607
608 for(off = soff; off < eoff; ){
609 offset = *off++;
610 run = offset & MaxLitRun;
611 if(run){
612 for(i = 0; i < run; i++){
613 lit = out->hist[litoff & (HistBlock - 1)];
614 litoff++;
615 lzput(out, litlentab[lit].encode, litlentab[lit].bits);
616 }
617 if(!(offset & LenFlag))
618 continue;
619 len = offset >> LenShift;
620 offset = *off++;
621 }else if(offset & LenFlag){
622 len = offset >> LenShift;
623 offset = *off++;
624 }else{
625 len = 0;
626 offset >>= LenShift;
627 }
628 litoff += len + MinMatch;
629 c = lencode[len];
630 lzput(out, litlentab[c].encode, litlentab[c].bits);
631 c -= LenStart;
632 if(litlenextra[c])
633 lzput(out, len - litlenbase[c], litlenextra[c]);
634
635 if(offset < MaxOffCode)
636 c = offcode[offset];
637 else
638 c = bigoffcode[offset >> 7];
639 lzput(out, offtab[c].encode, offtab[c].bits);
640 if(offextra[c])
641 lzput(out, offset - offbase[c], offextra[c]);
642 }
643}
644
645/*
646 * look for the longest, closest string which matches
647 * the next prefix. the clever part here is looking for
648 * a string 1 longer than the previous best match.
649 *
650 * follows the recommendation of limiting number of chains
651 * which are checked. this appears to be the best heuristic.
652 */
653static int
654lzmatch(int now, int then, uchar *p, uchar *es, ushort *nexts, uchar *hist, int runlen, int check, int *m)
655{
656 uchar *s, *t;
657 int ml, off, last;
658
659 ml = check;
660 if(runlen >= 8)
661 check >>= 2;
662 *m = 0;
663 if(p + runlen >= es)
664 return runlen;
665 last = 0;
666 for(; check-- > 0; then = nexts[then & (MaxOff-1)]){
667 off = (ushort)(now - then);
668 if(off <= last || off > MaxOff)
669 break;
670 s = p + runlen;
671 t = hist + (((p - hist) - off) & (HistBlock-1));
672 t += runlen;
673 for(; s >= p; s--){
674 if(*s != *t)
675 goto matchloop;
676 t--;
677 }
678
679 /*
680 * we have a new best match.
681 * extend it to it's maximum length
682 */
683 t += runlen + 2;
684 s += runlen + 2;
685 for(; s < es; s++){
686 if(*s != *t)
687 break;
688 t++;
689 }
690 runlen = s - p;
691 *m = off - 1;
692 if(s == es || runlen > ml)
693 break;
694matchloop:;
695 last = off;
696 }
697 return runlen;
698}
699
700static int
701lzcomp(LZstate *lz, LZblock *lzb, uchar *ep, ushort *parse, int finish)
702{
703 ulong cont, excost, *litlencount, *offcount;
704 uchar *p, *q, *s, *es;
705 ushort *nexts, *hash;
706 int v, i, h, runlen, n, now, then, m, prevlen, prevoff, maxdefer;
707
708 litlencount = lzb->litlencount;
709 offcount = lzb->offcount;
710 nexts = lz->nexts;
711 hash = lz->hash;
712 now = lz->now;
713
714 p = &lz->hist[lz->pos];
715 if(lz->prevlen != MinMatch - 1)
716 p++;
717
718 /*
719 * hash in the links for any hanging link positions,
720 * and calculate the hash for the current position.
721 */
722 n = MinMatch;
723 if(n > ep - p)
724 n = ep - p;
725 cont = 0;
726 for(i = 0; i < n - 1; i++){
727 m = now - ((MinMatch-1) - i);
728 if(m < lz->dot)
729 continue;
730 s = lz->hist + (((p - lz->hist) - (now - m)) & (HistBlock-1));
731
732 cont = (s[0] << 16) | (s[1] << 8) | s[2];
733 h = hashit(cont);
734 prevoff = 0;
735 for(then = hash[h]; ; then = nexts[then & (MaxOff-1)]){
736 v = (ushort)(now - then);
737 if(v <= prevoff || v >= (MinMatch-1) - i)
738 break;
739 prevoff = v;
740 }
741 if(then == (ushort)m)
742 continue;
743 nexts[m & (MaxOff-1)] = hash[h];
744 hash[h] = m;
745 }
746 for(i = 0; i < n; i++)
747 cont = (cont << 8) | p[i];
748
749 /*
750 * now must point to the index in the nexts array
751 * corresponding to p's position in the history
752 */
753 prevlen = lz->prevlen;
754 prevoff = lz->prevoff;
755 maxdefer = lz->maxcheck >> 2;
756 excost = 0;
757 v = lzb->lastv;
758 for(;;){
759 es = p + MaxMatch;
760 if(es > ep){
761 if(!finish || p >= ep)
762 break;
763 es = ep;
764 }
765
766 h = hashit(cont);
767 runlen = lzmatch(now, hash[h], p, es, nexts, lz->hist, prevlen, lz->maxcheck, &m);
768
769 /*
770 * back out of small matches too far in the past
771 */
772 if(runlen == MinMatch && m >= MinMatchMaxOff){
773 runlen = MinMatch - 1;
774 m = 0;
775 }
776
777 /*
778 * record the encoding and increment counts for huffman trees
779 * if we get a match, defer selecting it until we check for
780 * a longer match at the next position.
781 */
782 if(prevlen >= runlen && prevlen != MinMatch - 1){
783 /*
784 * old match at least as good; use that one
785 */
786 n = prevlen - MinMatch;
787 if(v || n){
788 *parse++ = v | LenFlag | (n << LenShift);
789 *parse++ = prevoff;
790 }else
791 *parse++ = prevoff << LenShift;
792 v = 0;
793
794 n = lencode[n];
795 litlencount[n]++;
796 excost += litlenextra[n - LenStart];
797
798 if(prevoff < MaxOffCode)
799 n = offcode[prevoff];
800 else
801 n = bigoffcode[prevoff >> 7];
802 offcount[n]++;
803 excost += offextra[n];
804
805 runlen = prevlen - 1;
806 prevlen = MinMatch - 1;
807 nmatches++;
808 }else if(runlen == MinMatch - 1){
809 /*
810 * no match; just put out the literal
811 */
812 if(++v == MaxLitRun){
813 *parse++ = v;
814 v = 0;
815 }
816 litlencount[*p]++;
817 nlits++;
818 runlen = 1;
819 }else{
820 if(prevlen != MinMatch - 1){
821 /*
822 * longer match now. output previous literal,
823 * update current match, and try again
824 */
825 if(++v == MaxLitRun){
826 *parse++ = v;
827 v = 0;
828 }
829 litlencount[p[-1]]++;
830 nlits++;
831 }
832
833 prevoff = m;
834
835 if(runlen < maxdefer){
836 prevlen = runlen;
837 runlen = 1;
838 }else{
839 n = runlen - MinMatch;
840 if(v || n){
841 *parse++ = v | LenFlag | (n << LenShift);
842 *parse++ = prevoff;
843 }else
844 *parse++ = prevoff << LenShift;
845 v = 0;
846
847 n = lencode[n];
848 litlencount[n]++;
849 excost += litlenextra[n - LenStart];
850
851 if(prevoff < MaxOffCode)
852 n = offcode[prevoff];
853 else
854 n = bigoffcode[prevoff >> 7];
855 offcount[n]++;
856 excost += offextra[n];
857
858 prevlen = MinMatch - 1;
859 nmatches++;
860 }
861 }
862
863 /*
864 * update the hash for the newly matched data
865 * this is constructed so the link for the old
866 * match in this position must be at the end of a chain,
867 * and will expire when this match is added, ie it will
868 * never be examined by the match loop.
869 * add to the hash chain only if we have the real hash data.
870 */
871 for(q = p + runlen; p != q; p++){
872 if(p + MinMatch <= ep){
873 h = hashit(cont);
874 nexts[now & (MaxOff-1)] = hash[h];
875 hash[h] = now;
876 if(p + MinMatch < ep)
877 cont = (cont << 8) | p[MinMatch];
878 }
879 now++;
880 }
881 }
882
883 /*
884 * we can just store away the lazy state and
885 * pick it up next time. the last block will have finish set
886 * so we won't have any pending matches
887 * however, we need to correct for how much we've encoded
888 */
889 if(prevlen != MinMatch - 1)
890 p--;
891
892 lzb->excost += excost;
893 lzb->eparse = parse;
894 lzb->lastv = v;
895
896 lz->now = now;
897 lz->prevlen = prevlen;
898 lz->prevoff = prevoff;
899
900 return p - &lz->hist[lz->pos];
901}
902
903/*
904 * make up the dynamic code tables, and return the number of bits
905 * needed to transmit them.
906 */
907static int
908huffcodes(Dyncode *dc, Huff *littab, Huff *offtab)
909{
910 Huff *codetab;
911 uchar *codes, *codeaux;
912 ulong codecount[Nclen], excost;
913 int i, n, m, v, c, nlit, noff, ncode, nclen;
914
915 codetab = dc->codetab;
916 codes = dc->codes;
917 codeaux = dc->codeaux;
918
919 /*
920 * trim the sizes of the tables
921 */
922 for(nlit = Nlitlen; nlit > 257 && littab[nlit-1].bits == 0; nlit--)
923 ;
924 for(noff = Noff; noff > 1 && offtab[noff-1].bits == 0; noff--)
925 ;
926
927 /*
928 * make the code-length code
929 */
930 for(i = 0; i < nlit; i++)
931 codes[i] = littab[i].bits;
932 for(i = 0; i < noff; i++)
933 codes[i + nlit] = offtab[i].bits;
934
935 /*
936 * run-length compress the code-length code
937 */
938 excost = 0;
939 c = 0;
940 ncode = nlit+noff;
941 for(i = 0; i < ncode; ){
942 n = i + 1;
943 v = codes[i];
944 while(n < ncode && v == codes[n])
945 n++;
946 n -= i;
947 i += n;
948 if(v == 0){
949 while(n >= 11){
950 m = n;
951 if(m > 138)
952 m = 138;
953 codes[c] = 18;
954 codeaux[c++] = m - 11;
955 n -= m;
956 excost += 7;
957 }
958 if(n >= 3){
959 codes[c] = 17;
960 codeaux[c++] = n - 3;
961 n = 0;
962 excost += 3;
963 }
964 }
965 while(n--){
966 codes[c++] = v;
967 while(n >= 3){
968 m = n;
969 if(m > 6)
970 m = 6;
971 codes[c] = 16;
972 codeaux[c++] = m - 3;
973 n -= m;
974 excost += 3;
975 }
976 }
977 }
978
979 memset(codecount, 0, sizeof codecount);
980 for(i = 0; i < c; i++)
981 codecount[codes[i]]++;
982 if(!mkgzprecode(codetab, codecount, Nclen, 8))
983 return -1;
984
985 for(nclen = Nclen; nclen > 4 && codetab[clenorder[nclen-1]].bits == 0; nclen--)
986 ;
987
988 dc->nlit = nlit;
989 dc->noff = noff;
990 dc->nclen = nclen;
991 dc->ncode = c;
992
993 return 5 + 5 + 4 + nclen * 3 + bitcost(codetab, codecount, Nclen) + excost;
994}
995
996static void
997wrdyncode(LZstate *out, Dyncode *dc)
998{
999 Huff *codetab;
1000 uchar *codes, *codeaux;
1001 int i, v, c;
1002
1003 /*
1004 * write out header, then code length code lengths,
1005 * and code lengths
1006 */
1007 lzput(out, dc->nlit-257, 5);
1008 lzput(out, dc->noff-1, 5);
1009 lzput(out, dc->nclen-4, 4);
1010
1011 codetab = dc->codetab;
1012 for(i = 0; i < dc->nclen; i++)
1013 lzput(out, codetab[clenorder[i]].bits, 3);
1014
1015 codes = dc->codes;
1016 codeaux = dc->codeaux;
1017 c = dc->ncode;
1018 for(i = 0; i < c; i++){
1019 v = codes[i];
1020 lzput(out, codetab[v].encode, codetab[v].bits);
1021 if(v >= 16){
1022 if(v == 16)
1023 lzput(out, codeaux[i], 2);
1024 else if(v == 17)
1025 lzput(out, codeaux[i], 3);
1026 else /* v == 18 */
1027 lzput(out, codeaux[i], 7);
1028 }
1029 }
1030}
1031
1032static int
1033bitcost(Huff *tab, ulong *count, int n)
1034{
1035 ulong tot;
1036 int i;
1037
1038 tot = 0;
1039 for(i = 0; i < n; i++)
1040 tot += count[i] * tab[i].bits;
1041 return tot;
1042}
1043
1044static int
1045mkgzprecode(Huff *tab, ulong *count, int n, int maxbits)
1046{
1047 ulong bitcount[MaxHuffBits];
1048 int i, nbits;
1049
1050 nbits = mkprecode(tab, count, n, maxbits, bitcount);
1051 for(i = 0; i < n; i++){
1052 if(tab[i].bits == -1)
1053 tab[i].bits = 0;
1054 else if(tab[i].bits == 0){
1055 if(nbits != 0 || bitcount[0] != 1)
1056 return 0;
1057 bitcount[1] = 1;
1058 bitcount[0] = 0;
1059 nbits = 1;
1060 tab[i].bits = 1;
1061 }
1062 }
1063 if(bitcount[0] != 0)
1064 return 0;
1065 return hufftabinit(tab, n, bitcount, nbits);
1066}
1067
1068static int
1069hufftabinit(Huff *tab, int n, ulong *bitcount, int nbits)
1070{
1071 ulong code, nc[MaxHuffBits];
1072 int i, bits;
1073
1074 code = 0;
1075 for(bits = 1; bits <= nbits; bits++){
1076 code = (code + bitcount[bits-1]) << 1;
1077 nc[bits] = code;
1078 }
1079
1080 for(i = 0; i < n; i++){
1081 bits = tab[i].bits;
1082 if(bits){
1083 code = nc[bits]++ << (16 - bits);
1084 if(code & ~0xffff)
1085 return 0;
1086 tab[i].encode = revtab[code >> 8] | (revtab[code & 0xff] << 8);
1087 }
1088 }
1089 return 1;
1090}
1091
1092
1093/*
1094 * this should be in a library
1095 */
1096struct Chain
1097{
1098 ulong count; /* occurances of everything in the chain */
1099 ushort leaf; /* leaves to the left of chain, or leaf value */
1100 char col; /* ref count for collecting unused chains */
1101 char gen; /* need to generate chains for next lower level */
1102 Chain *up; /* Chain up in the lists */
1103};
1104
1105struct Chains
1106{
1107 Chain *lists[(MaxHuffBits - 1) * 2];
1108 ulong leafcount[MaxLeaf]; /* sorted list of leaf counts */
1109 ushort leafmap[MaxLeaf]; /* map to actual leaf number */
1110 int nleaf; /* number of leaves */
1111 Chain chains[ChainMem];
1112 Chain *echains;
1113 Chain *free;
1114 char col;
1115 int nlists;
1116};
1117
1118/*
1119 * fast, low space overhead algorithm for max depth huffman type codes
1120 *
1121 * J. Katajainen, A. Moffat and A. Turpin, "A fast and space-economical
1122 * algorithm for length-limited coding," Proc. Intl. Symp. on Algorithms
1123 * and Computation, Cairns, Australia, Dec. 1995, Lecture Notes in Computer
1124 * Science, Vol 1004, J. Staples, P. Eades, N. Katoh, and A. Moffat, eds.,
1125 * pp 12-21, Springer Verlag, New York, 1995.
1126 */
1127static int
1128mkprecode(Huff *tab, ulong *count, int n, int maxbits, ulong *bitcount)
1129{
1130 Chains cs;
1131 Chain *c;
1132 int i, m, em, bits;
1133
1134 /*
1135 * set up the sorted list of leaves
1136 */
1137 m = 0;
1138 for(i = 0; i < n; i++){
1139 tab[i].bits = -1;
1140 tab[i].encode = 0;
1141 if(count[i] != 0){
1142 cs.leafcount[m] = count[i];
1143 cs.leafmap[m] = i;
1144 m++;
1145 }
1146 }
1147 if(m < 2){
1148 if(m != 0){
1149 tab[cs.leafmap[0]].bits = 0;
1150 bitcount[0] = 1;
1151 }else
1152 bitcount[0] = 0;
1153 return 0;
1154 }
1155 cs.nleaf = m;
1156 leafsort(cs.leafcount, cs.leafmap, 0, m);
1157
1158 for(i = 0; i < m; i++)
1159 cs.leafcount[i] = count[cs.leafmap[i]];
1160
1161 /*
1162 * set up free list
1163 */
1164 cs.free = &cs.chains[2];
1165 cs.echains = &cs.chains[ChainMem];
1166 cs.col = 1;
1167
1168 /*
1169 * initialize chains for each list
1170 */
1171 c = &cs.chains[0];
1172 c->count = cs.leafcount[0];
1173 c->leaf = 1;
1174 c->col = cs.col;
1175 c->up = nil;
1176 c->gen = 0;
1177 cs.chains[1] = cs.chains[0];
1178 cs.chains[1].leaf = 2;
1179 cs.chains[1].count = cs.leafcount[1];
1180 for(i = 0; i < maxbits-1; i++){
1181 cs.lists[i * 2] = &cs.chains[0];
1182 cs.lists[i * 2 + 1] = &cs.chains[1];
1183 }
1184
1185 cs.nlists = 2 * (maxbits - 1);
1186 m = 2 * m - 2;
1187 for(i = 2; i < m; i++)
1188 nextchain(&cs, cs.nlists - 2);
1189
1190 bits = 0;
1191 bitcount[0] = cs.nleaf;
1192 for(c = cs.lists[cs.nlists - 1]; c != nil; c = c->up){
1193 m = c->leaf;
1194 bitcount[bits++] -= m;
1195 bitcount[bits] = m;
1196 }
1197 m = 0;
1198 for(i = bits; i >= 0; i--)
1199 for(em = m + bitcount[i]; m < em; m++)
1200 tab[cs.leafmap[m]].bits = i;
1201
1202 return bits;
1203}
1204
1205/*
1206 * calculate the next chain on the list
1207 * we can always toss out the old chain
1208 */
1209static void
1210nextchain(Chains *cs, int list)
1211{
1212 Chain *c, *oc;
1213 int i, nleaf, sumc;
1214
1215 oc = cs->lists[list + 1];
1216 cs->lists[list] = oc;
1217 if(oc == nil)
1218 return;
1219
1220 /*
1221 * make sure we have all chains needed to make sumc
1222 * note it is possible to generate only one of these,
1223 * use twice that value for sumc, and then generate
1224 * the second if that preliminary sumc would be chosen.
1225 * however, this appears to be slower on current tests
1226 */
1227 if(oc->gen){
1228 nextchain(cs, list - 2);
1229 nextchain(cs, list - 2);
1230 oc->gen = 0;
1231 }
1232
1233 /*
1234 * pick up the chain we're going to add;
1235 * collect unused chains no free ones are left
1236 */
1237 for(c = cs->free; ; c++){
1238 if(c >= cs->echains){
1239 cs->col++;
1240 for(i = 0; i < cs->nlists; i++)
1241 for(c = cs->lists[i]; c != nil; c = c->up)
1242 c->col = cs->col;
1243 c = cs->chains;
1244 }
1245 if(c->col != cs->col)
1246 break;
1247 }
1248
1249 /*
1250 * pick the cheapest of
1251 * 1) the next package from the previous list
1252 * 2) the next leaf
1253 */
1254 nleaf = oc->leaf;
1255 sumc = 0;
1256 if(list > 0 && cs->lists[list-1] != nil)
1257 sumc = cs->lists[list-2]->count + cs->lists[list-1]->count;
1258 if(sumc != 0 && (nleaf >= cs->nleaf || cs->leafcount[nleaf] > sumc)){
1259 c->count = sumc;
1260 c->leaf = oc->leaf;
1261 c->up = cs->lists[list-1];
1262 c->gen = 1;
1263 }else if(nleaf >= cs->nleaf){
1264 cs->lists[list + 1] = nil;
1265 return;
1266 }else{
1267 c->leaf = nleaf + 1;
1268 c->count = cs->leafcount[nleaf];
1269 c->up = oc->up;
1270 c->gen = 0;
1271 }
1272 cs->free = c + 1;
1273
1274 cs->lists[list + 1] = c;
1275 c->col = cs->col;
1276}
1277
1278static int
1279pivot(ulong *c, int a, int n)
1280{
1281 int j, pi, pj, pk;
1282
1283 j = n/6;
1284 pi = a + j; /* 1/6 */
1285 j += j;
1286 pj = pi + j; /* 1/2 */
1287 pk = pj + j; /* 5/6 */
1288 if(c[pi] < c[pj]){
1289 if(c[pi] < c[pk]){
1290 if(c[pj] < c[pk])
1291 return pj;
1292 return pk;
1293 }
1294 return pi;
1295 }
1296 if(c[pj] < c[pk]){
1297 if(c[pi] < c[pk])
1298 return pi;
1299 return pk;
1300 }
1301 return pj;
1302}
1303
1304static void
1305leafsort(ulong *leafcount, ushort *leafmap, int a, int n)
1306{
1307 ulong t;
1308 int j, pi, pj, pn;
1309
1310 while(n > 1){
1311 if(n > 10){
1312 pi = pivot(leafcount, a, n);
1313 }else
1314 pi = a + (n>>1);
1315
1316 t = leafcount[pi];
1317 leafcount[pi] = leafcount[a];
1318 leafcount[a] = t;
1319 t = leafmap[pi];
1320 leafmap[pi] = leafmap[a];
1321 leafmap[a] = t;
1322 pi = a;
1323 pn = a + n;
1324 pj = pn;
1325 for(;;){
1326 do
1327 pi++;
1328 while(pi < pn && (leafcount[pi] < leafcount[a] || leafcount[pi] == leafcount[a] && leafmap[pi] > leafmap[a]));
1329 do
1330 pj--;
1331 while(pj > a && (leafcount[pj] > leafcount[a] || leafcount[pj] == leafcount[a] && leafmap[pj] < leafmap[a]));
1332 if(pj < pi)
1333 break;
1334 t = leafcount[pi];
1335 leafcount[pi] = leafcount[pj];
1336 leafcount[pj] = t;
1337 t = leafmap[pi];
1338 leafmap[pi] = leafmap[pj];
1339 leafmap[pj] = t;
1340 }
1341 t = leafcount[a];
1342 leafcount[a] = leafcount[pj];
1343 leafcount[pj] = t;
1344 t = leafmap[a];
1345 leafmap[a] = leafmap[pj];
1346 leafmap[pj] = t;
1347 j = pj - a;
1348
1349 n = n-j-1;
1350 if(j >= n){
1351 leafsort(leafcount, leafmap, a, j);
1352 a += j+1;
1353 }else{
1354 leafsort(leafcount, leafmap, a + (j+1), n);
1355 n = j;
1356 }
1357 }
1358}
os/boot/libflate/deflateblock.c+55−0
@@ -0,0 +1,55 @@
1#include "lib9.h"
2#include <flate.h>
3
4typedef struct Block Block;
5
6struct Block
7{
8 uchar *pos;
9 uchar *limit;
10};
11
12static int
13blread(void *vb, void *buf, int n)
14{
15 Block *b;
16
17 b = vb;
18 if(n > b->limit - b->pos)
19 n = b->limit - b->pos;
20 memmove(buf, b->pos, n);
21 b->pos += n;
22 return n;
23}
24
25static int
26blwrite(void *vb, void *buf, int n)
27{
28 Block *b;
29
30 b = vb;
31
32 if(n > b->limit - b->pos)
33 n = b->limit - b->pos;
34 memmove(b->pos, buf, n);
35 b->pos += n;
36 return n;
37}
38
39int
40deflateblock(uchar *dst, int dsize, uchar *src, int ssize, int level, int debug)
41{
42 Block bd, bs;
43 int ok;
44
45 bs.pos = src;
46 bs.limit = src + ssize;
47
48 bd.pos = dst;
49 bd.limit = dst + dsize;
50
51 ok = deflate(&bd, blwrite, &bs, blread, level, debug);
52 if(ok != FlateOk)
53 return ok;
54 return bd.pos - dst;
55}
os/boot/libflate/deflatezlib.c+59−0
@@ -0,0 +1,59 @@
1#include "lib9.h"
2#include <flate.h>
3#include "zlib.h"
4
5typedef struct ZRead ZRead;
6
7struct ZRead
8{
9 ulong adler;
10 void *rr;
11 int (*r)(void*, void*, int);
12};
13
14static int
15zlread(void *vzr, void *buf, int n)
16{
17 ZRead *zr;
18
19 zr = vzr;
20 n = (*zr->r)(zr->rr, buf, n);
21 if(n <= 0)
22 return n;
23 zr->adler = adler32(zr->adler, buf, n);
24 return n;
25}
26
27int
28deflatezlib(void *wr, int (*w)(void*, void*, int), void *rr, int (*r)(void*, void*, int), int level, int debug)
29{
30 ZRead zr;
31 uchar buf[4];
32 int ok;
33
34 buf[0] = ZlibDeflate | ZlibWin32k;
35
36 /* bogus zlib encoding of compression level */
37 buf[1] = ((level > 2) + (level > 5) + (level > 8)) << 6;
38
39 /* header check field */
40 buf[1] |= 31 - ((buf[0] << 8) | buf[1]) % 31;
41 if((*w)(wr, buf, 2) != 2)
42 return FlateOutputFail;
43
44 zr.rr = rr;
45 zr.r = r;
46 zr.adler = 1;
47 ok = deflate(wr, w, &zr, zlread, level, debug);
48 if(ok != FlateOk)
49 return ok;
50
51 buf[0] = zr.adler >> 24;
52 buf[1] = zr.adler >> 16;
53 buf[2] = zr.adler >> 8;
54 buf[3] = zr.adler;
55 if((*w)(wr, buf, 4) != 4)
56 return FlateOutputFail;
57
58 return FlateOk;
59}
os/boot/libflate/deflatezlibblock.c+33−0
@@ -0,0 +1,33 @@
1#include "lib9.h"
2#include <flate.h>
3#include "zlib.h"
4
5int
6deflatezlibblock(uchar *dst, int dsize, uchar *src, int ssize, int level, int debug)
7{
8 ulong adler;
9 int n;
10
11 if(dsize < 6)
12 return FlateOutputFail;
13
14 n = deflateblock(dst + 2, dsize - 6, src, ssize, level, debug);
15 if(n < 0)
16 return n;
17
18 dst[0] = ZlibDeflate | ZlibWin32k;
19
20 /* bogus zlib encoding of compression level */
21 dst[1] = ((level > 2) + (level > 5) + (level > 8)) << 6;
22
23 /* header check field */
24 dst[1] |= 31 - ((dst[0] << 8) | dst[1]) % 31;
25
26 adler = adler32(1, src, ssize);
27 dst[n + 2] = adler >> 24;
28 dst[n + 3] = adler >> 16;
29 dst[n + 4] = adler >> 8;
30 dst[n + 5] = adler;
31
32 return n + 6;
33}
os/boot/libflate/flateerr.c+22−0
@@ -0,0 +1,22 @@
1#include "lib9.h"
2#include <flate.h>
3
4char *
5flateerr(int err)
6{
7 switch(err){
8 case FlateOk:
9 return "no error";
10 case FlateNoMem:
11 return "out of memory";
12 case FlateInputFail:
13 return "input error";
14 case FlateOutputFail:
15 return "output error";
16 case FlateCorrupted:
17 return "corrupted data";
18 case FlateInternal:
19 return "internal error";
20 }
21 return "unknown error";
22}
os/boot/libflate/inflate.c+692−0
@@ -0,0 +1,692 @@
1#include "lib9.h"
2#include <flate.h>
3
4enum {
5 HistorySize= 32*1024,
6 BufSize= 4*1024,
7 MaxHuffBits= 17, /* maximum bits in a encoded code */
8 Nlitlen= 288, /* number of litlen codes */
9 Noff= 32, /* number of offset codes */
10 Nclen= 19, /* number of codelen codes */
11 LenShift= 10, /* code = len<<LenShift|code */
12 LitlenBits= 7, /* number of bits in litlen decode table */
13 OffBits= 6, /* number of bits in offset decode table */
14 ClenBits= 6, /* number of bits in code len decode table */
15 MaxFlatBits= LitlenBits,
16 MaxLeaf= Nlitlen
17};
18
19typedef struct Input Input;
20typedef struct History History;
21typedef struct Huff Huff;
22
23struct Input
24{
25 int error; /* first error encountered, or FlateOk */
26 void *wr;
27 int (*w)(void*, void*, int);
28 void *getr;
29 int (*get)(void*);
30 ulong sreg;
31 int nbits;
32};
33
34struct History
35{
36 uchar his[HistorySize];
37 uchar *cp; /* current pointer in history */
38 int full; /* his has been filled up at least once */
39};
40
41struct Huff
42{
43 int maxbits; /* max bits for any code */
44 int minbits; /* min bits to get before looking in flat */
45 int flatmask; /* bits used in "flat" fast decoding table */
46 ulong flat[1<<MaxFlatBits];
47 ulong maxcode[MaxHuffBits];
48 ulong last[MaxHuffBits];
49 ulong decode[MaxLeaf];
50};
51
52/* litlen code words 257-285 extra bits */
53static int litlenextra[Nlitlen-257] =
54{
55/* 257 */ 0, 0, 0,
56/* 260 */ 0, 0, 0, 0, 0, 1, 1, 1, 1, 2,
57/* 270 */ 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
58/* 280 */ 4, 5, 5, 5, 5, 0, 0, 0
59};
60
61static int litlenbase[Nlitlen-257];
62
63/* offset code word extra bits */
64static int offextra[Noff] =
65{
66 0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
67 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
68 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
69 0, 0,
70};
71static int offbase[Noff];
72
73/* order code lengths */
74static int clenorder[Nclen] =
75{
76 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
77};
78
79/* for static huffman tables */
80static Huff litlentab;
81static Huff offtab;
82static uchar revtab[256];
83
84static int uncblock(Input *in, History*);
85static int fixedblock(Input *in, History*);
86static int dynamicblock(Input *in, History*);
87static int sregfill(Input *in, int n);
88static int sregunget(Input *in);
89static int decode(Input*, History*, Huff*, Huff*);
90static int hufftab(Huff*, char*, int, int);
91static int hdecsym(Input *in, Huff *h, int b);
92
93int
94inflateinit(void)
95{
96 char *len;
97 int i, j, base;
98
99 /* byte reverse table */
100 for(i=0; i<256; i++)
101 for(j=0; j<8; j++)
102 if(i & (1<<j))
103 revtab[i] |= 0x80 >> j;
104
105 for(i=257,base=3; i<Nlitlen; i++) {
106 litlenbase[i-257] = base;
107 base += 1<<litlenextra[i-257];
108 }
109 /* strange table entry in spec... */
110 litlenbase[285-257]--;
111
112 for(i=0,base=1; i<Noff; i++) {
113 offbase[i] = base;
114 base += 1<<offextra[i];
115 }
116
117 len = malloc(MaxLeaf);
118 if(len == nil)
119 return FlateNoMem;
120
121 /* static Litlen bit lengths */
122 for(i=0; i<144; i++)
123 len[i] = 8;
124 for(i=144; i<256; i++)
125 len[i] = 9;
126 for(i=256; i<280; i++)
127 len[i] = 7;
128 for(i=280; i<Nlitlen; i++)
129 len[i] = 8;
130
131 if(!hufftab(&litlentab, len, Nlitlen, MaxFlatBits))
132 return FlateInternal;
133
134 /* static Offset bit lengths */
135 for(i=0; i<Noff; i++)
136 len[i] = 5;
137
138 if(!hufftab(&offtab, len, Noff, MaxFlatBits))
139 return FlateInternal;
140 free(len);
141
142 return FlateOk;
143}
144
145int
146inflate(void *wr, int (*w)(void*, void*, int), void *getr, int (*get)(void*))
147{
148 History *his;
149 Input in;
150 int final, type;
151
152 his = malloc(sizeof(History));
153 if(his == nil)
154 return FlateNoMem;
155 his->cp = his->his;
156 his->full = 0;
157 in.getr = getr;
158 in.get = get;
159 in.wr = wr;
160 in.w = w;
161 in.nbits = 0;
162 in.sreg = 0;
163 in.error = FlateOk;
164
165 do {
166 if(!sregfill(&in, 3))
167 goto bad;
168 final = in.sreg & 0x1;
169 type = (in.sreg>>1) & 0x3;
170 in.sreg >>= 3;
171 in.nbits -= 3;
172 switch(type) {
173 default:
174 in.error = FlateCorrupted;
175 goto bad;
176 case 0:
177 /* uncompressed */
178 if(!uncblock(&in, his))
179 goto bad;
180 break;
181 case 1:
182 /* fixed huffman */
183 if(!fixedblock(&in, his))
184 goto bad;
185 break;
186 case 2:
187 /* dynamic huffman */
188 if(!dynamicblock(&in, his))
189 goto bad;
190 break;
191 }
192 } while(!final);
193
194 if(his->cp != his->his && (*w)(wr, his->his, his->cp - his->his) != his->cp - his->his) {
195 in.error = FlateOutputFail;
196 goto bad;
197 }
198
199 if(!sregunget(&in))
200 goto bad;
201
202 free(his);
203 if(in.error != FlateOk)
204 return FlateInternal;
205 return FlateOk;
206
207bad:
208 free(his);
209 if(in.error == FlateOk)
210 return FlateInternal;
211 return in.error;
212}
213
214static int
215uncblock(Input *in, History *his)
216{
217 int len, nlen, c;
218 uchar *hs, *hp, *he;
219
220 if(!sregunget(in))
221 return 0;
222 len = (*in->get)(in->getr);
223 len |= (*in->get)(in->getr)<<8;
224 nlen = (*in->get)(in->getr);
225 nlen |= (*in->get)(in->getr)<<8;
226 if(len != (~nlen&0xffff)) {
227 in->error = FlateCorrupted;
228 return 0;
229 }
230
231 hp = his->cp;
232 hs = his->his;
233 he = hs + HistorySize;
234
235 while(len > 0) {
236 c = (*in->get)(in->getr);
237 if(c < 0)
238 return 0;
239 *hp++ = c;
240 if(hp == he) {
241 his->full = 1;
242 if((*in->w)(in->wr, hs, HistorySize) != HistorySize) {
243 in->error = FlateOutputFail;
244 return 0;
245 }
246 hp = hs;
247 }
248 len--;
249 }
250
251 his->cp = hp;
252
253 return 1;
254}
255
256static int
257fixedblock(Input *in, History *his)
258{
259 return decode(in, his, &litlentab, &offtab);
260}
261
262static int
263dynamicblock(Input *in, History *his)
264{
265 Huff *lentab, *offtab;
266 char *len;
267 int i, j, n, c, nlit, ndist, nclen, res, nb;
268
269 if(!sregfill(in, 14))
270 return 0;
271 nlit = (in->sreg&0x1f) + 257;
272 ndist = ((in->sreg>>5) & 0x1f) + 1;
273 nclen = ((in->sreg>>10) & 0xf) + 4;
274 in->sreg >>= 14;
275 in->nbits -= 14;
276
277 if(nlit > Nlitlen || ndist > Noff || nlit < 257) {
278 in->error = FlateCorrupted;
279 return 0;
280 }
281
282 /* huff table header */
283 len = malloc(Nlitlen+Noff);
284 lentab = malloc(sizeof(Huff));
285 offtab = malloc(sizeof(Huff));
286 if(len == nil || lentab == nil || offtab == nil){
287 in->error = FlateNoMem;
288 goto bad;
289 }
290 for(i=0; i < Nclen; i++)
291 len[i] = 0;
292 for(i=0; i<nclen; i++) {
293 if(!sregfill(in, 3))
294 goto bad;
295 len[clenorder[i]] = in->sreg & 0x7;
296 in->sreg >>= 3;
297 in->nbits -= 3;
298 }
299
300 if(!hufftab(lentab, len, Nclen, ClenBits)){
301 in->error = FlateCorrupted;
302 goto bad;
303 }
304
305 n = nlit+ndist;
306 for(i=0; i<n;) {
307 nb = lentab->minbits;
308 for(;;){
309 if(in->nbits<nb && !sregfill(in, nb))
310 goto bad;
311 c = lentab->flat[in->sreg & lentab->flatmask];
312 nb = c & 0xff;
313 if(nb > in->nbits){
314 if(nb != 0xff)
315 continue;
316 c = hdecsym(in, lentab, c);
317 if(c < 0)
318 goto bad;
319 }else{
320 c >>= 8;
321 in->sreg >>= nb;
322 in->nbits -= nb;
323 }
324 break;
325 }
326
327 if(c < 16) {
328 j = 1;
329 } else if(c == 16) {
330 if(in->nbits<2 && !sregfill(in, 2))
331 goto bad;
332 j = (in->sreg&0x3)+3;
333 in->sreg >>= 2;
334 in->nbits -= 2;
335 if(i == 0) {
336 in->error = FlateCorrupted;
337 goto bad;
338 }
339 c = len[i-1];
340 } else if(c == 17) {
341 if(in->nbits<3 && !sregfill(in, 3))
342 goto bad;
343 j = (in->sreg&0x7)+3;
344 in->sreg >>= 3;
345 in->nbits -= 3;
346 c = 0;
347 } else if(c == 18) {
348 if(in->nbits<7 && !sregfill(in, 7))
349 goto bad;
350 j = (in->sreg&0x7f)+11;
351 in->sreg >>= 7;
352 in->nbits -= 7;
353 c = 0;
354 } else {
355 in->error = FlateCorrupted;
356 goto bad;
357 }
358
359 if(i+j > n) {
360 in->error = FlateCorrupted;
361 goto bad;
362 }
363
364 while(j) {
365 len[i] = c;
366 i++;
367 j--;
368 }
369 }
370
371 if(!hufftab(lentab, len, nlit, LitlenBits)
372 || !hufftab(offtab, &len[nlit], ndist, OffBits)){
373 in->error = FlateCorrupted;
374 goto bad;
375 }
376
377 res = decode(in, his, lentab, offtab);
378
379 free(len);
380 free(lentab);
381 free(offtab);
382
383 return res;
384
385bad:
386 free(len);
387 free(lentab);
388 free(offtab);
389 return 0;
390}
391
392static int
393decode(Input *in, History *his, Huff *litlentab, Huff *offtab)
394{
395 int len, off;
396 uchar *hs, *hp, *hq, *he;
397 int c;
398 int nb;
399
400 hs = his->his;
401 he = hs + HistorySize;
402 hp = his->cp;
403
404 for(;;) {
405 nb = litlentab->minbits;
406 for(;;){
407 if(in->nbits<nb && !sregfill(in, nb))
408 return 0;
409 c = litlentab->flat[in->sreg & litlentab->flatmask];
410 nb = c & 0xff;
411 if(nb > in->nbits){
412 if(nb != 0xff)
413 continue;
414 c = hdecsym(in, litlentab, c);
415 if(c < 0)
416 return 0;
417 }else{
418 c >>= 8;
419 in->sreg >>= nb;
420 in->nbits -= nb;
421 }
422 break;
423 }
424
425 if(c < 256) {
426 /* literal */
427 *hp++ = c;
428 if(hp == he) {
429 his->full = 1;
430 if((*in->w)(in->wr, hs, HistorySize) != HistorySize) {
431 in->error = FlateOutputFail;
432 return 0;
433 }
434 hp = hs;
435 }
436 continue;
437 }
438
439 if(c == 256)
440 break;
441
442 if(c > 285) {
443 in->error = FlateCorrupted;
444 return 0;
445 }
446
447 c -= 257;
448 nb = litlenextra[c];
449 if(in->nbits < nb && !sregfill(in, nb))
450 return 0;
451 len = litlenbase[c] + (in->sreg & ((1<<nb)-1));
452 in->sreg >>= nb;
453 in->nbits -= nb;
454
455 /* get offset */
456 nb = offtab->minbits;
457 for(;;){
458 if(in->nbits<nb && !sregfill(in, nb))
459 return 0;
460 c = offtab->flat[in->sreg & offtab->flatmask];
461 nb = c & 0xff;
462 if(nb > in->nbits){
463 if(nb != 0xff)
464 continue;
465 c = hdecsym(in, offtab, c);
466 if(c < 0)
467 return 0;
468 }else{
469 c >>= 8;
470 in->sreg >>= nb;
471 in->nbits -= nb;
472 }
473 break;
474 }
475
476 if(c > 29) {
477 in->error = FlateCorrupted;
478 return 0;
479 }
480
481 nb = offextra[c];
482 if(in->nbits < nb && !sregfill(in, nb))
483 return 0;
484
485 off = offbase[c] + (in->sreg & ((1<<nb)-1));
486 in->sreg >>= nb;
487 in->nbits -= nb;
488
489 hq = hp - off;
490 if(hq < hs) {
491 if(!his->full) {
492 in->error = FlateCorrupted;
493 return 0;
494 }
495 hq += HistorySize;
496 }
497
498 /* slow but correct */
499 while(len) {
500 *hp = *hq;
501 hq++;
502 hp++;
503 if(hq >= he)
504 hq = hs;
505 if(hp == he) {
506 his->full = 1;
507 if((*in->w)(in->wr, hs, HistorySize) != HistorySize) {
508 in->error = FlateOutputFail;
509 return 0;
510 }
511 hp = hs;
512 }
513 len--;
514 }
515
516 }
517
518 his->cp = hp;
519
520 return 1;
521}
522
523static int
524revcode(int c, int b)
525{
526 /* shift encode up so it starts on bit 15 then reverse */
527 c <<= (16-b);
528 c = revtab[c>>8] | (revtab[c&0xff]<<8);
529 return c;
530}
531
532/*
533 * construct the huffman decoding arrays and a fast lookup table.
534 * the fast lookup is a table indexed by the next flatbits bits,
535 * which returns the symbol matched and the number of bits consumed,
536 * or the minimum number of bits needed and 0xff if more than flatbits
537 * bits are needed.
538 *
539 * flatbits can be longer than the smallest huffman code,
540 * because shorter codes are assigned smaller lexical prefixes.
541 * this means assuming zeros for the next few bits will give a
542 * conservative answer, in the sense that it will either give the
543 * correct answer, or return the minimum number of bits which
544 * are needed for an answer.
545 */
546static int
547hufftab(Huff *h, char *hb, int maxleaf, int flatbits)
548{
549 ulong bitcount[MaxHuffBits];
550 ulong c, fc, ec, mincode, code, nc[MaxHuffBits];
551 int i, b, minbits, maxbits;
552
553 for(i = 0; i < MaxHuffBits; i++)
554 bitcount[i] = 0;
555 maxbits = -1;
556 minbits = MaxHuffBits + 1;
557 for(i=0; i < maxleaf; i++){
558 b = hb[i];
559 if(b){
560 bitcount[b]++;
561 if(b < minbits)
562 minbits = b;
563 if(b > maxbits)
564 maxbits = b;
565 }
566 }
567
568 h->maxbits = maxbits;
569 if(maxbits <= 0){
570 h->maxbits = 0;
571 h->minbits = 0;
572 h->flatmask = 0;
573 return 1;
574 }
575 code = 0;
576 c = 0;
577 for(b = 0; b <= maxbits; b++){
578 h->last[b] = c;
579 c += bitcount[b];
580 mincode = code << 1;
581 nc[b] = mincode;
582 code = mincode + bitcount[b];
583 if(code > (1 << b))
584 return 0;
585 h->maxcode[b] = code - 1;
586 h->last[b] += code - 1;
587 }
588
589 if(flatbits > maxbits)
590 flatbits = maxbits;
591 h->flatmask = (1 << flatbits) - 1;
592 if(minbits > flatbits)
593 minbits = flatbits;
594 h->minbits = minbits;
595
596 b = 1 << flatbits;
597 for(i = 0; i < b; i++)
598 h->flat[i] = ~0;
599
600 /*
601 * initialize the flat table to include the minimum possible
602 * bit length for each code prefix
603 */
604 for(b = maxbits; b > flatbits; b--){
605 code = h->maxcode[b];
606 if(code == -1)
607 break;
608 mincode = code + 1 - bitcount[b];
609 mincode >>= b - flatbits;
610 code >>= b - flatbits;
611 for(; mincode <= code; mincode++)
612 h->flat[revcode(mincode, flatbits)] = (b << 8) | 0xff;
613 }
614
615 for(i = 0; i < maxleaf; i++){
616 b = hb[i];
617 if(b <= 0)
618 continue;
619 c = nc[b]++;
620 if(b <= flatbits){
621 code = (i << 8) | b;
622 ec = (c + 1) << (flatbits - b);
623 if(ec > (1<<flatbits))
624 return 0; /* this is actually an internal error */
625 for(fc = c << (flatbits - b); fc < ec; fc++)
626 h->flat[revcode(fc, flatbits)] = code;
627 }
628 if(b > minbits){
629 c = h->last[b] - c;
630 if(c >= maxleaf)
631 return 0;
632 h->decode[c] = i;
633 }
634 }
635 return 1;
636}
637
638static int
639hdecsym(Input *in, Huff *h, int nb)
640{
641 long c;
642
643 if((nb & 0xff) == 0xff)
644 nb = nb >> 8;
645 else
646 nb = nb & 0xff;
647 for(; nb <= h->maxbits; nb++){
648 if(in->nbits<nb && !sregfill(in, nb))
649 return -1;
650 c = revtab[in->sreg&0xff]<<8;
651 c |= revtab[(in->sreg>>8)&0xff];
652 c >>= (16-nb);
653 if(c <= h->maxcode[nb]){
654 in->sreg >>= nb;
655 in->nbits -= nb;
656 return h->decode[h->last[nb] - c];
657 }
658 }
659 in->error = FlateCorrupted;
660 return -1;
661}
662
663static int
664sregfill(Input *in, int n)
665{
666 int c;
667
668 while(n > in->nbits) {
669 c = (*in->get)(in->getr);
670 if(c < 0){
671 in->error = FlateInputFail;
672 return 0;
673 }
674 in->sreg |= c<<in->nbits;
675 in->nbits += 8;
676 }
677 return 1;
678}
679
680static int
681sregunget(Input *in)
682{
683 if(in->nbits >= 8) {
684 in->error = FlateInternal;
685 return 0;
686 }
687
688 /* throw other bits on the floor */
689 in->nbits = 0;
690 in->sreg = 0;
691 return 1;
692}
os/boot/libflate/inflateblock.c+53−0
@@ -0,0 +1,53 @@
1#include "lib9.h"
2#include <flate.h>
3
4typedef struct Block Block;
5
6struct Block
7{
8 uchar *pos;
9 uchar *limit;
10};
11
12static int
13blgetc(void *vb)
14{
15 Block *b;
16
17 b = vb;
18 if(b->pos >= b->limit)
19 return -1;
20 return *b->pos++;
21}
22
23static int
24blwrite(void *vb, void *buf, int n)
25{
26 Block *b;
27
28 b = vb;
29
30 if(n > b->limit - b->pos)
31 n = b->limit - b->pos;
32 memmove(b->pos, buf, n);
33 b->pos += n;
34 return n;
35}
36
37int
38inflateblock(uchar *dst, int dsize, uchar *src, int ssize)
39{
40 Block bd, bs;
41 int ok;
42
43 bs.pos = src;
44 bs.limit = src + ssize;
45
46 bd.pos = dst;
47 bd.limit = dst + dsize;
48
49 ok = inflate(&bd, blwrite, &bs, blgetc);
50 if(ok != FlateOk)
51 return ok;
52 return bd.pos - dst;
53}
os/boot/libflate/inflatezlib.c+65−0
@@ -0,0 +1,65 @@
1#include "lib9.h"
2#include <flate.h>
3#include "zlib.h"
4
5typedef struct ZWrite ZWrite;
6
7struct ZWrite
8{
9 ulong adler;
10 void *wr;
11 int (*w)(void*, void*, int);
12};
13
14static int
15zlwrite(void *vzw, void *buf, int n)
16{
17 ZWrite *zw;
18
19 zw = vzw;
20 zw->adler = adler32(zw->adler, buf, n);
21 n = (*zw->w)(zw->wr, buf, n);
22 if(n <= 0)
23 return n;
24 return n;
25}
26
27int
28inflatezlib(void *wr, int (*w)(void*, void*, int), void *getr, int (*get)(void*))
29{
30 ZWrite zw;
31 ulong v;
32 int c, i;
33
34 c = (*get)(getr);
35 if(c < 0)
36 return FlateInputFail;
37 i = (*get)(getr);
38 if(i < 0)
39 return FlateInputFail;
40
41 if(((c << 8) | i) % 31)
42 return FlateCorrupted;
43 if((c & ZlibMeth) != ZlibDeflate
44 || (c & ZlibCInfo) > ZlibWin32k)
45 return FlateCorrupted;
46
47 zw.wr = wr;
48 zw.w = w;
49 zw.adler = 1;
50 i = inflate(&zw, zlwrite, getr, get);
51 if(i != FlateOk)
52 return i;
53
54 v = 0;
55 for(i = 0; i < 4; i++){
56 c = (*get)(getr);
57 if(c < 0)
58 return FlateInputFail;
59 v = (v << 8) | c;
60 }
61 if(zw.adler != v)
62 return FlateCorrupted;
63
64 return FlateOk;
65}
os/boot/libflate/inflatezlibblock.c+67−0
@@ -0,0 +1,67 @@
1#include "lib9.h"
2#include <flate.h>
3#include "zlib.h"
4
5typedef struct Block Block;
6
7struct Block
8{
9 uchar *pos;
10 uchar *limit;
11};
12
13static int
14blgetc(void *vb)
15{
16 Block *b;
17
18 b = vb;
19 if(b->pos >= b->limit)
20 return -1;
21 return *b->pos++;
22}
23
24static int
25blwrite(void *vb, void *buf, int n)
26{
27 Block *b;
28
29 b = vb;
30
31 if(n > b->limit - b->pos)
32 n = b->limit - b->pos;
33 memmove(b->pos, buf, n);
34 b->pos += n;
35 return n;
36}
37
38int
39inflatezlibblock(uchar *dst, int dsize, uchar *src, int ssize)
40{
41 Block bd, bs;
42 int ok;
43
44 if(ssize < 6)
45 return FlateInputFail;
46
47 if(((src[0] << 8) | src[1]) % 31)
48 return FlateCorrupted;
49 if((src[0] & ZlibMeth) != ZlibDeflate
50 || (src[0] & ZlibCInfo) > ZlibWin32k)
51 return FlateCorrupted;
52
53 bs.pos = src + 2;
54 bs.limit = src + ssize - 6;
55
56 bd.pos = dst;
57 bd.limit = dst + dsize;
58
59 ok = inflate(&bd, blwrite, &bs, blgetc);
60 if(ok != FlateOk)
61 return ok;
62
63 if(adler32(1, dst, bs.pos - dst) != ((bs.pos[0] << 24) | (bs.pos[1] << 16) | (bs.pos[2] << 8) | bs.pos[3]))
64 return FlateCorrupted;
65
66 return bd.pos - dst;
67}
os/boot/libflate/mkfile+21−0
@@ -0,0 +1,21 @@
1<../../../mkconfig
2
3LIB=libflate.a
4OFILES=\
5 deflate.$O\
6 deflatezlib.$O\
7 deflateblock.$O\
8 deflatezlibblock.$O\
9 inflate.$O\
10 inflatezlib.$O\
11 inflateblock.$O\
12 inflatezlibblock.$O\
13 flateerr.$O\
14 crc.$O\
15 adler.$O\
16
17HFILES=\
18 $ROOT/include/flate.h\
19 zlib.h\
20
21<$ROOT/mkfiles/mksyslib-$SHELLTYPE
os/boot/libflate/zlib.h+11−0
@@ -0,0 +1,11 @@
1/*
2 * zlib header fields
3 */
4enum
5{
6 ZlibMeth = 0x0f, /* mask of compression methods */
7 ZlibDeflate = 0x08,
8
9 ZlibCInfo = 0xf0, /* mask of compression aux. info */
10 ZlibWin32k = 0x70, /* 32k history window */
11};
os/boot/mpc/NOTICE+3−0
@@ -0,0 +1,3 @@
1Inferno® Copyright © 1996-1999 Lucent Technologies Inc. All rights reserved.
2PowerPC support Copyright © 1995-1997 C H Forsyth (forsyth@caldo.demon.co.uk). All rights reserved.
3MPC8xx Inferno PowerPC port Copyright © 1998-2003 Vita Nuova Holdings Limited. All rights reserved.
os/boot/mpc/alarm.c+123−0
@@ -0,0 +1,123 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7#define MAXALARM 10
8
9Alarm alarmtab[MAXALARM];
10
11/*
12 * Insert new into list after where
13 */
14void
15insert(List **head, List *where, List *new)
16{
17 if(where == 0){
18 new->next = *head;
19 *head = new;
20 }else{
21 new->next = where->next;
22 where->next = new;
23 }
24
25}
26
27/*
28 * Delete old from list. where->next is known to be old.
29 */
30void
31delete(List **head, List *where, List *old)
32{
33 if(where == 0){
34 *head = old->next;
35 return;
36 }
37 where->next = old->next;
38}
39
40Alarm*
41newalarm(void)
42{
43 int i;
44 Alarm *a;
45
46 for(i=0,a=alarmtab; i < nelem(alarmtab); i++,a++)
47 if(a->busy==0 && a->f==0){
48 a->f = 0;
49 a->arg = 0;
50 a->busy = 1;
51 return a;
52 }
53 panic("newalarm");
54 return 0; /* not reached */
55}
56
57Alarm*
58alarm(int ms, void (*f)(Alarm*), void *arg)
59{
60 Alarm *a, *w, *pw;
61 ulong s;
62
63 if(ms < 0)
64 ms = 0;
65 s = splhi();
66 a = newalarm();
67 a->dt = MS2TK(ms);
68 a->f = f;
69 a->arg = arg;
70 pw = 0;
71 for(w=m->alarm; w; pw=w, w=w->next){
72 if(w->dt <= a->dt){
73 a->dt -= w->dt;
74 continue;
75 }
76 w->dt -= a->dt;
77 break;
78 }
79 insert(&m->alarm, pw, a);
80 splx(s);
81 return a;
82}
83
84void
85cancel(Alarm *a)
86{
87 a->f = 0;
88}
89
90void
91alarminit(void)
92{
93}
94
95#define NA 10 /* alarms per clock tick */
96void
97checkalarms(void)
98{
99 int i, n, s;
100 Alarm *a;
101 void (*f)(Alarm*);
102 Alarm *alist[NA];
103
104 s = splhi();
105 a = m->alarm;
106 if(a){
107 for(n=0; a && a->dt<=0 && n<NA; n++){
108 alist[n] = a;
109 delete(&m->alarm, 0, a);
110 a = m->alarm;
111 }
112 if(a)
113 a->dt--;
114
115 for(i = 0; i < n; i++){
116 f = alist[i]->f; /* avoid race with cancel */
117 if(f)
118 (*f)(alist[i]);
119 alist[i]->busy = 0;
120 }
121 }
122 splx(s);
123}
os/boot/mpc/all.h+6−0
@@ -0,0 +1,6 @@
1#include "u.h"
2#include "lib.h"
3#include "dat.h"
4#include "fns.h"
5#include "mem.h"
6#include "io.h"
os/boot/mpc/archfads.c+355−0
@@ -0,0 +1,355 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7#include "archfads.h"
8
9/*
10 * board-specific support for the 8xxFADS (including 860/21 development system)
11 */
12
13enum {
14 USESDRAM = 0, /* set to 1 if kernel is to use SDRAM as well as DRAM */
15
16 /* sccr */
17 RTSEL = IBIT(8), /* =0, select main oscillator (OSCM); =1, select external crystal (EXTCLK) */
18 RTDIV = IBIT(7), /* =0, divide by 4; =1, divide by 512 */
19 CRQEN = IBIT(9), /* =1, switch to high frequency when CPM active */
20 PRQEN = IBIT(10), /* =1, switch to high frequency when interrupt pending */
21
22 /* plprcr */
23 CSRC = IBIT(21), /* =0, clock is DFNH; =1, clock is DFNL */
24};
25
26/*
27 * called early in main.c, after machinit:
28 * using board and architecture specific registers, initialise
29 * 8xx registers that need it and complete initialisation of the Mach structure.
30 */
31void
32archinit(void)
33{
34 IMM *io;
35 int mf, isfads, sysmhz, t;
36 ulong v;
37
38 v = getimmr() & 0xFFFF;
39 isfads = 0; /* assume it's the 860/821 board */
40 sysmhz = 40;
41 switch(v>>8){
42 case 0x00: t = 0x86000; break;
43 case 0x20: t = 0x82300; isfads = 1; break;
44 case 0x21: t = 0x823a0; isfads = 1; break;
45 default: t = 0; break;
46 }
47 m->cputype = t;
48 m->bcsr = KADDR(BCSRMEM);
49 m->bcsr[1] |= DisableRS232a | DisableIR | DisableEther | DisablePCMCIA | DisableRS232b;
50 m->bcsr[1] &= ~(DisableDRAM|DisableFlash);
51 if(isfads){
52 sysmhz = 50;
53 m->bcsr[1] &= ~EnableSDRAM;
54 m->bcsr[4] &= ~(EnableVideoClock|EnableVideoPort);
55 m->bcsr[4] |= DisableVideoLamp;
56 }
57 io = m->iomem;
58 if(1 || io->sccr & IBIT(7)){ /* RTDIV=1 */
59 /* oscillator frequency can't be determined independently: check a switch */
60 if((m->bcsr[2]>>19)&(1<<2))
61 m->clockgen = 5*MHz;
62 else
63 m->clockgen = 4*MHz;
64 } else
65 m->clockgen = 32768;
66 mf = (sysmhz*MHz)/m->clockgen;
67 m->cpuhz = m->clockgen*mf;
68 io->plprcrk = KEEP_ALIVE_KEY;
69 io->plprcr &= ~IBIT(21); /* general system clock is DFNH */
70 io->plprcr = (io->plprcr & ((1<<20)-1)) | ((mf-1)<<20);
71 io->mptpr = 0x0400; /* memory prescaler = 16 for refresh */
72 io->plprcrk = ~KEEP_ALIVE_KEY;
73 if(isfads){
74 m->bcsr[1] |= EnableSDRAM;
75 sdraminit(SDRAMMEM);
76 if(!USESDRAM)
77 m->bcsr[1] &= ~EnableSDRAM; /* tells kernel not to map it */
78 }
79}
80
81static void
82archidprint(void)
83{
84 int f, i;
85 ulong v;
86
87 /* 8xx and FADS specific */
88 print("IMMR: ");
89 v = getimmr() & 0xFFFF;
90 switch(v>>8){
91 case 0x00: print("MPC860/821"); break;
92 case 0x20: print("MPC823"); break;
93 case 0x21: print("MPC823A"); break;
94 default: print("Type #%lux", v>>8); break;
95 }
96 print(", mask #%lux\n", v&0xFF);
97 v = m->bcsr[3]>>16;
98 print("MPC8xxFADS rev %lud, DB: ", ((v>>4)&8)|((v>>1)&4)|(v&3));
99 f = (v>>8)&0x3F;
100 switch(f){
101 default: print("ID#%x", f); break;
102 case 0x00: print("MPC860/821"); break;
103 case 0x01: print("MPC813"); break;
104 case 0x02: print("MPC821"); break;
105 case 0x03: print("MPC823"); break;
106 case 0x20: print("MPC801"); break;
107 case 0x21: print("MPC850"); break;
108 case 0x22: print("MPC860"); break;
109 case 0x23: print("MPC860SAR"); break;
110 case 0x24: print("MPC860T"); break;
111 }
112 print("ADS, rev #%lux\n", (m->bcsr[2]>>16)&7);
113 for(i=0; i<=4; i++)
114 print("BCSR%d: %8.8lux\n", i, m->bcsr[i]);
115 v = m->bcsr[2];
116 f = (v>>28)&0xF;
117 switch(f){
118 default: print("Unknown"); break;
119 case 4: print("SM732A2000/SM73228 - 8M SIMM"); break;
120 case 5: print("SM732A1000A/SM73218 - 4M SIMM"); break;
121 case 6: print("MCM29080 - 8M SIMM"); break;
122 case 7: print("MCM29040 - 4M SIMM"); break;
123 case 8: print("MCM29020 - 2M SIMM"); break;
124 }
125 switch((m->bcsr[3]>>20)&7){
126 default: i = 0; break;
127 case 1: i = 150; break;
128 case 2: i = 120; break;
129 case 3: i = 90; break;
130 }
131 print(" flash, %dns\n", i);
132 f = (v>>23)&0xF;
133 switch(f&3){
134 case 0: i = 4; break;
135 case 1: i = 32; break;
136 case 2: i = 16; break;
137 case 3: i = 8; break;
138 }
139 print("%dM SIMM, ", i);
140 switch(f>>2){
141 default: i = 0; break;
142 case 2: i = 70; break;
143 case 3: i = 60; break;
144 }
145 print("%dns\n", i);
146 print("options: #%lux\n", (m->bcsr[2]>>19)&0xF);
147 print("plprcr=%8.8lux sccr=%8.8lux\n", m->iomem->plprcr, m->iomem->sccr);
148}
149
150void
151cpuidprint(void)
152{
153 int t;
154
155 print("PVR: ");
156 t = getpvr()>>16;
157 switch(t){
158 case 0x01: print("MPC601"); break;
159 case 0x03: print("MPC603"); break;
160 case 0x04: print("MPC604"); break;
161 case 0x06: print("MPC603e"); break;
162 case 0x07: print("MPC603e-v7"); break;
163 case 0x50: print("MPC8xx"); break;
164 default: print("PowerPC version #%x", t); break;
165 }
166 print(", revision #%lux\n", getpvr()&0xffff);
167 archidprint();
168 print("%lud MHz system\n", m->cpuhz/MHz);
169 print("\n");
170}
171
172static char* defplan9ini[2] = {
173 /* 860/821 */
174 "ether0=type=SCC port=1 ea=00108bf12900\r\n"
175 "vgasize=640x480x8\r\n"
176 "kernelpercent=40\r\n"
177 "console=0 lcd\r\nbaud=9600\r\n",
178
179 /* 823 */
180 "ether0=type=SCC port=2 ea=00108bf12900\r\n"
181 "vgasize=640x480x8\r\n"
182 "kernelpercent=40\r\n"
183 "console=0 lcd\r\nbaud=9600\r\n",
184};
185
186char *
187archconfig(void)
188{
189 print("Using default configuration\n");
190 return defplan9ini[MPCMODEL(m->cputype) == 0x823];
191}
192
193/*
194 * provide value for #r/switch (devrtc.c)
195 */
196int
197archoptionsw(void)
198{
199 return (m->bcsr[2]>>19)&0xF; /* value of switch DS1 */
200}
201
202/*
203 * invoked by clock.c:/^clockintr
204 */
205static void
206twinkle(void)
207{
208 if(m->ticks%MS2TK(1000) == 0)
209 m->bcsr[4] ^= DisableLamp;
210}
211
212void (*archclocktick)(void) = twinkle;
213
214/*
215 * for flash.c:/^flashreset
216 * retrieve flash type, virtual base and length and return 0;
217 * return -1 on error (no flash)
218 */
219int
220archflashreset(char *type, void **addr, long *length)
221{
222 char *t;
223 int mbyte;
224
225 if((m->iomem->memc[0].base & 1) == 0)
226 return -1; /* shouldn't happen */
227 switch((m->bcsr[2]>>28)&0xF){
228 default: return -1; /* unknown or not there */
229 case 4: mbyte=8; t = "SM732x8"; break;
230 case 5: mbyte=4; t = "SM732x8"; break;
231 case 6: mbyte=8; t = "AMD29F0x0"; break;
232 case 7: mbyte=4; t = "AMD29F0x0"; break;
233 case 8: mbyte=2; t = "AMD29F0x0"; break;
234 }
235 strcpy(type, t);
236 *addr = KADDR(FLASHMEM);
237 *length = mbyte*1024*1024;
238 return 0;
239}
240
241/*
242 * enable the clocks for the given SCC ether and reveal them to the caller.
243 * do anything else required to prepare the transceiver (eg, set full-duplex, reset loopback).
244 */
245int
246archetherenable(int cpmid, int *rcs, int *tcs)
247{
248 IMM *io;
249
250 switch(cpmid){
251 default:
252 /* no other SCCs are wired on the FADS board */
253 return -1;
254
255 case SCC2ID: /* assume 8xxFADS board with 823DABS */
256 io = ioplock();
257 m->bcsr[1] |= DisableIR|DisableRS232b;
258 m->bcsr[1] &= ~DisableEther;
259 io->papar |= SIBIT(6)|SIBIT(5); /* enable CLK2 and CLK3 */
260 io->padir &= ~(SIBIT(6)|SIBIT(5));
261
262 /* ETHLOOP etc set in BCSR elsewhere */
263 *rcs = CLK2;
264 *tcs = CLK3;
265 iopunlock();
266 break;
267
268 case SCC1ID: /* assume 860/21 development board */
269 io = ioplock();
270 m->bcsr[1] |= DisableIR|DisableRS232b; /* TO DO: might not be shared with RS232b */
271 m->bcsr[1] &= ~DisableEther;
272 io->papar |= SIBIT(6)|SIBIT(7); /* enable CLK2 and CLK1 */
273 io->padir &= ~(SIBIT(6)|SIBIT(7));
274
275 /* settings peculiar to 860/821 development board */
276 io->pcpar &= ~(SIBIT(4)|SIBIT(5)|SIBIT(6)); /* ETHLOOP, TPFULDL~, TPSQEL~ */
277 io->pcdir |= SIBIT(4)|SIBIT(5)|SIBIT(6);
278 io->pcdat &= ~SIBIT(4);
279 io->pcdat |= SIBIT(5)|SIBIT(6);
280 *rcs = CLK2;
281 *tcs = CLK1;
282 iopunlock();
283 break;
284 }
285 return 0;
286}
287
288void
289archetherdisable(int id)
290{
291 USED(id);
292 m->bcsr[1] |= DisableEther|DisableIR|DisableRS232b;
293}
294
295/*
296 * do anything extra required to enable the UART on the given CPM port
297 */
298void
299archenableuart(int id, int irda)
300{
301 switch(id){
302 case SMC1ID:
303 m->bcsr[1] &= ~DisableRS232a;
304 break;
305 case SCC2ID:
306 m->bcsr[1] |= DisableEther|DisableIR|DisableRS232b;
307 if(irda)
308 m->bcsr[1] &= ~DisableIR;
309 else
310 m->bcsr[1] &= ~DisableRS232b;
311 break;
312 default:
313 /* nothing special */
314 break;
315 }
316}
317
318/*
319 * do anything extra required to disable the UART on the given CPM port
320 */
321void
322archdisableuart(int id)
323{
324 switch(id){
325 case SMC1ID:
326 m->bcsr[1] |= DisableRS232a;
327 break;
328 case SCC2ID:
329 m->bcsr[1] |= DisableIR|DisableRS232b;
330 break;
331 default:
332 /* nothing special */
333 break;
334 }
335}
336
337/*
338 * enable/disable the LCD panel's backlight via
339 * York touch panel interface (does no harm without it)
340 */
341void
342archbacklight(int on)
343{
344 IMM *io;
345
346 delay(2);
347 io = ioplock();
348 io->papar &= ~SIBIT(4);
349 io->padir |= SIBIT(4);
350 if(on)
351 io->padat |= SIBIT(4);
352 else
353 io->padat &= ~SIBIT(4);
354 iopunlock();
355}
os/boot/mpc/archfads.h+42−0
@@ -0,0 +1,42 @@
1
2enum {
3 /* BCSR1 bits */
4 DisableFlash= IBIT(0),
5 DisableDRAM= IBIT(1),
6 DisableEther= IBIT(2),
7 DisableIR= IBIT(3),
8 DisableRS232a= IBIT(7),
9 DisablePCMCIA= IBIT(8),
10 PCCVCCMask= IBIT(9)|IBIT(15),
11 PCCVPPMask= IBIT(10)|IBIT(11),
12 DisableRS232b= IBIT(13),
13 EnableSDRAM= IBIT(14),
14
15 PCCVCC0V= IBIT(15)|IBIT(9),
16 PCCVCC5V= IBIT(9), /* active low */
17 PCCVCC3V= IBIT(15), /* active low */
18 PCCVPP0V= IBIT(10)|IBIT(11), /* active low */
19 PCCVPP5V= IBIT(10), /* active low */
20 PCCVPP12V= IBIT(11), /* active low */
21 PCCVPPHiZ= IBIT(10)|IBIT(11),
22
23 /* BCSR4 bits */
24 DisableTPDuplex= IBIT(1),
25 DisableLamp= IBIT(3),
26 DisableUSB= IBIT(4),
27 USBFullSpeed= IBIT(5),
28 DisableUSBVcc= IBIT(6),
29 DisableVideoLamp= IBIT(8),
30 EnableVideoClock= IBIT(9),
31 EnableVideoPort= IBIT(10),
32 DisableModem= IBIT(11),
33};
34
35enum {
36 /* memory controller CS assignment on FADS boards */
37 BOOTCS = 0,
38 BCSRCS = 1,
39 DRAM1 = 2,
40 DRAM2 = 3,
41 SDRAM = 4,
42};
os/boot/mpc/archpaq.c+240−0
@@ -0,0 +1,240 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7
8#include "archpaq.h"
9
10/*
11 * board-specific support for the 82x PowerPAQ
12 */
13
14enum {
15 SYSMHZ = 50, /* desired system clock in MHz */
16
17 /* sccr */
18 RTSEL = IBIT(8), /* =0, select main oscillator (OSCM); =1, select external crystal (EXTCLK) */
19 RTDIV = IBIT(7), /* =0, divide by 4; =1, divide by 512 */
20 CRQEN = IBIT(9), /* =1, switch to high frequency when CPM active */
21 PRQEN = IBIT(10), /* =1, switch to high frequency when interrupt pending */
22
23 /* plprcr */
24 CSRC = IBIT(21), /* =0, clock is DFNH; =1, clock is DFNL */
25};
26
27/*
28 * called early in main.c, after machinit:
29 * using board and architecture specific registers, initialise
30 * 8xx registers that need it and complete initialisation of the Mach structure.
31 */
32void
33archinit(void)
34{
35 IMM *io;
36 int mf, t;
37
38 switch((getimmr()>>8)&0xFF){
39 case 0x00: t = 0x86000; break; /* also 821 */
40 case 0x20: t = 0x82300; break;
41 case 0x21: t = 0x823a0; break;
42 default: t = 0; break;
43 }
44 m->cputype = t;
45 m->bcsr = nil; /* there isn't one */
46 m->clockgen = 32*1024; /* crystal frequency */
47 io = m->iomem;
48 io->sccrk = KEEP_ALIVE_KEY;
49 io->sccr &= ~RTDIV; /* divide 32k by 4 */
50 io->sccr |= RTSEL;
51 io->sccrk = ~KEEP_ALIVE_KEY;
52 mf = (SYSMHZ*MHz)/m->clockgen;
53 m->cpuhz = m->clockgen*mf;
54 io->plprcrk = KEEP_ALIVE_KEY;
55 io->plprcr &= ~IBIT(21); /* general system clock is DFNH */
56 io->plprcr = (io->plprcr & ((1<<20)-1)) | ((mf-1)<<20);
57 io->mptpr = 0x0400; /* memory prescaler = 16 for refresh */
58 io->plprcrk = ~KEEP_ALIVE_KEY;
59}
60
61void
62cpuidprint(void)
63{
64 int t, v;
65
66 print("PVR: ");
67 t = getpvr()>>16;
68 switch(t){
69 case 0x01: print("MPC601"); break;
70 case 0x03: print("MPC603"); break;
71 case 0x04: print("MPC604"); break;
72 case 0x06: print("MPC603e"); break;
73 case 0x07: print("MPC603e-v7"); break;
74 case 0x50: print("MPC8xx"); break;
75 default: print("PowerPC version #%x", t); break;
76 }
77 print(", revision #%lux\n", getpvr()&0xffff);
78 print("IMMR: ");
79 v = getimmr() & 0xFFFF;
80 switch(v>>8){
81 case 0x00: print("MPC860/821"); break;
82 case 0x20: print("MPC823"); break;
83 case 0x21: print("MPC823A"); break;
84 default: print("Type #%lux", v>>8); break;
85 }
86 print(", mask #%lux\n", v&0xFF);
87 print("plprcr=%8.8lux sccr=%8.8lux\n", m->iomem->plprcr, m->iomem->sccr);
88 print("%lud MHz system\n", m->cpuhz/MHz);
89 print("\n");
90}
91
92static char* defplan9ini[2] = {
93 /* 860/821 */
94 "ether0=type=SCC port=1 ea=00108bf12900\r\n"
95 "vgasize=640x480x8\r\n"
96 "kernelpercent=40\r\n"
97 "console=0 lcd\r\nbaud=19200\r\n",
98
99 /* 823 */
100 "ether0=type=SCC port=2 ea=00108bf12900\r\n"
101 "vgasize=640x480x8\r\n"
102 "kernelpercent=40\r\n"
103 "console=0 lcd\r\nbaud=19200\r\n",
104};
105
106char *
107archconfig(void)
108{
109 print("Using default configuration\n");
110 return defplan9ini[MPCMODEL(m->cputype) == 0x823];
111}
112
113/*
114 * provide value for #r/switch (devrtc.c)
115 */
116int
117archoptionsw(void)
118{
119 return 0;
120}
121
122/*
123 * invoked by clock.c:/^clockintr
124 */
125static void
126twinkle(void)
127{
128 /* no easy-to-use LED on PAQ (they use i2c) */
129}
130
131void (*archclocktick)(void) = twinkle;
132
133/*
134 * for flash.c:/^flashinit
135 * retrieve flash type, virtual base and length and return 0;
136 * return -1 on error (no flash)
137 */
138int
139archflashreset(char *type, void **addr, long *length)
140{
141 strcpy(type, "AMD29F0x0");
142 *addr = KADDR(FLASHMEM);
143 *length = 8*1024*1024; /* 8mbytes on some models */
144 return 0;
145}
146
147/*
148 * enable the clocks for the given SCC ether and reveal them to the caller.
149 * do anything else required to prepare the transceiver (eg, set full-duplex, reset loopback).
150 */
151int
152archetherenable(int cpmid, int *rcs, int *tcs)
153{
154 USED(cpmid, rcs, tcs);
155 return -1; /* there isn't an ether on the PAQs */
156}
157
158void
159archetherdisable(int id)
160{
161 USED(id);
162}
163
164/*
165 * do anything extra required to enable the UART on the given CPM port
166 */
167void
168archenableuart(int id, int irda)
169{
170 IMM *io;
171
172 USED(irda);
173 switch(id){
174 case SMC1ID:
175 io = ioplock();
176 io->pbodr &= ~0xc0;
177 io->pbdat |= 0xc0;
178 io->pcdat |= 0x400;
179 io->pcpar &= ~0x400;
180 io->pcdir |= 0x400;
181 io->pcdat &= ~0x400; /* enable SMC RS232 buffer */
182 iopunlock();
183 break;
184 case SCC2ID:
185 /* TO DO */
186 break;
187 default:
188 /* nothing special */
189 break;
190 }
191}
192
193/*
194 * do anything extra required to disable the UART on the given CPM port
195 */
196void
197archdisableuart(int id)
198{
199 switch(id){
200 case SMC1ID:
201 /* TO DO */
202 break;
203 case SCC2ID:
204 /* TO DO */
205 break;
206 default:
207 /* nothing special */
208 break;
209 }
210}
211
212/*
213 * enable/disable the LCD panel's backlight via i2c
214 */
215void
216archbacklight(int on)
217{
218 uchar msg;
219 IMM *io;
220
221 i2csetup();
222 msg = ~7;
223 i2csend(LEDRegI2C, &msg, 1);
224 io = ioplock();
225 io->pbpar &= ~EnableLCD;
226 io->pbodr &= ~EnableLCD;
227 io->pbdir |= EnableLCD;
228 if(on)
229 io->pbdat |= EnableLCD;
230 else
231 io->pbdat &= ~EnableLCD;
232 iopunlock();
233 if(on){
234 msg = ~(DisablePanelVCC5|DisableTFT);
235 i2csend(PanelI2C, &msg, 1);
236 }else{
237 msg = ~0;
238 i2csend(PanelI2C, &msg, 1);
239 }
240}
os/boot/mpc/archpaq.h+29−0
@@ -0,0 +1,29 @@
1enum {
2 /* memory controller CS assignment on PowerPAQ */
3 BOOTCS = 0,
4 DRAM1 = 1, /* UPMB */
5 DRAM2 = 2, /* UPMB */
6 /* CS3 also connected to DRAM */
7 /* CS4 128mbyte 8-bit gpcm, trlx, 15 wait; it's DAC */
8 /* CS5 is external*/
9};
10
11enum {
12 /* I2C addresses */
13 PanelI2C = 0x21<<1,
14 /* the control bits are active low enables, or high disables */
15 DisableVGA = ~0xFD, /* disable VGA signals */
16 DisableTFT = ~0xFB, /* disable TFT panel signals */
17 DisableSPIBus = ~0xF7, /* disable SPI/I2C to panel */
18 DisablePanelVCC5 = ~0xEF, /* disable +5V to panel(s) */
19 DisablePanelVCC3 = ~0xDF, /* disable +3.3V to panel(s) */
20 DisableMonoPanel = ~0xBF, /* disable mono panel signals */
21 DisableSPISelect = ~0x7F, /* disable SPI chip select to LVDS panel */
22 ContrastI2C = 0x2E<<1,
23 LEDRegI2C = 0x20<<1,
24 DisableGreenLED = ~0xFE,
25 DisableYellowLED = ~0xFD,
26 DisableRedLED = ~0xFB,
27
28 EnableLCD = IBIT(23), /* LCD enable bit in i/o port B */
29};
os/boot/mpc/boot.h+8−0
@@ -0,0 +1,8 @@
1#include <u.h>
2#include "lib.h"
3
4#include "mem.h"
5#include "dat.h"
6#include "fns.h"
7#include "io.h"
8#include "ureg.h"
os/boot/mpc/bootp.c+507−0
@@ -0,0 +1,507 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7
8#include "ip.h"
9
10enum {
11 CHECKSUM = 1, /* set zero if trouble booting from Linux */
12};
13
14uchar broadcast[Eaddrlen] = {
15 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
16};
17
18static ushort tftpport = 5000;
19static int Id = 1;
20static Netaddr myaddr;
21static Netaddr server;
22
23typedef struct {
24 uchar header[4];
25 uchar data[Segsize];
26} Tftp;
27static Tftp tftpb;
28
29static void
30hnputs(uchar *ptr, ushort val)
31{
32 ptr[0] = val>>8;
33 ptr[1] = val;
34}
35
36static void
37hnputl(uchar *ptr, ulong val)
38{
39 ptr[0] = val>>24;
40 ptr[1] = val>>16;
41 ptr[2] = val>>8;
42 ptr[3] = val;
43}
44
45static ulong
46nhgetl(uchar *ptr)
47{
48 return ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]);
49}
50
51static ushort
52nhgets(uchar *ptr)
53{
54 return ((ptr[0]<<8) | ptr[1]);
55}
56
57static short endian = 1;
58static char* aendian = (char*)&endian;
59#define LITTLE *aendian
60
61static ushort
62ptcl_csum(void *a, int len)
63{
64 uchar *addr;
65 ulong t1, t2;
66 ulong losum, hisum, mdsum, x;
67
68 addr = a;
69 losum = 0;
70 hisum = 0;
71 mdsum = 0;
72
73 x = 0;
74 if((ulong)addr & 1) {
75 if(len) {
76 hisum += addr[0];
77 len--;
78 addr++;
79 }
80 x = 1;
81 }
82 while(len >= 16) {
83 t1 = *(ushort*)(addr+0);
84 t2 = *(ushort*)(addr+2); mdsum += t1;
85 t1 = *(ushort*)(addr+4); mdsum += t2;
86 t2 = *(ushort*)(addr+6); mdsum += t1;
87 t1 = *(ushort*)(addr+8); mdsum += t2;
88 t2 = *(ushort*)(addr+10); mdsum += t1;
89 t1 = *(ushort*)(addr+12); mdsum += t2;
90 t2 = *(ushort*)(addr+14); mdsum += t1;
91 mdsum += t2;
92 len -= 16;
93 addr += 16;
94 }
95 while(len >= 2) {
96 mdsum += *(ushort*)addr;
97 len -= 2;
98 addr += 2;
99 }
100 if(x) {
101 if(len)
102 losum += addr[0];
103 if(LITTLE)
104 losum += mdsum;
105 else
106 hisum += mdsum;
107 } else {
108 if(len)
109 hisum += addr[0];
110 if(LITTLE)
111 hisum += mdsum;
112 else
113 losum += mdsum;
114 }
115
116 losum += hisum >> 8;
117 losum += (hisum & 0xff) << 8;
118 while(hisum = losum>>16)
119 losum = hisum + (losum & 0xffff);
120
121 return ~losum;
122}
123
124static ushort
125ip_csum(uchar *addr)
126{
127 int len;
128 ulong sum = 0;
129
130 len = (addr[0]&0xf)<<2;
131
132 while(len > 0) {
133 sum += addr[0]<<8 | addr[1] ;
134 len -= 2;
135 addr += 2;
136 }
137
138 sum = (sum & 0xffff) + (sum >> 16);
139 sum = (sum & 0xffff) + (sum >> 16);
140 return (sum^0xffff);
141}
142
143static void
144udpsend(int ctlrno, Netaddr *a, void *data, int dlen)
145{
146 Udphdr *uh;
147 Etherhdr *ip;
148 static Etherpkt pkt;
149 int len, ptcllen;
150
151
152 uh = (Udphdr*)&pkt;
153
154 memset(uh, 0, sizeof(Etherpkt));
155 memmove(uh->udpcksum+sizeof(uh->udpcksum), data, dlen);
156
157 /*
158 * UDP portion
159 */
160 ptcllen = dlen + (UDP_HDRSIZE-UDP_PHDRSIZE);
161 uh->ttl = 0;
162 uh->udpproto = IP_UDPPROTO;
163 uh->frag[0] = 0;
164 uh->frag[1] = 0;
165 hnputs(uh->udpplen, ptcllen);
166 hnputl(uh->udpsrc, myaddr.ip);
167 hnputs(uh->udpsport, myaddr.port);
168 hnputl(uh->udpdst, a->ip);
169 hnputs(uh->udpdport, a->port);
170 hnputs(uh->udplen, ptcllen);
171 uh->udpcksum[0] = 0;
172 uh->udpcksum[1] = 0;
173 /*dlen = (dlen+1)&~1; */
174 hnputs(uh->udpcksum, ptcl_csum(&uh->ttl, dlen+UDP_HDRSIZE));
175
176 /*
177 * IP portion
178 */
179 ip = (Etherhdr*)&pkt;
180 len = sizeof(Udphdr)+dlen;
181 ip->vihl = IP_VER|IP_HLEN;
182 ip->tos = 0;
183 ip->ttl = 255;
184 hnputs(ip->length, len-ETHER_HDR);
185 hnputs(ip->id, Id++);
186 ip->frag[0] = 0;
187 ip->frag[1] = 0;
188 ip->cksum[0] = 0;
189 ip->cksum[1] = 0;
190 hnputs(ip->cksum, ip_csum(&ip->vihl));
191
192 /*
193 * Ethernet MAC portion
194 */
195 hnputs(ip->type, ET_IP);
196 memmove(ip->d, a->ea, sizeof(ip->d));
197
198 ethertxpkt(ctlrno, &pkt, len, Timeout);
199}
200
201static void
202nak(int ctlrno, Netaddr *a, int code, char *msg, int report)
203{
204 int n;
205 char buf[128];
206
207 buf[0] = 0;
208 buf[1] = Tftp_ERROR;
209 buf[2] = 0;
210 buf[3] = code;
211 strcpy(buf+4, msg);
212 n = strlen(msg) + 4 + 1;
213 udpsend(ctlrno, a, buf, n);
214 if(report)
215 print("\ntftp: error(%d): %s\n", code, msg);
216}
217
218static int
219udprecv(int ctlrno, Netaddr *a, void *data, int dlen)
220{
221 int n, len;
222 ushort csm;
223 Udphdr *h;
224 ulong addr, timo;
225 static Etherpkt pkt;
226 static int rxactive;
227
228 if(rxactive == 0)
229 timo = 1000;
230 else
231 timo = Timeout;
232 timo += TK2MS(m->ticks);
233 while(timo > TK2MS(m->ticks)){
234 n = etherrxpkt(ctlrno, &pkt, timo-TK2MS(m->ticks));
235 if(n <= 0)
236 continue;
237
238 h = (Udphdr*)&pkt;
239 if(nhgets(h->type) != ET_IP)
240 continue;
241
242 if(ip_csum(&h->vihl)) {
243 print("ip chksum error\n");
244 continue;
245 }
246 if(h->vihl != (IP_VER|IP_HLEN)) {
247 print("ip bad vers/hlen\n");
248 continue;
249 }
250
251 if(h->udpproto != IP_UDPPROTO)
252 continue;
253
254 h->ttl = 0;
255 len = nhgets(h->udplen);
256 hnputs(h->udpplen, len);
257
258 if(CHECKSUM && nhgets(h->udpcksum)) {
259 csm = ptcl_csum(&h->ttl, len+UDP_PHDRSIZE);
260 if(csm != 0) {
261 print("udp chksum error csum #%4lux len %d\n", csm, n);
262 break;
263 }
264 }
265
266 if(a->port != 0 && nhgets(h->udpsport) != a->port)
267 continue;
268
269 addr = nhgetl(h->udpsrc);
270 if(a->ip != Bcastip && addr != a->ip)
271 continue;
272
273 len -= UDP_HDRSIZE-UDP_PHDRSIZE;
274 if(len > dlen) {
275 print("udp: packet too big\n");
276 continue;
277 }
278
279 memmove(data, h->udpcksum+sizeof(h->udpcksum), len);
280 a->ip = addr;
281 a->port = nhgets(h->udpsport);
282 memmove(a->ea, pkt.s, sizeof(a->ea));
283
284 rxactive = 1;
285 return len;
286 }
287
288 return 0;
289}
290
291static int tftpblockno;
292
293static int
294tftpopen(int ctlrno, Netaddr *a, char *name, Tftp *tftp)
295{
296 int i, len, rlen, oport;
297 char buf[Segsize+2];
298
299 buf[0] = 0;
300 buf[1] = Tftp_READ;
301 len = sprint(buf+2, "%s", name) + 2;
302 len += sprint(buf+len+1, "octet") + 2;
303
304 oport = a->port;
305 for(i = 0; i < 5; i++){
306 a->port = oport;
307 udpsend(ctlrno, a, buf, len);
308 a->port = 0;
309 if((rlen = udprecv(ctlrno, a, tftp, sizeof(Tftp))) < sizeof(tftp->header))
310 continue;
311
312 switch((tftp->header[0]<<8)|tftp->header[1]){
313
314 case Tftp_ERROR:
315 print("tftpopen: error (%d): %s\n",
316 (tftp->header[2]<<8)|tftp->header[3], tftp->data);
317 return -1;
318
319 case Tftp_DATA:
320 tftpblockno = 1;
321 len = (tftp->header[2]<<8)|tftp->header[3];
322 if(len != tftpblockno){
323 print("tftpopen: block error: %d\n", len);
324 nak(ctlrno, a, 1, "block error", 0);
325 return -1;
326 }
327 return rlen-sizeof(tftp->header);
328 }
329 }
330
331 print("tftpopen: failed to connect to server\n");
332 return -1;
333}
334
335static int
336tftpread(int ctlrno, Netaddr *a, Tftp *tftp, int dlen)
337{
338 int blockno, len, retry;
339 uchar buf[4];
340
341 buf[0] = 0;
342 buf[1] = Tftp_ACK;
343 buf[2] = tftpblockno>>8;
344 buf[3] = tftpblockno;
345 tftpblockno++;
346
347 dlen += sizeof(tftp->header);
348
349 retry = 0;
350buggery:
351 udpsend(ctlrno, a, buf, sizeof(buf));
352
353 if((len = udprecv(ctlrno, a, tftp, dlen)) < dlen){
354 print("tftpread: %d != %d\n", len, dlen);
355 nak(ctlrno, a, 2, "short read", 0);
356 if(retry++ < 5)
357 goto buggery;
358 return -1;
359 }
360
361 blockno = (tftp->header[2]<<8)|tftp->header[3];
362 if(blockno != tftpblockno){
363 print("?");
364
365 if(blockno == tftpblockno-1 && retry++ < 8)
366 goto buggery;
367 print("tftpread: block error: %d, expected %d\n", blockno, tftpblockno);
368 nak(ctlrno, a, 1, "block error", 0);
369
370 return -1;
371 }
372
373 return len-sizeof(tftp->header);
374}
375
376int
377bootp(int ctlrno, char *file)
378{
379 Bootp req, rep;
380 int i, dlen, segsize, text, data, bss, total;
381 uchar *ea, *addr, *p;
382 ulong entry;
383 Exec *exec;
384 char name[128], *filename, *sysname;
385
386 if((ea = etheraddr(ctlrno)) == 0){
387 print("invalid ctlrno %d\n", ctlrno);
388 return -1;
389 }
390
391 filename = 0;
392 sysname = 0;
393 if(file && *file){
394 strcpy(name, file);
395 if(filename = strchr(name, ':')){
396 if(filename != name && *(filename-1) != '\\'){
397 sysname = name;
398 *filename++ = 0;
399 }
400 }
401 else
402 filename = name;
403 }
404
405
406 memset(&req, 0, sizeof(req));
407 req.op = Bootrequest;
408 req.htype = 1; /* ethernet */
409 req.hlen = Eaddrlen; /* ethernet */
410 memmove(req.chaddr, ea, Eaddrlen);
411
412 myaddr.ip = 0;
413 myaddr.port = BPportsrc;
414 memmove(myaddr.ea, ea, Eaddrlen);
415
416 for(i = 0; i < 10; i++) {
417 server.ip = Bcastip;
418 server.port = BPportdst;
419 memmove(server.ea, broadcast, sizeof(server.ea));
420 udpsend(ctlrno, &server, &req, sizeof(req));
421 if(udprecv(ctlrno, &server, &rep, sizeof(rep)) <= 0)
422 continue;
423 if(memcmp(req.chaddr, rep.chaddr, Eaddrlen))
424 continue;
425 if(rep.htype != 1 || rep.hlen != Eaddrlen)
426 continue;
427 if(sysname == 0 || strcmp(sysname, rep.sname) == 0)
428 break;
429 }
430 if(i >= 10) {
431 print("bootp timed out\n");
432 return -1;
433 }
434
435 if(filename == 0 || *filename == 0)
436 filename = rep.file;
437
438 if(rep.sname[0] != '\0')
439 print("%s ", rep.sname);
440 print("(%d.%d.%d.%d!%d): %s\n",
441 rep.siaddr[0],
442 rep.siaddr[1],
443 rep.siaddr[2],
444 rep.siaddr[3],
445 server.port,
446 filename);uartwait();
447
448 myaddr.ip = nhgetl(rep.yiaddr);
449 myaddr.port = tftpport++;
450 server.ip = nhgetl(rep.siaddr);
451 server.port = TFTPport;
452
453 if((dlen = tftpopen(ctlrno, &server, filename, &tftpb)) < 0)
454 return -1;
455 exec = (Exec*)(tftpb.data);
456 if(dlen < sizeof(Exec) || GLLONG(exec->magic) != Q_MAGIC){
457 nak(ctlrno, &server, 0, "bad magic number", 1);
458 return -1;
459 }
460 text = GLLONG(exec->text);
461 data = GLLONG(exec->data);
462 bss = GLLONG(exec->bss);
463 total = text+data+bss;
464 entry = GLLONG(exec->entry);
465print("load@%8.8lux: ", PADDR(entry));uartwait();
466 print("%d", text);
467
468 addr = (uchar*)PADDR(entry);
469 p = tftpb.data+sizeof(Exec);
470 dlen -= sizeof(Exec);
471 segsize = text;
472 for(;;){
473 if(dlen == 0){
474 if((dlen = tftpread(ctlrno, &server, &tftpb, sizeof(tftpb.data))) < 0)
475 return -1;
476 p = tftpb.data;
477 }
478 if(segsize <= dlen)
479 i = segsize;
480 else
481 i = dlen;
482 memmove(addr, p, i);
483
484 addr += i;
485 p += i;
486 segsize -= i;
487 dlen -= i;
488
489 if(segsize <= 0){
490 if(data == 0)
491 break;
492 print("+%d", data);
493 segsize = data;
494 data = 0;
495 addr = (uchar*)PGROUND((ulong)addr);
496 }
497 }
498 nak(ctlrno, &server, 3, "ok", 0); /* tftpclose */
499 print("+%d=%d\n", bss, total);
500 print("entry: 0x%lux\n", entry);
501 uartwait();
502 scc2stop();
503 splhi();
504 (*(void(*)(void))(PADDR(entry)))();
505
506 return 0;
507}
os/boot/mpc/clock.c+71−0
@@ -0,0 +1,71 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7#include "ureg.h"
8
9enum {
10 Timebase = 4, /* system clock cycles per time base cycle */
11};
12
13void (*archclocktick)(void); /* set by arch*.c when desired */
14
15static ulong clkreload;
16
17void
18delay(int l)
19{
20 ulong i, j;
21
22 j = m->delayloop;
23 while(l-- > 0)
24 for(i=0; i < j; i++)
25 ;
26}
27
28void
29microdelay(int l)
30{
31 ulong i;
32
33 l *= m->delayloop;
34 l /= 1000;
35 if(l <= 0)
36 l = 1;
37 for(i = 0; i < l; i++)
38 ;
39}
40
41void
42clockintr(Ureg*, void*)
43{
44 putdec(clkreload);
45 m->ticks++;
46 checkalarms();
47 if(archclocktick != nil)
48 archclocktick();
49}
50
51void
52clockinit(void)
53{
54 long x;
55
56 m->delayloop = m->cpuhz/1000; /* initial estimate */
57 do {
58 x = gettbl();
59 delay(10);
60 x = gettbl() - x;
61 } while(x < 0);
62
63 /*
64 * fix count
65 */
66 m->delayloop = ((vlong)m->delayloop*(10*m->clockgen/1000))/(x*Timebase);
67 if(m->delayloop == 0)
68 m->delayloop = 1;
69 clkreload = (m->clockgen/Timebase)/HZ-1;
70 putdec(clkreload);
71}
os/boot/mpc/conf.c+173−0
@@ -0,0 +1,173 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7
8#include "dosfs.h"
9
10static char *confname[MAXCONF];
11static char *confval[MAXCONF];
12static int nconf;
13
14extern char **ini;
15
16char*
17getconf(char *name)
18{
19 int i;
20
21 for(i = 0; i < nconf; i++)
22 if(strcmp(confname[i], name) == 0)
23 return confval[i];
24 return 0;
25}
26
27/*
28 * read configuration file
29 */
30int
31plan9ini(Dos *dos, char *val)
32{
33 Dosfile rc;
34 int i, n;
35 char *cp, *p, *q, *line[MAXCONF];
36
37 cp = BOOTARGS;
38 if(dos) {
39 if(dosstat(dos, *ini, &rc) <= 0)
40 return -1;
41
42 *cp = 0;
43 n = dosread(&rc, cp, BOOTARGSLEN-1);
44 if(n <= 0)
45 return -1;
46 cp[n] = 0;
47 } else if(val != nil){
48 if(memchr(val, 0, BOOTARGSLEN-1) == nil)
49 return -1;
50 print("Using flash configuration\n");
51 strcpy(cp, val);
52 n = strlen(cp);
53 }else{
54 strcpy(cp, archconfig());
55 n = strlen(cp);
56 }
57
58 /*
59 * Make a working copy.
60 * We could change this to pass the parsed strings
61 * to the booted programme instead of the raw
62 * string, then it only gets done once.
63 */
64 memmove(cp+BOOTARGSLEN, cp, n+1);
65 cp += BOOTARGSLEN;
66
67 /*
68 * Strip out '\r', change '\t' -> ' '.
69 */
70 p = cp;
71 for(q = cp; *q; q++){
72 if(*q == '\r')
73 continue;
74 if(*q == '\t')
75 *q = ' ';
76 *p++ = *q;
77 }
78 *p = 0;
79 n = getcfields(cp, line, MAXCONF, "\n");
80 for(i = 0; i < n; i++){
81 cp = strchr(line[i], '=');
82 if(cp == 0)
83 continue;
84 *cp++ = 0;
85 if(cp - line[i] >= NAMELEN+1)
86 *(line[i]+NAMELEN-1) = 0;
87 confname[nconf] = line[i];
88 confval[nconf] = cp;
89 nconf++;
90 }
91 return 0;
92}
93
94int
95parseether(uchar *to, char *from)
96{
97 char nip[4];
98 char *p;
99 int i;
100
101 p = from;
102 while(*p == ' ')
103 ++p;
104 for(i = 0; i < 6; i++){
105 if(*p == 0)
106 return -1;
107 nip[0] = *p++;
108 if(*p == 0)
109 return -1;
110 nip[1] = *p++;
111 nip[2] = 0;
112 to[i] = strtoul(nip, 0, 16);
113 if(*p == ':')
114 p++;
115 }
116 return 0;
117}
118
119int
120isaconfig(char *class, int ctlrno, ISAConf *isa)
121{
122 char cc[NAMELEN], *p, *q, *r;
123 int n;
124
125 sprint(cc, "%s%d", class, ctlrno);
126 for(n = 0; n < nconf; n++){
127 if(strncmp(confname[n], cc, NAMELEN))
128 continue;
129 isa->nopt = 0;
130 p = confval[n];
131 while(*p){
132 while(*p == ' ' || *p == '\t')
133 p++;
134 if(*p == '\0')
135 break;
136 if(strncmp(p, "type=", 5) == 0){
137 p += 5;
138 for(q = isa->type; q < &isa->type[NAMELEN-1]; q++){
139 if(*p == '\0' || *p == ' ' || *p == '\t')
140 break;
141 *q = *p++;
142 }
143 *q = '\0';
144 }
145 else if(strncmp(p, "port=", 5) == 0)
146 isa->port = strtoul(p+5, &p, 0);
147 else if(strncmp(p, "irq=", 4) == 0)
148 isa->irq = strtoul(p+4, &p, 0);
149 else if(strncmp(p, "mem=", 4) == 0)
150 isa->mem = strtoul(p+4, &p, 0);
151 else if(strncmp(p, "size=", 5) == 0)
152 isa->size = strtoul(p+5, &p, 0);
153 else if(strncmp(p, "ea=", 3) == 0){
154 if(parseether(isa->ea, p+3) == -1)
155 memset(isa->ea, 0, 6);
156 }
157 else if(isa->nopt < NISAOPT){
158 r = isa->opt[isa->nopt];
159 while(*p && *p != ' ' && *p != '\t'){
160 *r++ = *p++;
161 if(r-isa->opt[isa->nopt] >= ISAOPTLEN-1)
162 break;
163 }
164 *r = '\0';
165 isa->nopt++;
166 }
167 while(*p && *p != ' ' && *p != '\t')
168 p++;
169 }
170 return 1;
171 }
172 return 0;
173}
os/boot/mpc/console.c+173−0
@@ -0,0 +1,173 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7
8static Queue* consiq;
9static Queue* consoq;
10
11void
12bothputs(char *s, int n)
13{
14 uartputs(s, n);
15 screenputs(s, n);
16}
17
18static void (*consputs)(char*, int) = bothputs; /* or screenputs */
19
20void
21consinit(void)
22{
23 char *p;
24 int baud, port;
25 static int cgadone;
26
27 p = getconf("console");
28 if(0)
29 if(p == 0 || strcmp(p, "lcd") == 0 || strcmp(p, "screen") == 0){
30 consiq = qopen(4*1024, 0, 0, 0);
31 consoq = qopen(8*1024, 0, 0, 0);
32 consputs = screenputs;
33 return;
34 }
35 if(p!=0 && strstr(p, "lcd") == 0)
36 consputs = bothputs;
37 else
38 consputs = uartputs;
39//consputs = screenputs;
40 port = 0;
41 if(p)
42 port = strtoul(p, 0, 0);
43 baud = 0;
44 if(p = getconf("baud"))
45 baud = strtoul(p, 0, 0);
46 if(baud == 0)
47 baud = 9600;
48 uartspecial(port, baud, &consiq, &consoq, kbdchar);
49}
50
51void
52kbdchar(Queue *q, int c)
53{
54 c &= 0x7F;
55 if(c == 0x10)
56 panic("^p");
57 qbputc(q, c);
58}
59
60static int
61getline(char *buf, int size, int dotimeout)
62{
63 int c, i=0;
64 ulong start;
65 char echo;
66
67 for (;;) {
68 start = m->ticks;
69 do{
70 if(dotimeout && ((m->ticks - start) > 5*HZ))
71 return -2;
72 c = qbgetc(consiq);
73 }while(c == -1);
74 if(c == '\r')
75 c = '\n'; /* turn carriage return into newline */
76 if(c == '\177')
77 c = '\010'; /* turn delete into backspace */
78 if(c == '\025')
79 echo = '\n'; /* echo ^U as a newline */
80 else
81 echo = c;
82 (*consputs)(&echo, 1);
83
84 if(c == '\010'){
85 if(i > 0)
86 i--; /* bs deletes last character */
87 continue;
88 }
89 /* a newline ends a line */
90 if (c == '\n')
91 break;
92 /* ^U wipes out the line */
93 if (c =='\025')
94 return -1;
95 if(i == size)
96 return size;
97 buf[i++] = c;
98 }
99 buf[i] = 0;
100 return i;
101}
102
103int
104getstr(char *prompt, char *buf, int size, char *def)
105{
106 int len, isdefault;
107
108 buf[0] = 0;
109 isdefault = (def && *def);
110 for (;;) {
111 if(isdefault)
112 print("%s[default==%s]: ", prompt, def);
113 else
114 print("%s: ", prompt);
115 len = getline(buf, size, isdefault);
116 switch(len){
117 case -1:
118 /* ^U typed */
119 continue;
120 case -2:
121 /* timeout, use default */
122 (*consputs)("\n", 1);
123 len = 0;
124 break;
125 default:
126 break;
127 }
128 if(len >= size){
129 print("line too long\n");
130 continue;
131 }
132 break;
133 }
134 if(len == 0 && isdefault)
135 strcpy(buf, def);
136 return 0;
137}
138
139int
140sprint(char *s, char *fmt, ...)
141{
142 return donprint(s, s+PRINTSIZE, fmt, (&fmt+1)) - s;
143}
144
145int
146print(char *fmt, ...)
147{
148 char buf[PRINTSIZE];
149 int n;
150
151 if(consputs == 0)
152 return 0;
153 n = donprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
154 (*consputs)(buf, n);
155 return n;
156}
157
158void
159panic(char *fmt, ...)
160{
161 char buf[PRINTSIZE];
162 int n;
163
164 if(consputs){
165 (*consputs)("panic: ", 7);
166 n = donprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
167 (*consputs)(buf, n);
168 (*consputs)("\n", 1);
169 }
170 spllo();
171 for(;;)
172 idle();
173}
os/boot/mpc/cpm.c+162−0
@@ -0,0 +1,162 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7
8enum {
9 BDSIZE= 1024, /* TO DO: check this */
10};
11
12static Map bdmapv[BDSIZE/sizeof(BD)];
13static RMap bdmap = {"buffer descriptors"};
14
15void
16cpminit(void)
17{
18 IMM *io;
19
20 io = m->iomem;
21 io->sdcr = 1;
22 io->lccr &= ~1; /* disable LCD */
23 io->pcint = 0; /* disable all port C interrupts */
24 io->pcso = 0;
25 io->pcdir =0;
26 io->pcpar = 0;
27 io->pcdat = 0;
28 io->papar = 0;
29 io->padir = 0;
30 io->paodr = 0;
31 io->padat = 0;
32 io->pbpar = 0;
33 io->pbdir = 0;
34 io->pbodr = 0;
35 io->pbdat = 0;
36 eieio();
37
38 for(io->cpcr = 0x8001; io->cpcr & 1;) /* reset all CPM channels */
39 eieio();
40
41 mapinit(&bdmap, bdmapv, sizeof(bdmapv));
42 mapfree(&bdmap, DPBASE, BDSIZE);
43}
44
45void
46cpmop(int op, int cno, int param)
47{
48 IMM *io;
49 int s;
50
51 s = splhi();
52 io = m->iomem;
53 eieio();
54 while(io->cpcr & 1)
55 eieio();
56 io->cpcr = (op<<8)|(cno<<4)|(param<<1)|1;
57 eieio();
58 while(io->cpcr & 1)
59 eieio();
60 splx(s);
61}
62
63/*
64 * connect SCCx clocks in NSMI mode (x=1 for USB)
65 */
66void
67sccnmsi(int x, int rcs, int tcs)
68{
69 IMM *io;
70 ulong v;
71 int sh;
72
73 sh = (x-1)*8; /* each SCCx field in sicr is 8 bits */
74 v = (((rcs&7)<<3) | (tcs&7)) << sh;
75 io = ioplock();
76 io->sicr = (io->sicr & ~(0xFF<<sh)) | v;
77 iopunlock();
78}
79
80void
81scc2stop(void)
82{
83 SCC *scc;
84
85 scc = IOREGS(0xA20, SCC);
86 if(scc->gsmrl & (3<<4)){
87 cpmop(GracefulStopTx, SCC2ID, 0);
88 cpmop(CloseRxBD, SCC2ID, 0);
89 delay(1);
90 scc->gsmrl &= ~(3<<4); /* disable current use */
91 archetherdisable(SCC2ID);
92 }
93}
94
95BD *
96bdalloc(int n)
97{
98 ulong a;
99
100 a = mapalloc(&bdmap, 0, n*sizeof(BD), 0);
101 if(a == 0)
102 panic("bdalloc");
103 return KADDR(a);
104}
105
106void
107bdfree(BD *b, int n)
108{
109 if(b){
110 eieio();
111 mapfree(&bdmap, PADDR(b), n*sizeof(BD));
112 }
113}
114
115/*
116 * initialise receive and transmit buffer rings.
117 */
118int
119ioringinit(Ring* r, int nrdre, int ntdre, int bufsize)
120{
121 int i, x;
122
123 /* the ring entries must be aligned on sizeof(BD) boundaries */
124 r->nrdre = nrdre;
125 if(r->rdr == nil)
126 r->rdr = bdalloc(nrdre);
127 /* the buffer size must align with cache lines since the cache doesn't snoop */
128 bufsize = (bufsize+CACHELINESZ-1)&~(CACHELINESZ-1);
129 if(r->rrb == nil)
130 r->rrb = malloc(nrdre*bufsize);
131 if(r->rdr == nil || r->rrb == nil)
132 return -1;
133 dcflush(r->rrb, nrdre*bufsize);
134 x = PADDR(r->rrb);
135 for(i = 0; i < nrdre; i++){
136 r->rdr[i].length = 0;
137 r->rdr[i].addr = x;
138 r->rdr[i].status = BDEmpty|BDInt;
139 x += bufsize;
140 }
141 r->rdr[i-1].status |= BDWrap;
142 r->rdrx = 0;
143
144 r->ntdre = ntdre;
145 if(r->tdr == nil)
146 r->tdr = bdalloc(ntdre);
147 if(r->txb == nil)
148 r->txb = malloc(ntdre*sizeof(Block*));
149 if(r->tdr == nil || r->txb == nil)
150 return -1;
151 for(i = 0; i < ntdre; i++){
152 r->txb[i] = nil;
153 r->tdr[i].addr = 0;
154 r->tdr[i].length = 0;
155 r->tdr[i].status = 0;
156 }
157 r->tdr[i-1].status |= BDWrap;
158 r->tdrh = 0;
159 r->tdri = 0;
160 r->ntq = 0;
161 return 0;
162}
os/boot/mpc/crc32.c+42−0
@@ -0,0 +1,42 @@
1#include "boot.h"
2
3/*
4 * from Rob Warnock
5 */
6static ulong crc32tab[256]; /* initialised on first call to crc32 */
7
8enum {
9 CRC32POLY = 0x04c11db7 /* AUTODIN II, Ethernet, & FDDI */
10};
11
12/*
13 * Build auxiliary table for parallel byte-at-a-time CRC-32.
14 */
15static void
16initcrc32(void)
17{
18 int i, j;
19 ulong c;
20
21 for(i = 0; i < 256; i++) {
22 for(c = i << 24, j = 8; j > 0; j--)
23 if(c & (1<<31))
24 c = (c<<1) ^ CRC32POLY;
25 else
26 c <<= 1;
27 crc32tab[i] = c;
28 }
29}
30
31ulong
32crc32(void *buf, int n, ulong crc)
33{
34 uchar *p;
35
36 if(crc32tab[1] == 0)
37 initcrc32();
38 crc = ~crc;
39 for(p = buf; --n >= 0;)
40 crc = (crc << 8) ^ crc32tab[(crc >> 24) ^ *p++];
41 return ~crc;
42}
os/boot/mpc/dat.h+217−0
@@ -0,0 +1,217 @@
1typedef struct Alarm Alarm;
2typedef struct Block Block;
3typedef struct IMM IMM;
4typedef struct Queue Queue;
5
6typedef struct List {
7 void *next;
8} List;
9
10typedef struct {
11 int fake;
12 int pri;
13} Lock;
14#define lock(x)
15#define unlock(x)
16
17struct Alarm {
18 List;
19 int busy;
20 long dt;
21 void (*f)(Alarm*);
22 void *arg;
23};
24
25enum {
26 Eaddrlen = 6,
27 ETHERMINTU = 60, /* minimum transmit size */
28 ETHERMAXTU = 1514, /* maximum transmit size */
29 ETHERHDRSIZE = 14, /* size of an ethernet header */
30
31 MaxEther = 4,
32};
33
34typedef struct {
35 uchar d[Eaddrlen];
36 uchar s[Eaddrlen];
37 uchar type[2];
38 uchar data[1500];
39 uchar crc[4];
40} Etherpkt;
41
42extern uchar broadcast[Eaddrlen];
43
44enum {
45 Npart = 20+2, /* 8 sub partitions, disk, and partition */
46 Maxxfer = 16*1024, /* maximum transfer size/cmd */
47};
48
49typedef struct {
50 ulong start;
51 ulong end;
52 char name[NAMELEN+1];
53} Partition;
54
55typedef struct {
56 int online;
57 int npart; /* number of real partitions */
58 Partition p[Npart];
59 ulong offset;
60 Partition *current; /* current partition */
61
62 ulong cap; /* total bytes */
63 int bytes; /* bytes/sector */
64 int sectors; /* sectors/track */
65 int heads; /* heads/cyl */
66 long cyl; /* cylinders/drive */
67
68 char lba; /* true if drive has logical block addressing */
69 char multi; /* non-zero if drive does multiple block xfers */
70} Disc;
71
72enum {
73 ScsiTestunit = 0x00,
74 ScsiExtsens = 0x03,
75 ScsiInquiry = 0x12,
76 ScsiModesense = 0x1a,
77 ScsiStartunit = 0x1B,
78 ScsiStopunit = 0x1B,
79 ScsiGetcap = 0x25,
80 ScsiRead = 0x08,
81 ScsiWrite = 0x0a,
82 ScsiExtread = 0x28,
83 ScsiExtwrite = 0x2a,
84
85 /* data direction */
86 ScsiIn = 1,
87 ScsiOut = 0,
88};
89
90typedef struct Scsibuf Scsibuf;
91typedef struct Scsibuf {
92 void* virt;
93 void* phys;
94 Scsibuf* next;
95};
96
97typedef struct Scsidata {
98 uchar* base;
99 uchar* lim;
100 uchar* ptr;
101} Scsidata;
102
103typedef struct Ureg Ureg;
104
105typedef struct Scsi {
106 ulong pid;
107 ushort target;
108 ushort lun;
109 ushort rflag;
110 ushort status;
111 Scsidata cmd;
112 Scsidata data;
113 Scsibuf* b;
114 uchar* save;
115 uchar cmdblk[16];
116} Scsi;
117
118typedef struct Segdesc {
119 ulong d0;
120 ulong d1;
121} Segdesc;
122
123typedef struct Mach {
124 ulong ticks; /* of the clock since boot time */
125 ulong delayloop;
126 long cpuhz; /* general system clock (cycles) */
127 long clockgen; /* clock generator frequency (cycles) */
128 ulong cpupvr; /* cpu type in processor version register */
129 ulong cputype; /* cpu variant in BCD (eg, 0x823xx) */
130 void* alarm; /* alarms bound to this clock */
131 ulong* bcsr;
132 IMM* iomem;
133} Mach;
134
135/* Mach.cputype */
136#define MPCREV(x) ((x) & 0xFF)
137#define MPCMODEL(x) (((x)>>8) & 0xFFF)
138#define MPCFAMILY(x) (((x)>>24) & 0x0F)
139
140
141extern Mach *m;
142
143#define Q_MAGIC ((((4*21)+0)*21)+7)
144
145typedef struct Exec Exec;
146struct Exec
147{
148 uchar magic[4]; /* magic number */
149 uchar text[4]; /* size of text segment */
150 uchar data[4]; /* size of initialized data */
151 uchar bss[4]; /* size of uninitialized data */
152 uchar syms[4]; /* size of symbol table */
153 uchar entry[4]; /* entry point */
154 uchar spsz[4]; /* size of sp/pc offset table */
155 uchar pcsz[4]; /* size of pc/line number table */
156};
157
158/*
159 * bootline passed by boot program
160 */
161#define BOOTLINE ((char *)0x200000-150)
162
163/*
164 * Where we leave configuration info.
165 */
166#define BOOTARGS ((char*)(0x200000))
167#define BOOTARGSLEN 1024
168#define MAXCONF 32
169
170/*
171 * a parsed plan9.ini line
172 */
173#define ISAOPTLEN 16
174#define NISAOPT 8
175
176typedef struct ISAConf {
177 char type[NAMELEN];
178 ulong port;
179 ulong irq;
180 ulong mem;
181 ulong size;
182 uchar ea[6];
183
184 int nopt;
185 char opt[NISAOPT][ISAOPTLEN];
186} ISAConf;
187
188typedef struct {
189 int size;
190 ulong addr;
191} Map;
192
193typedef struct {
194 char* name;
195 Map* map;
196 Map* mapend;
197
198 Lock;
199} RMap;
200
201typedef struct PCIcfg PCIcfg;
202
203extern uchar* vgamem;
204
205struct Block {
206 uchar *rp;
207 uchar *wp;
208 uchar *lim;
209 uchar *data;
210 Block* next;
211 ulong magic;
212};
213#define BLEN(b) ((b)->wp-(b)->rp)
214
215typedef struct QLock {
216 int dummy;
217} QLock;
os/boot/mpc/defont0.c+216−0
@@ -0,0 +1,216 @@
1#include <u.h>
2#include <libc.h>
3#include <libg.h>
4#include <gnot.h>
5
6
7
8static ulong bits0[] = {
9 0x907070f0, 0xf0f07000, 0xf0888888, 0xf8707070, 0xe0e0e0e0, 0xe09070f0, 0x70f870f0, 0xf870f088,
10 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
11 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
12 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000000e0,
13 0xd0808080, 0x80808800, 0x8888c888, 0x80888888, 0x90909090, 0x90d08080, 0x80808080, 0x80888888,
14 0x00000000, 0x08000000, 0x0c300000, 0x00000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
15 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000003c, 0xc03c0000,
16 0x00006000, 0x06001e00, 0x60181860, 0x78000000, 0x00000000, 0x00000000, 0x0000001c, 0x18380090,
17 0xb06060e0, 0xe0e0f800, 0xf088a888, 0x80808080, 0x90909090, 0x90b060e0, 0x808060e0, 0x80808888,
18 0x00182428, 0x3e707018, 0x18180000, 0x00000006, 0x3c183c3c, 0x1c3e3c7e, 0x3c3c0000, 0x0200403c,
19 0x3c187c1e, 0x787e7e1e, 0x663c7c66, 0x6066623c, 0x7c3c7c3c, 0x7e6266c2, 0x66667e30, 0xc00c1000,
20 0x08006000, 0x06003000, 0x60181860, 0x18000000, 0x00000000, 0x10000000, 0x00000030, 0x180c0090,
21 0x90101080, 0x80808818, 0x88f8a888, 0xe0807070, 0xe0e0e0e0, 0xe0901080, 0x70e01080, 0xe098f088,
22 0x00182428, 0x6adad818, 0x18181000, 0x0000000c, 0x66386666, 0x2c3e667e, 0x66660000, 0x06006066,
23 0x42186632, 0x6c606032, 0x66181864, 0x60667224, 0x66246666, 0x186262da, 0x62620630, 0x600c3800,
24 0x10006000, 0x06003000, 0x60000060, 0x18000000, 0x00000000, 0x30000000, 0x00000030, 0x180c00e0,
25 0x00e0e0f0, 0xf0f00018, 0x88889850, 0x80880808, 0x201c1c1c, 0x1c00e0f0, 0x0080e0f0, 0x80888888,
26 0x00182428, 0x68dad808, 0x300c5418, 0x0000000c, 0x66580606, 0x2c206002, 0x66661818, 0x0cfe3006,
27 0x9e2c6660, 0x66606060, 0x6618186c, 0x60667266, 0x66666660, 0x186262da, 0x36660c30, 0x600c2800,
28 0x103c6c3c, 0x3e3c7e3e, 0x6c787866, 0x18d46c3c, 0x6c3e763c, 0x7e6666c2, 0x66667e18, 0x18180000,
29 0x44180000, 0x18241c24, 0xf0888820, 0x8070f0f0, 0x20202020, 0x201c243e, 0x1cf8241c, 0x80708870,
30 0x0018247c, 0x78745008, 0x300c3818, 0x00000018, 0x66180606, 0x4c206006, 0x76661818, 0x18fe180c,
31 0xb62c6660, 0x66606060, 0x66181868, 0x607e5a66, 0x66666470, 0x186266da, 0x34340c30, 0x300c6c00,
32 0x18667666, 0x66663066, 0x76181864, 0x18fe7666, 0x76663666, 0x306662da, 0x62620608, 0x1810323c,
33 0x44247c7c, 0x24342042, 0x00000000, 0x00000000, 0x20202020, 0x20222408, 0x22002420, 0x00000000,
34 0x00180028, 0x3c287610, 0x300cee7e, 0x00fe0018, 0x66180c18, 0x4c3c7c0c, 0x3c3e0000, 0x30000c18,
35 0xb62c7c60, 0x667c7c6e, 0x7e181878, 0x605a5a66, 0x6466783c, 0x186234da, 0x18341830, 0x300c4400,
36 0x18066660, 0x66663066, 0x66181868, 0x18d66666, 0x66663860, 0x306662da, 0x34620c30, 0x180c5a20,
37 0x44241010, 0x242c2042, 0x0e3e103e, 0x3e3c1c3e, 0x3c1c1c1c, 0x1c3e1c08, 0x3e222418, 0x0e0e0e0e,
38 0x0008007c, 0x1e5cdc00, 0x300c387e, 0x00fe0030, 0x66181806, 0x7e066618, 0x6e060000, 0x18001818,
39 0xb67e6660, 0x66606066, 0x6618186c, 0x605a4e66, 0x78666c0e, 0x1862346c, 0x2c183030, 0x180c4400,
40 0x003e6660, 0x667e3066, 0x66181878, 0x18d66666, 0x6666303c, 0x306634da, 0x18341808, 0x18104c38,
41 0x3c181010, 0x18241c42, 0x11081008, 0x20222208, 0x00000000, 0x00220408, 0x22361804, 0x11111111,
42 0x00000028, 0x16b6cc00, 0x300c5418, 0x00000030, 0x66183006, 0x7e066618, 0x66060000, 0x0cfe3000,
43 0x9a466660, 0x66606066, 0x6618186c, 0x605a4e66, 0x60666606, 0x1862346c, 0x6c183030, 0x180c0000,
44 0x00666660, 0x66603066, 0x6618186c, 0x18d66666, 0x66663006, 0x3066346c, 0x2c343018, 0x18180020,
45 0x00091010, 0x000e0942, 0x10081008, 0x20222208, 0x0f06060f, 0x0a09041e, 0x002a0e38, 0x10101010,
46 0x00180028, 0x56b6cc00, 0x300c1018, 0x18001860, 0x66187e66, 0x0c666630, 0x66661818, 0x06fe6018,
47 0x40466632, 0x6c606036, 0x66181866, 0x605a4624, 0x60246666, 0x1834186c, 0x46186030, 0x0c0c0000,
48 0x006e6666, 0x6e66306e, 0x66181866, 0x18d66666, 0x666e3066, 0x306e186c, 0x46186030, 0x180c003c,
49 0x08090909, 0x1f110aff, 0x0e081008, 0x382c2208, 0x08020901, 0x0a0a0911, 0x09220907, 0x0e0e0e0e,
50 0x00180028, 0x7c1c7600, 0x18180000, 0x18001860, 0x3c7e7e3c, 0x0c3c3c30, 0x3c3c1818, 0x02004018,
51 0x3e467c1e, 0x787e601e, 0x663c1866, 0x7e42463c, 0x603c663c, 0x1818186c, 0x66187e30, 0x0c0c0000,
52 0x00367c3c, 0x363c7c36, 0x667e1866, 0x7ed6663c, 0x7c367c3c, 0x1e36186c, 0x66187e30, 0x180c0008,
53 0x080f0606, 0x04110c18, 0x01081008, 0x20222208, 0x0e020203, 0x0a0c0d1e, 0x0d220e08, 0x01010101,
54 0x00000000, 0x10000000, 0x18180000, 0x080000c0, 0x00000000, 0x00000000, 0x00000008, 0x00000000,
55 0x00000000, 0x00000000, 0x00001800, 0x00000000, 0x000c0000, 0x00000000, 0x00000030, 0x060c00fe,
56 0x00000000, 0x00000006, 0x00001800, 0x00000000, 0x60060000, 0x00000000, 0x0010001c, 0x18380008,
57 0x08090606, 0x040e0a18, 0x11081f08, 0x20221c3e, 0x08020401, 0x0f0a0b11, 0x0b220908, 0x11111111,
58 0x00000000, 0x00000000, 0x0c300000, 0x080000c0, 0x00000000, 0x00000000, 0x00000008, 0x00000000,
59 0x00000000, 0x00000000, 0x00007000, 0x00000000, 0x00060000, 0x00000000, 0x0000003c, 0x063c0000,
60 0x00000000, 0x00000066, 0x00001800, 0x00000000, 0x60060000, 0x00000000, 0x00300000, 0x00000008,
61 0x0f090909, 0x04030900, 0x0e000000, 0x00000000, 0x0f0f0f0f, 0x0209091e, 0x09000f07, 0x0e0e0e0e,
62 0x00000000, 0x00000000, 0x00000000, 0x10000000, 0x00000000, 0x00000000, 0x00000010, 0x00000000,
63 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
64 0x00000000, 0x0000003c, 0x00007000, 0x00000000, 0x60060000, 0x00000000, 0x00600000, 0x0000000f,
65
66};
67
68static GBitmap strike0 = {
69 bits0,
70 0,
71 32,
72 0,
73 {0, 0, 1024, 14},
74 {0, 0, 1024, 14},
75};
76
77static Fontchar info0[] = {
78 { 0, 0, 14, 0, 8 },
79 { 8, 0, 14, 0, 8 },
80 { 16, 0, 14, 0, 8 },
81 { 24, 0, 14, 0, 8 },
82 { 32, 0, 14, 0, 8 },
83 { 40, 0, 14, 0, 8 },
84 { 48, 0, 14, 0, 8 },
85 { 56, 0, 14, 0, 8 },
86 { 64, 0, 14, 0, 8 },
87 { 72, 0, 14, 0, 8 },
88 { 80, 0, 14, 0, 8 },
89 { 88, 0, 14, 0, 8 },
90 { 96, 0, 14, 0, 8 },
91 { 104, 0, 14, 0, 8 },
92 { 112, 0, 14, 0, 8 },
93 { 120, 0, 14, 0, 8 },
94 { 128, 0, 14, 0, 8 },
95 { 136, 0, 14, 0, 8 },
96 { 144, 0, 14, 0, 8 },
97 { 152, 0, 14, 0, 8 },
98 { 160, 0, 14, 0, 8 },
99 { 168, 0, 14, 0, 8 },
100 { 176, 0, 14, 0, 8 },
101 { 184, 0, 14, 0, 8 },
102 { 192, 0, 14, 0, 8 },
103 { 200, 0, 14, 0, 8 },
104 { 208, 0, 14, 0, 8 },
105 { 216, 0, 14, 0, 8 },
106 { 224, 0, 14, 0, 8 },
107 { 232, 0, 14, 0, 8 },
108 { 240, 0, 14, 0, 8 },
109 { 248, 0, 14, 0, 8 },
110 { 256, 0, 0, 0, 8 },
111 { 264, 2, 11, 0, 8 },
112 { 272, 2, 6, 0, 8 },
113 { 280, 2, 11, 0, 8 },
114 { 288, 1, 12, 0, 8 },
115 { 296, 2, 11, 0, 8 },
116 { 304, 2, 11, 0, 8 },
117 { 312, 2, 7, 0, 8 },
118 { 320, 1, 13, 0, 8 },
119 { 328, 1, 13, 0, 8 },
120 { 336, 3, 10, 0, 8 },
121 { 344, 4, 10, 0, 8 },
122 { 352, 9, 14, 0, 8 },
123 { 360, 6, 8, 0, 8 },
124 { 368, 9, 11, 0, 8 },
125 { 376, 1, 13, 0, 8 },
126 { 384, 2, 11, 0, 8 },
127 { 392, 2, 11, 0, 8 },
128 { 400, 2, 11, 0, 8 },
129 { 408, 2, 11, 0, 8 },
130 { 416, 2, 11, 0, 8 },
131 { 424, 2, 11, 0, 8 },
132 { 432, 2, 11, 0, 8 },
133 { 440, 2, 11, 0, 8 },
134 { 448, 2, 11, 0, 8 },
135 { 456, 2, 11, 0, 8 },
136 { 464, 4, 11, 0, 8 },
137 { 472, 4, 14, 0, 8 },
138 { 480, 2, 11, 0, 8 },
139 { 488, 4, 10, 0, 8 },
140 { 496, 2, 11, 0, 8 },
141 { 504, 2, 11, 0, 8 },
142 { 512, 2, 11, 0, 8 },
143 { 520, 2, 11, 0, 8 },
144 { 528, 2, 11, 0, 8 },
145 { 536, 2, 11, 0, 8 },
146 { 544, 2, 11, 0, 8 },
147 { 552, 2, 11, 0, 8 },
148 { 560, 2, 11, 0, 8 },
149 { 568, 2, 11, 0, 8 },
150 { 576, 2, 11, 0, 8 },
151 { 584, 2, 11, 0, 8 },
152 { 592, 2, 13, 0, 8 },
153 { 600, 2, 11, 0, 8 },
154 { 608, 2, 11, 0, 8 },
155 { 616, 2, 11, 0, 8 },
156 { 624, 2, 11, 0, 8 },
157 { 632, 2, 11, 0, 8 },
158 { 640, 2, 11, 0, 8 },
159 { 648, 2, 13, 0, 8 },
160 { 656, 2, 11, 0, 8 },
161 { 664, 2, 11, 0, 8 },
162 { 672, 2, 11, 0, 8 },
163 { 680, 2, 11, 0, 8 },
164 { 688, 2, 11, 0, 8 },
165 { 696, 2, 11, 0, 8 },
166 { 704, 2, 11, 0, 8 },
167 { 712, 2, 11, 0, 8 },
168 { 720, 2, 11, 0, 8 },
169 { 728, 1, 13, 0, 8 },
170 { 736, 1, 13, 0, 8 },
171 { 744, 1, 13, 0, 8 },
172 { 752, 2, 8, 0, 8 },
173 { 760, 11, 12, 0, 8 },
174 { 768, 2, 7, 0, 8 },
175 { 776, 4, 11, 0, 8 },
176 { 784, 1, 11, 0, 8 },
177 { 792, 4, 11, 0, 8 },
178 { 800, 1, 11, 0, 8 },
179 { 808, 4, 11, 0, 8 },
180 { 816, 1, 11, 0, 8 },
181 { 824, 4, 14, 0, 8 },
182 { 832, 1, 11, 0, 8 },
183 { 840, 1, 11, 0, 8 },
184 { 848, 1, 14, 0, 8 },
185 { 856, 1, 11, 0, 8 },
186 { 864, 1, 11, 0, 8 },
187 { 872, 4, 11, 0, 8 },
188 { 880, 4, 11, 0, 8 },
189 { 888, 4, 11, 0, 8 },
190 { 896, 4, 14, 0, 8 },
191 { 904, 4, 14, 0, 8 },
192 { 912, 4, 11, 0, 8 },
193 { 920, 4, 11, 0, 8 },
194 { 928, 2, 11, 0, 8 },
195 { 936, 4, 11, 0, 8 },
196 { 944, 4, 11, 0, 8 },
197 { 952, 4, 11, 0, 8 },
198 { 960, 4, 11, 0, 8 },
199 { 968, 4, 14, 0, 8 },
200 { 976, 4, 11, 0, 8 },
201 { 984, 1, 12, 0, 8 },
202 { 992, 1, 12, 0, 8 },
203 { 1000, 1, 12, 0, 8 },
204 { 1008, 5, 8, 0, 8 },
205 { 1016, 0, 14, 0, 8 },
206 { 1024, 0, 14, 0, 8 },
207 { 0, 0, 0, 0, 0 }
208};
209
210GSubfont defont0 = {
211 129,
212 14,
213 2,
214 info0,
215 &strike0,
216};
os/boot/mpc/devether.c+157−0
@@ -0,0 +1,157 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7
8#include "etherif.h"
9
10static Ctlr ether[MaxEther];
11
12static struct {
13 char *type;
14 int (*reset)(Ctlr*);
15} cards[] = {
16 { "SCC", sccethreset, },
17 { "SCC2", sccethreset, },
18 { 0, }
19};
20
21int
22etherinit(void)
23{
24 Ctlr *ctlr;
25 int ctlrno, i, mask, n;
26
27 mask = 0;
28 for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){
29 ctlr = &ether[ctlrno];
30 memset(ctlr, 0, sizeof(Ctlr));
31 if(isaconfig("ether", ctlrno, &ctlr->card) == 0)
32 continue;
33 for(n = 0; cards[n].type; n++){
34 if(strcmp(cards[n].type, ctlr->card.type))
35 continue;
36 ctlr->ctlrno = ctlrno;
37 if((*cards[n].reset)(ctlr))
38 break;
39
40 ctlr->iq = qopen(16*1024, 1, 0, 0);
41 ctlr->oq = qopen(16*1024, 1, 0, 0);
42
43 ctlr->present = 1;
44 mask |= 1<<ctlrno;
45
46 print("ether%d: %s: port 0x%luX irq %d",
47 ctlr->ctlrno, ctlr->card.type, ctlr->card.port, ctlr->card.irq);
48 if(ctlr->card.mem)
49 print(" addr 0x%luX", PADDR(ctlr->card.mem));
50 if(ctlr->card.size)
51 print(" size 0x%luX", ctlr->card.size);
52 print(":");
53 for(i = 0; i < sizeof(ctlr->card.ea); i++)
54 print(" %2.2uX", ctlr->card.ea[i]);
55 print("\n"); uartwait();
56 setvec(VectorPIC + ctlr->card.irq, ctlr->card.intr, ctlr);
57 break;
58 }
59 }
60
61 return mask;
62}
63
64static Ctlr*
65attach(int ctlrno)
66{
67 Ctlr *ctlr;
68
69 if(ctlrno >= MaxEther || ether[ctlrno].present == 0)
70 return 0;
71
72 ctlr = &ether[ctlrno];
73 if(ctlr->present == 1){
74 ctlr->present = 2;
75 (*ctlr->card.attach)(ctlr);
76 }
77
78 return ctlr;
79}
80
81uchar*
82etheraddr(int ctlrno)
83{
84 Ctlr *ctlr;
85
86 if((ctlr = attach(ctlrno)) == 0)
87 return 0;
88
89 return ctlr->card.ea;
90}
91
92int
93etherrxpkt(int ctlrno, Etherpkt *pkt, int timo)
94{
95 int n;
96 Ctlr *ctlr;
97 Block *b;
98 ulong start;
99
100 if((ctlr = attach(ctlrno)) == 0)
101 return 0;
102
103 start = m->ticks;
104 while((b = qget(ctlr->iq)) == 0){
105 if(TK2MS(m->ticks - start) >= timo){
106 /*
107 print("ether%d: rx timeout\n", ctlrno);
108 */
109 return 0;
110 }
111 }
112
113 n = BLEN(b);
114 memmove(pkt, b->rp, n);
115 freeb(b);
116
117 return n;
118}
119
120int
121etheriq(Ctlr *ctlr, Block *b, int freebp)
122{
123 if(memcmp(((Etherpkt*)b->rp)->d, ctlr->card.ea, Eaddrlen) != 0 &&
124 memcmp(((Etherpkt*)b->rp)->d, broadcast, Eaddrlen) != 0){
125 if(freebp)
126 freeb(b);
127 return 0;
128 }
129 qbwrite(ctlr->iq, b);
130 return 1;
131}
132
133int
134ethertxpkt(int ctlrno, Etherpkt *pkt, int len, int)
135{
136 Ctlr *ctlr;
137 Block *b;
138 int s;
139
140 if((ctlr = attach(ctlrno)) == 0)
141 return 0;
142
143 if(qlen(ctlr->oq) > 16*1024){
144 print("ether%d: tx queue full\n", ctlrno);
145 return 0;
146 }
147 b = iallocb(sizeof(Etherpkt));
148 memmove(b->wp, pkt, len);
149 memmove(((Etherpkt*)b->wp)->s, ctlr->card.ea, Eaddrlen);
150 b->wp += len;
151 qbwrite(ctlr->oq, b);
152 s = splhi();
153 (*ctlr->card.transmit)(ctlr);
154 splx(s);
155
156 return 1;
157}
os/boot/mpc/devuart.c+230−0
@@ -0,0 +1,230 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7
8/*
9 * SMC1 in UART mode
10 */
11
12typedef struct Uartsmc Uartsmc;
13struct Uartsmc {
14 IOCparam;
15 ushort maxidl;
16 ushort idlc;
17 ushort brkln;
18 ushort brkec;
19 ushort brkcr;
20 ushort rmask;
21};
22
23typedef struct Uart Uart;
24struct Uart
25{
26 int port;
27 int setup;
28 uchar txbusy;
29
30 Queue* iq;
31 Queue* oq;
32 void (*rx)(Queue*, int);
33 void (*boot)(uchar*, int);
34
35 ulong frame;
36 ulong overrun;
37 uchar rxbuf[128];
38 char txbuf[16];
39 BD* rxb;
40 BD* txb;
41};
42
43Uart uart[1];
44int predawn = 1;
45
46static void uartintr(Ureg*, void*);
47static void uartkick(void*);
48
49static int
50baudgen(int baud)
51{
52 int d;
53
54 d = ((m->cpuhz/baud)+8)>>4;
55 if(d >= (1<<12))
56 return ((d+15)>>3)|1;
57 return d<<1;
58}
59
60static void
61smcsetup(Uart *up, int baud)
62{
63 IMM *io;
64 Uartsmc *p;
65 BD *bd;
66 SMC *smc;
67
68 archenableuart(SMC1ID, 0);
69 io = m->iomem;
70 io->pbpar |= IBIT(24)|IBIT(25); /* enable SMC1 TX/RX */
71 io->pbdir &= ~(IBIT(24)|IBIT(25));
72 io->brgc1 = baudgen(baud) | BaudEnable;
73 io->simode &= ~0xF000; /* SMC1 to NMSI mode, Tx/Rx clocks are BRG1 */
74
75 bd = bdalloc(1);
76 p = (Uartsmc*)KADDR(SMC1P);
77 p->rbase = (ushort)bd;
78 up->rxb = bd;
79 bd->status = BDEmpty|BDWrap|BDInt;
80 bd->length = 0;
81 bd->addr = PADDR(up->rxbuf);
82 bd = bdalloc(1);
83 p->tbase = (ushort)bd;
84 up->txb = bd;
85 bd->status = BDWrap|BDInt;
86 bd->length = 0;
87 bd->addr = PADDR(up->txbuf);
88
89 cpmop(InitRxTx, SMC1ID, 0);
90
91 /* protocol parameters */
92 p->rfcr = 0x18;
93 p->tfcr = 0x18;
94 p->mrblr = 1;
95 p->maxidl = 1;
96 p->brkln = 0;
97 p->brkec = 0;
98 p->brkcr = 1;
99 smc = IOREGS(0xA80, SMC);
100 smc->smce = 0xff; /* clear events */
101 smc->smcm = 0x17; /* enable all possible interrupts */
102 setvec(VectorCPIC+4, uartintr, up);
103 smc->smcmr = 0x4820; /* 8-bit mode, no parity, 1 stop bit, UART mode, ... */
104 smc->smcmr |= 3; /* enable rx/tx */
105}
106
107static void
108uartintr(Ureg*, void *arg)
109{
110 Uart *up;
111 int ch, i;
112 BD *bd;
113 SMC *smc;
114 Block *b;
115
116 up = arg;
117 smc = IOREGS(0xA80, SMC);
118 smc->smce = 0xff; /* clear all events */
119 if((bd = up->rxb) != nil && (bd->status & BDEmpty) == 0){
120 if(up->iq != nil && bd->length > 0){
121 if(up->boot != nil){
122 up->boot(up->rxbuf, bd->length);
123 }else if(up->rx != nil){
124 for(i=0; i<bd->length; i++){
125 ch = up->rxbuf[i];
126 up->rx(up->iq, ch);
127 }
128 }else{
129 b = iallocb(bd->length);
130 memmove(b->wp, up->rxbuf, bd->length);
131 b->wp += bd->length;
132 qbwrite(up->iq, b);
133 }
134 }
135 bd->status |= BDEmpty|BDInt;
136 } else if((bd = up->txb) != nil && (bd->status & BDReady) == 0){
137 ch = -1;
138 if(up->oq)
139 ch = qbgetc(up->oq);
140 if(ch != -1){
141 up->txbuf[0] = ch;
142 bd->length = 1;
143 bd->status |= BDReady;
144 }else
145 up->txbusy = 0;
146 }
147 /* TO DO: modem status, errors, etc */
148}
149
150static void
151uartkick(void *arg)
152{
153 Uart *up = arg;
154 int s, c, i;
155
156 s = splhi();
157 while(up->txbusy == 0 && (c = qbgetc(up->oq)) != -1){
158 if(predawn){
159 while(up->txb->status & BDReady)
160 ;
161 } else {
162 for(i = 0; i < 100; i++){
163 if((up->txb->status & BDReady) == 0)
164 break;
165 delay(1);
166 }
167 }
168 up->txbuf[0] = c;
169 up->txb->length = 1;
170 up->txb->status |= BDReady;
171 up->txbusy = !predawn;
172 }
173 splx(s);
174}
175
176void
177uartspecial(int port, int baud, Queue **iq, Queue **oq, void (*rx)(Queue*,int))
178{
179 Uart *up = &uart[0];
180
181 if(up->setup)
182 return;
183 up->setup = 1;
184
185 *iq = up->iq = qopen(4*1024, 0, 0, 0);
186 *oq = up->oq = qopen(16*1024, 0, uartkick, up);
187 up->rx = rx;
188 USED(port);
189 up->port = SMC1ID;
190 if(baud == 0)
191 baud = 9600;
192 smcsetup(up, baud);
193 /* if using SCCn's UART, would also set DTR and RTS, but SMC doesn't use them */
194}
195
196void
197uartsetboot(void (*f)(uchar*, int))
198{
199 uart[0].boot = f;
200}
201
202void
203uartputs(char *s, int n)
204{
205 Uart *up = &uart[0];
206 Block *b;
207 int nl;
208 char *p;
209
210 nl = 0;
211 for(p = s; p < s+n; p++)
212 if(*p == '\n')
213 nl++;
214 b = iallocb(n+nl);
215 while(n--){
216 if(*s == '\n')
217 *b->wp++ = '\r';
218 *b->wp++ = *s++;
219 }
220 qbwrite(up->oq, b);
221}
222
223void
224uartwait(void)
225{
226 Uart *up = &uart[0];
227
228 while(up->txbusy)
229 ;
230}
os/boot/mpc/dload.c+103−0
@@ -0,0 +1,103 @@
1#include <u.h>
2#include <libc.h>
3#include <bio.h>
4#include <mach.h>
5
6static char *kernelfile = "/power/ipaq";
7ulong crc32(void *buf, int n, ulong crc);
8
9void
10main(int argc, char **argv)
11{
12 int ifd, n;
13 char buf[64], reply[1];
14 int i, execsize;
15 Fhdr f;
16 ulong csum;
17
18 ARGBEGIN{
19 }ARGEND
20 ifd = open(kernelfile, OREAD);
21 if(ifd < 0){
22 fprint(2, "dload: can't open %s: %r\n", kernelfile);
23 exits("open");
24 }
25 i = 0;
26 if(crackhdr(ifd, &f) == 0){
27 fprint(2, "dload: not an executable file: %r\n");
28 exits("format");
29 }
30 if(f.magic != Q_MAGIC){
31 fprint(2, "dload: not a powerpc executable\n");
32 exits("format");
33 }
34 execsize = f.txtsz + f.datsz + f.txtoff;
35 seek(ifd, 0, 0);
36 csum = ~0;
37 while(execsize > 0 && (n = read(ifd, buf, sizeof(buf))) > 0){
38 if(n > execsize)
39 n = execsize;
40 for(;;){
41 if(write(1, buf, sizeof(buf)) != sizeof(buf)){ /* always writes full buffer */
42 fprint(2, "dload: write error: %r\n");
43 exits("write");
44 }
45 if(read(0, reply, 1) != 1){
46 fprint(2, "dload: bad reply\n");
47 exits("read");
48 }
49 if(reply[0] != 'n')
50 break;
51 fprint(2, "!");
52 }
53 if(reply[0] != 'y'){
54 fprint(2, "dload: bad ack: %c\n", reply[0]);
55 exits("reply");
56 }
57 if(++i%10 == 0)
58 fprint(2, ".");
59 execsize -= n;
60 }
61 exits(0);
62}
63
64/*
65 * from Rob Warnock
66 */
67static ulong crc32tab[256]; /* initialised on first call to crc32 */
68
69enum {
70 CRC32POLY = 0x04c11db7 /* AUTODIN II, Ethernet, & FDDI */
71};
72
73/*
74 * Build auxiliary table for parallel byte-at-a-time CRC-32.
75 */
76static void
77initcrc32(void)
78{
79 int i, j;
80 ulong c;
81
82 for(i = 0; i < 256; i++) {
83 for(c = i << 24, j = 8; j > 0; j--)
84 if(c & (1<<31))
85 c = (c<<1) ^ CRC32POLY;
86 else
87 c <<= 1;
88 crc32tab[i] = c;
89 }
90}
91
92ulong
93crc32(void *buf, int n, ulong crc)
94{
95 uchar *p;
96
97 if(crc32tab[1] == 0)
98 initcrc32();
99 crc = ~crc;
100 for(p = buf; --n >= 0;)
101 crc = (crc << 8) ^ crc32tab[(crc >> 24) ^ *p++];
102 return ~crc;
103}
os/boot/mpc/donprint.c+332−0
@@ -0,0 +1,332 @@
1#include "u.h"
2#include "lib.h"
3
4#define PTR sizeof(char*)
5#define SHORT sizeof(int)
6#define INT sizeof(int)
7#define LONG sizeof(long)
8#define IDIGIT 30
9#define MAXCON 30
10
11#define FLONG (1<<0)
12#define FSHORT (1<<1)
13#define FUNSIGN (1<<2)
14
15typedef struct Op Op;
16struct Op
17{
18 char *p;
19 char *ep;
20 void *argp;
21 int f1;
22 int f2;
23 int f3;
24};
25
26static int noconv(Op*);
27static int cconv(Op*);
28static int dconv(Op*);
29static int hconv(Op*);
30static int lconv(Op*);
31static int oconv(Op*);
32static int sconv(Op*);
33static int uconv(Op*);
34static int xconv(Op*);
35static int Xconv(Op*);
36static int percent(Op*);
37
38static
39int (*fmtconv[MAXCON])(Op*) =
40{
41 noconv,
42 cconv, dconv, hconv, lconv,
43 oconv, sconv, uconv, xconv,
44 Xconv, percent,
45};
46static
47char fmtindex[128] =
48{
49 ['c'] 1,
50 ['d'] 2,
51 ['h'] 3,
52 ['l'] 4,
53 ['o'] 5,
54 ['s'] 6,
55 ['u'] 7,
56 ['x'] 8,
57 ['X'] 9,
58 ['%'] 10,
59};
60
61static int convcount = { 11 };
62static int ucase;
63
64static void
65PUT(Op *o, int c)
66{
67 static int pos;
68 int opos;
69
70 if(c == '\t'){
71 opos = pos;
72 pos = (opos+8) & ~7;
73 while(opos++ < pos && o->p < o->ep)
74 *o->p++ = ' ';
75 return;
76 }
77 if(o->p < o->ep){
78 *o->p++ = c;
79 pos++;
80 }
81 if(c == '\n')
82 pos = 0;
83}
84
85int
86fmtinstall(char c, int (*f)(Op*))
87{
88
89 c &= 0177;
90 if(fmtindex[c] == 0) {
91 if(convcount >= MAXCON)
92 return 1;
93 fmtindex[c] = convcount++;
94 }
95 fmtconv[fmtindex[c]] = f;
96 return 0;
97}
98
99char*
100donprint(char *p, char *ep, char *fmt, void *argp)
101{
102 int sf1, c;
103 Op o;
104
105 o.p = p;
106 o.ep = ep;
107 o.argp = argp;
108
109loop:
110 c = *fmt++;
111 if(c != '%') {
112 if(c == 0) {
113 if(o.p < o.ep)
114 *o.p = 0;
115 return o.p;
116 }
117 PUT(&o, c);
118 goto loop;
119 }
120 o.f1 = 0;
121 o.f2 = -1;
122 o.f3 = 0;
123 c = *fmt++;
124 sf1 = 0;
125 if(c == '-') {
126 sf1 = 1;
127 c = *fmt++;
128 }
129 while(c >= '0' && c <= '9') {
130 o.f1 = o.f1*10 + c-'0';
131 c = *fmt++;
132 }
133 if(sf1)
134 o.f1 = -o.f1;
135 if(c != '.')
136 goto l1;
137 c = *fmt++;
138 while(c >= '0' && c <= '9') {
139 if(o.f2 < 0)
140 o.f2 = 0;
141 o.f2 = o.f2*10 + c-'0';
142 c = *fmt++;
143 }
144l1:
145 if(c == 0)
146 fmt--;
147 c = (*fmtconv[fmtindex[c&0177]])(&o);
148 if(c < 0) {
149 o.f3 |= -c;
150 c = *fmt++;
151 goto l1;
152 }
153 o.argp = (char*)o.argp + c;
154 goto loop;
155}
156
157void
158strconv(char *o, Op *op, int f1, int f2)
159{
160 int n, c;
161 char *p;
162
163 n = strlen(o);
164 if(f1 >= 0)
165 while(n < f1) {
166 PUT(op, ' ');
167 n++;
168 }
169 for(p=o; c = *p++;)
170 if(f2 != 0) {
171 PUT(op, c);
172 f2--;
173 }
174 if(f1 < 0) {
175 f1 = -f1;
176 while(n < f1) {
177 PUT(op, ' ');
178 n++;
179 }
180 }
181}
182
183int
184numbconv(Op *op, int base)
185{
186 char b[IDIGIT];
187 int i, f, n, r;
188 long v;
189 short h;
190
191 f = 0;
192 switch(op->f3 & (FLONG|FSHORT|FUNSIGN)) {
193 case FLONG:
194 v = *(long*)op->argp;
195 r = LONG;
196 break;
197
198 case FUNSIGN|FLONG:
199 v = *(ulong*)op->argp;
200 r = LONG;
201 break;
202
203 case FSHORT:
204 h = *(int*)op->argp;
205 v = h;
206 r = SHORT;
207 break;
208
209 case FUNSIGN|FSHORT:
210 h = *(int*)op->argp;
211 v = (ushort)h;
212 r = SHORT;
213 break;
214
215 default:
216 v = *(int*)op->argp;
217 r = INT;
218 break;
219
220 case FUNSIGN:
221 v = *(unsigned*)op->argp;
222 r = INT;
223 break;
224 }
225 if(!(op->f3 & FUNSIGN) && v < 0) {
226 v = -v;
227 f = 1;
228 }
229 b[IDIGIT-1] = 0;
230 for(i = IDIGIT-2;; i--) {
231 n = (ulong)v % base;
232 n += '0';
233 if(n > '9'){
234 n += 'a' - ('9'+1);
235 if(ucase)
236 n += 'A'-'a';
237 }
238 b[i] = n;
239 if(i < 2)
240 break;
241 v = (ulong)v / base;
242 if(op->f2 >= 0 && i >= IDIGIT-op->f2)
243 continue;
244 if(v <= 0)
245 break;
246 }
247 if(f)
248 b[--i] = '-';
249 strconv(b+i, op, op->f1, -1);
250 return r;
251}
252
253static int
254noconv(Op *op)
255{
256
257 strconv("***", op, 0, -1);
258 return 0;
259}
260
261static int
262cconv(Op *op)
263{
264 char b[2];
265
266 b[0] = *(int*)op->argp;
267 b[1] = 0;
268 strconv(b, op, op->f1, -1);
269 return INT;
270}
271
272static int
273dconv(Op *op)
274{
275 return numbconv(op, 10);
276}
277
278static int
279hconv(Op*)
280{
281 return -FSHORT;
282}
283
284static int
285lconv(Op*)
286{
287 return -FLONG;
288}
289
290static int
291oconv(Op *op)
292{
293 return numbconv(op, 8);
294}
295
296static int
297sconv(Op *op)
298{
299 strconv(*(char**)op->argp, op, op->f1, op->f2);
300 return PTR;
301}
302
303static int
304uconv(Op*)
305{
306 return -FUNSIGN;
307}
308
309static int
310xconv(Op *op)
311{
312 return numbconv(op, 16);
313}
314
315static int
316Xconv(Op *op)
317{
318 int r;
319
320 ucase = 1;
321 r = numbconv(op, 16);
322 ucase = 0;
323 return r;
324}
325
326static int
327percent(Op *op)
328{
329
330 PUT(op, '%');
331 return 0;
332}
os/boot/mpc/dosboot.c+614−0
@@ -0,0 +1,614 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "dosfs.h"
7
8extern char *premature;
9
10/*
11 * predeclared
12 */
13static void bootdump(Dosboot*);
14static void setname(Dosfile*, char*);
15long dosreadseg(Dosfile*, long, long);
16
17/*
18 * debugging
19 */
20#define chatty 1
21#define chat if(chatty)print
22
23/*
24 * block io buffers
25 */
26enum
27{
28 Nbio= 16,
29};
30typedef struct Clustbuf Clustbuf;
31struct Clustbuf
32{
33 int age;
34 long sector;
35 uchar *iobuf;
36 Dos *dos;
37 int size;
38};
39Clustbuf bio[Nbio];
40
41/*
42 * get an io block from an io buffer
43 */
44Clustbuf*
45getclust(Dos *dos, long sector)
46{
47 Clustbuf *p, *oldest;
48 int size;
49
50 chat("getclust @ %d\n", sector);
51
52 /*
53 * if we have it, just return it
54 */
55 for(p = bio; p < &bio[Nbio]; p++){
56 if(sector == p->sector && dos == p->dos){
57 p->age = m->ticks;
58 chat("getclust %d in cache\n", sector);
59 return p;
60 }
61 }
62
63 /*
64 * otherwise, reuse the oldest entry
65 */
66 oldest = bio;
67 for(p = &bio[1]; p < &bio[Nbio]; p++){
68 if(p->age <= oldest->age)
69 oldest = p;
70 }
71 p = oldest;
72
73 /*
74 * make sure the buffer is big enough
75 */
76 size = dos->clustsize*dos->sectsize;
77 if(p->iobuf==0 || p->size < size)
78 p->iobuf = ialloc(size, 0);
79 p->size = size;
80
81 /*
82 * read in the cluster
83 */
84 chat("getclust addr %d\n", (sector+dos->start)*dos->sectsize);
85 if((*dos->seek)(dos->dev, (sector+dos->start)*dos->sectsize) < 0){
86 chat("can't seek block\n");
87 return 0;
88 }
89 if((*dos->read)(dos->dev, p->iobuf, size) != size){
90 chat("can't read block\n");
91 return 0;
92 }
93
94 p->age = m->ticks;
95 p->dos = dos;
96 p->sector = sector;
97 chat("getclust %d read\n", sector);
98 return p;
99}
100
101/*
102 * walk the fat one level ( n is a current cluster number ).
103 * return the new cluster number or -1 if no more.
104 */
105static long
106fatwalk(Dos *dos, int n)
107{
108 ulong k, sect;
109 Clustbuf *p;
110 int o;
111
112 chat("fatwalk %d\n", n);
113
114 if(n < 2 || n >= dos->fatclusters)
115 return -1;
116
117 switch(dos->fatbits){
118 case 12:
119 k = (3*n)/2; break;
120 case 16:
121 k = 2*n; break;
122 default:
123 return -1;
124 }
125 if(k >= dos->fatsize*dos->sectsize)
126 panic("getfat");
127
128 sect = (k/(dos->sectsize*dos->clustsize))*dos->clustsize + dos->fataddr;
129 o = k%(dos->sectsize*dos->clustsize);
130 p = getclust(dos, sect);
131 k = p->iobuf[o++];
132 if(o >= dos->sectsize*dos->clustsize){
133 p = getclust(dos, sect+dos->clustsize);
134 o = 0;
135 }
136 k |= p->iobuf[o]<<8;
137 if(dos->fatbits == 12){
138 if(n&1)
139 k >>= 4;
140 else
141 k &= 0xfff;
142 if(k >= 0xff8)
143 k |= 0xf000;
144 }
145 k = k < 0xfff8 ? k : -1;
146 chat("fatwalk %d -> %d\n", n, k);
147 return k;
148}
149
150/*
151 * map a file's logical cluster address to a physical sector address
152 */
153static long
154fileaddr(Dosfile *fp, long ltarget)
155{
156 Dos *dos = fp->dos;
157 long l;
158 long p;
159
160 chat("fileaddr %8.8s %d\n", fp->name, ltarget);
161 /*
162 * root directory is contiguous and easy
163 */
164 if(fp->pstart == 0){
165 if(ltarget*dos->sectsize*dos->clustsize >= dos->rootsize*sizeof(Dosdir))
166 return -1;
167 l = dos->rootaddr + ltarget*dos->clustsize;
168 chat("fileaddr %d -> %d\n", ltarget, l);
169 return l;
170 }
171
172 /*
173 * anything else requires a walk through the fat
174 */
175 if(ltarget >= fp->lcurrent && fp->pcurrent){
176 /* start at the currrent point */
177 l = fp->lcurrent;
178 p = fp->pcurrent;
179 } else {
180 /* go back to the beginning */
181 l = 0;
182 p = fp->pstart;
183 }
184 while(l != ltarget){
185 /* walk the fat */
186 p = fatwalk(dos, p);
187 if(p < 0)
188 return -1;
189 l++;
190 }
191 fp->lcurrent = l;
192 fp->pcurrent = p;
193
194 /*
195 * clusters start at 2 instead of 0 (why? - presotto)
196 */
197 l = dos->dataaddr + (p-2)*dos->clustsize;
198 chat("fileaddr %d -> %d\n", ltarget, l);
199 return l;
200}
201
202/*
203 * read from a dos file
204 */
205long
206dosread(Dosfile *fp, void *a, long n)
207{
208 long addr;
209 long rv;
210 int i;
211 int off;
212 Clustbuf *p;
213 uchar *from, *to;
214
215 if((fp->attr & DDIR) == 0){
216 if(fp->offset >= fp->length)
217 return 0;
218 if(fp->offset+n > fp->length)
219 n = fp->length - fp->offset;
220 }
221
222 to = a;
223 for(rv = 0; rv < n; rv+=i){
224 /*
225 * read the cluster
226 */
227 addr = fileaddr(fp, fp->offset/fp->dos->clustbytes);
228 if(addr < 0)
229 return -1;
230 p = getclust(fp->dos, addr);
231 if(p == 0)
232 return -1;
233
234 /*
235 * copy the bytes we need
236 */
237 off = fp->offset % fp->dos->clustbytes;
238 from = &p->iobuf[off];
239 i = n - rv;
240 if(i > fp->dos->clustbytes - off)
241 i = fp->dos->clustbytes - off;
242 memmove(to, from, i);
243 to += i;
244 fp->offset += i;
245 }
246
247 return rv;
248}
249
250/*
251 * walk a directory returns
252 * -1 if something went wrong
253 * 0 if not found
254 * 1 if found
255 */
256int
257doswalk(Dosfile *file, char *name)
258{
259 Dosdir d;
260 long n;
261
262 if((file->attr & DDIR) == 0){
263 chat("walking non-directory!\n");
264 return -1;
265 }
266
267 setname(file, name);
268
269 file->offset = 0; /* start at the beginning */
270 while((n = dosread(file, &d, sizeof(d))) == sizeof(d)){
271 chat("comparing to %8.8s.%3.3s\n", d.name, d.ext);
272 if(memcmp(file->name, d.name, sizeof(d.name)) != 0)
273 continue;
274 if(memcmp(file->ext, d.ext, sizeof(d.ext)) != 0)
275 continue;
276 if(d.attr & DVLABEL){
277 chat("%8.8s.%3.3s is a LABEL\n", d.name, d.ext);
278 continue;
279 }
280 file->attr = d.attr;
281 file->pstart = GSHORT(d.start);
282 file->length = GLONG(d.length);
283 file->pcurrent = 0;
284 file->lcurrent = 0;
285 file->offset = 0;
286 return 1;
287 }
288 return n >= 0 ? 0 : -1;
289}
290
291
292/*
293 * instructions that boot blocks can start with
294 */
295#define JMPSHORT 0xeb
296#define JMPNEAR 0xe9
297
298/*
299 * read dos file system properties
300 */
301int
302dosinit(Dos *dos, int start, int ishard)
303{
304 Dosboot *b;
305 int i;
306 Clustbuf *p;
307 Dospart *dp;
308 ulong mbroffset, offset;
309
310 /* defaults till we know better */
311 dos->start = start;
312 dos->sectsize = 512;
313 dos->clustsize = 1;
314 mbroffset = 0;
315
316dmddo:
317 /* get first sector */
318 p = getclust(dos, mbroffset);
319 if(p == 0){
320 chat("can't read boot block\n");
321 return -1;
322 }
323
324 /*
325 * If it's a hard disc then look for an MBR and pick either an
326 * active partition or the FAT with the lowest starting LBA.
327 * Things are tricky because we could be pointing to, amongst others:
328 * 1) a floppy BPB;
329 * 2) a hard disc MBR;
330 * 3) a hard disc extended partition table;
331 * 4) a logical drive on a hard disc;
332 * 5) a disc-manager boot block.
333 * They all have the same magic at the end of the block.
334 */
335 if(p->iobuf[0x1FE] != 0x55 || p->iobuf[0x1FF] != 0xAA) {
336 chat("not DOS\n");
337 return -1;
338 }
339 p->dos = 0;
340 b = (Dosboot *)p->iobuf;
341 if(ishard && b->mediadesc != 0xF8){
342 dp = (Dospart*)&p->iobuf[0x1BE];
343 offset = 0xFFFFFFFF;
344 for(i = 0; i < 4; i++, dp++){
345 if(dp->type == DMDDO){
346 mbroffset = 63;
347 goto dmddo;
348 }
349 if(dp->type != FAT12 && dp->type != FAT16 && dp->type != FATHUGE)
350 continue;
351 if(dp->flag & 0x80){
352 offset = GLONG(dp->start);
353 break;
354 }
355 if(GLONG(dp->start) < offset)
356 offset = GLONG(dp->start);
357 }
358 if(i != 4 || offset != 0xFFFFFFFF){
359 dos->start = mbroffset+offset;
360 p = getclust(dos, 0);
361 if(p == 0 || p->iobuf[0x1FE] != 0x55 || p->iobuf[0x1FF] != 0xAA)
362 return -1;
363 }
364 p->dos = 0;
365 }
366
367 b = (Dosboot *)p->iobuf;
368 if(b->magic[0] != JMPNEAR && (b->magic[0] != JMPSHORT || b->magic[2] != 0x90)){
369 chat("no dos file system\n");
370 return -1;
371 }
372
373 if(chatty)
374 bootdump(b);
375
376 /*
377 * determine the systems' wondersous properties
378 */
379 dos->sectsize = GSHORT(b->sectsize);
380 dos->clustsize = b->clustsize;
381 dos->clustbytes = dos->sectsize*dos->clustsize;
382 dos->nresrv = GSHORT(b->nresrv);
383 dos->nfats = b->nfats;
384 dos->rootsize = GSHORT(b->rootsize);
385 dos->volsize = GSHORT(b->volsize);
386 if(dos->volsize == 0)
387 dos->volsize = GLONG(b->bigvolsize);
388 dos->mediadesc = b->mediadesc;
389 dos->fatsize = GSHORT(b->fatsize);
390 dos->fataddr = dos->nresrv;
391 dos->rootaddr = dos->fataddr + dos->nfats*dos->fatsize;
392 i = dos->rootsize*sizeof(Dosdir) + dos->sectsize - 1;
393 i = i/dos->sectsize;
394 dos->dataaddr = dos->rootaddr + i;
395 dos->fatclusters = 2+(dos->volsize - dos->dataaddr)/dos->clustsize;
396 if(dos->fatclusters < 4087)
397 dos->fatbits = 12;
398 else
399 dos->fatbits = 16;
400 dos->freeptr = 2;
401
402 /*
403 * set up the root
404 */
405 dos->root.dos = dos;
406 dos->root.pstart = 0;
407 dos->root.pcurrent = dos->root.lcurrent = 0;
408 dos->root.offset = 0;
409 dos->root.attr = DDIR;
410 dos->root.length = dos->rootsize*sizeof(Dosdir);
411
412 return 0;
413}
414
415static void
416bootdump(Dosboot *b)
417{
418 if(chatty == 0)
419 return;
420 print("magic: 0x%2.2x 0x%2.2x 0x%2.2x\n",
421 b->magic[0], b->magic[1], b->magic[2]);
422 print("version: \"%8.8s\"\n", b->version);
423 print("sectsize: %d\n", GSHORT(b->sectsize));
424 print("allocsize: %d\n", b->clustsize);
425 print("nresrv: %d\n", GSHORT(b->nresrv));
426 print("nfats: %d\n", b->nfats);
427 print("rootsize: %d\n", GSHORT(b->rootsize));
428 print("volsize: %d\n", GSHORT(b->volsize));
429 print("mediadesc: 0x%2.2x\n", b->mediadesc);
430 print("fatsize: %d\n", GSHORT(b->fatsize));
431 print("trksize: %d\n", GSHORT(b->trksize));
432 print("nheads: %d\n", GSHORT(b->nheads));
433 print("nhidden: %d\n", GLONG(b->nhidden));
434 print("bigvolsize: %d\n", GLONG(b->bigvolsize));
435 print("driveno: %d\n", b->driveno);
436 print("reserved0: 0x%2.2x\n", b->reserved0);
437 print("bootsig: 0x%2.2x\n", b->bootsig);
438 print("volid: 0x%8.8x\n", GLONG(b->volid));
439 print("label: \"%11.11s\"\n", b->label);
440}
441
442/*
443 * grab next element from a path, return the pointer to unprocessed portion of
444 * path.
445 */
446static char *
447nextelem(char *path, char *elem)
448{
449 int i;
450
451 while(*path == '/')
452 path++;
453 if(*path==0 || *path==' ')
454 return 0;
455 for(i=0; *path!='\0' && *path!='/' && *path!=' '; i++){
456 if(i==28){
457 print("name component too long\n");
458 return 0;
459 }
460 *elem++ = *path++;
461 }
462 *elem = '\0';
463 return path;
464}
465
466int
467dosstat(Dos *dos, char *path, Dosfile *f)
468{
469 char element[NAMELEN];
470
471 *f = dos->root;
472 while(path = nextelem(path, element)){
473 switch(doswalk(f, element)){
474 case -1:
475 return -1;
476 case 0:
477 return 0;
478 }
479 }
480 return 1;
481}
482
483/*
484 * boot
485 */
486int
487dosboot(Dos *dos, char *path)
488{
489 Dosfile file;
490 long n;
491 long addr;
492 Exec *ep;
493 void (*b)(void);
494
495 switch(dosstat(dos, path, &file)){
496
497 case -1:
498 print("error walking to %s\n", path);
499 return -1;
500 case 0:
501 print("%s not found\n", path);
502 return -1;
503 case 1:
504 print("found %8.8s.%3.3s attr 0x%ux start 0x%lux len %d\n", file.name,
505 file.ext, file.attr, file.pstart, file.length);
506 break;
507 }
508
509 /*
510 * read header
511 */
512 ep = (Exec*)ialloc(sizeof(Exec), 0);
513 n = sizeof(Exec);
514 if(dosreadseg(&file, n, (ulong) ep) != n){
515 print(premature);
516 return -1;
517 }
518 if(GLLONG(ep->magic) != Q_MAGIC){
519 print("bad magic 0x%lux not a plan 9 executable!\n", GLLONG(ep->magic));
520 return -1;
521 }
522
523 /*
524 * read text
525 */
526 addr = PADDR(GLLONG(ep->entry));
527 n = GLLONG(ep->text);
528 print("+%d", n);
529 if(dosreadseg(&file, n, addr) != n){
530 print(premature);
531 return -1;
532 }
533
534 /*
535 * read data (starts at first page after kernel)
536 */
537 addr = PGROUND(addr+n);
538 n = GLLONG(ep->data);
539 print("+%d", n);
540 if(dosreadseg(&file, n, addr) != n){
541 print(premature);
542 return -1;
543 }
544
545 /*
546 * bss and entry point
547 */
548 print("+%d\nstart at 0x%lux\n", GLLONG(ep->bss), GLLONG(ep->entry));
549
550 /*
551 * Go to new code. It's up to the program to get its PC relocated to
552 * the right place.
553 */
554 b = (void (*)(void))(PADDR(GLLONG(ep->entry)));
555 (*b)();
556 return 0;
557}
558
559/*
560 * read in a segment
561 */
562long
563dosreadseg(Dosfile *fp, long len, long addr)
564{
565 char *a;
566 long n, sofar;
567
568 a = (char *)addr;
569 for(sofar = 0; sofar < len; sofar += n){
570 n = 8*1024;
571 if(len - sofar < n)
572 n = len - sofar;
573 n = dosread(fp, a + sofar, n);
574 if(n <= 0)
575 break;
576 print(".");
577 }
578 return sofar;
579}
580
581/*
582 * set up a dos file name
583 */
584static void
585setname(Dosfile *fp, char *from)
586{
587 char *to;
588
589 to = fp->name;
590 for(; *from && to-fp->name < 8; from++, to++){
591 if(*from == '.'){
592 from++;
593 break;
594 }
595 if(*from >= 'a' && *from <= 'z')
596 *to = *from + 'A' - 'a';
597 else
598 *to = *from;
599 }
600 while(to - fp->name < 8)
601 *to++ = ' ';
602
603 to = fp->ext;
604 for(; *from && to-fp->ext < 3; from++, to++){
605 if(*from >= 'a' && *from <= 'z')
606 *to = *from + 'A' - 'a';
607 else
608 *to = *from;
609 }
610 while(to-fp->ext < 3)
611 *to++ = ' ';
612
613 chat("name is %8.8s %3.3s\n", fp->name, fp->ext);
614}
os/boot/mpc/dosfs.h+110−0
@@ -0,0 +1,110 @@
1typedef struct Dosboot Dosboot;
2typedef struct Dos Dos;
3typedef struct Dosdir Dosdir;
4typedef struct Dosfile Dosfile;
5typedef struct Dospart Dospart;
6
7struct Dospart
8{
9 uchar flag; /* active flag */
10 uchar shead; /* starting head */
11 uchar scs[2]; /* starting cylinder/sector */
12 uchar type; /* partition type */
13 uchar ehead; /* ending head */
14 uchar ecs[2]; /* ending cylinder/sector */
15 uchar start[4]; /* starting sector */
16 uchar len[4]; /* length in sectors */
17};
18
19#define FAT12 0x01
20#define FAT16 0x04
21#define FATHUGE 0x06
22#define DMDDO 0x54
23
24struct Dosboot{
25 uchar magic[3];
26 uchar version[8];
27 uchar sectsize[2];
28 uchar clustsize;
29 uchar nresrv[2];
30 uchar nfats;
31 uchar rootsize[2];
32 uchar volsize[2];
33 uchar mediadesc;
34 uchar fatsize[2];
35 uchar trksize[2];
36 uchar nheads[2];
37 uchar nhidden[4];
38 uchar bigvolsize[4];
39 uchar driveno;
40 uchar reserved0;
41 uchar bootsig;
42 uchar volid[4];
43 uchar label[11];
44 uchar reserved1[8];
45};
46
47struct Dosfile{
48 Dos *dos; /* owning dos file system */
49 char name[8];
50 char ext[3];
51 uchar attr;
52 long length;
53 long pstart; /* physical start cluster address */
54 long pcurrent; /* physical current cluster address */
55 long lcurrent; /* logical current cluster address */
56 long offset;
57};
58
59struct Dos{
60 int dev; /* device id */
61 long (*read)(int, void*, long); /* read routine */
62 long (*seek)(int, long); /* seek routine */
63
64 int start; /* start of file system */
65 int sectsize; /* in bytes */
66 int clustsize; /* in sectors */
67 int clustbytes; /* in bytes */
68 int nresrv; /* sectors */
69 int nfats; /* usually 2 */
70 int rootsize; /* number of entries */
71 int volsize; /* in sectors */
72 int mediadesc;
73 int fatsize; /* in sectors */
74 int fatclusters;
75 int fatbits; /* 12 or 16 */
76 long fataddr; /* sector number */
77 long rootaddr;
78 long dataaddr;
79 long freeptr;
80
81 Dosfile root;
82};
83
84struct Dosdir{
85 uchar name[8];
86 uchar ext[3];
87 uchar attr;
88 uchar reserved[10];
89 uchar time[2];
90 uchar date[2];
91 uchar start[2];
92 uchar length[4];
93};
94
95#define DRONLY 0x01
96#define DHIDDEN 0x02
97#define DSYSTEM 0x04
98#define DVLABEL 0x08
99#define DDIR 0x10
100#define DARCH 0x20
101
102extern int chatty;
103
104extern int dosboot(Dos*, char*);
105extern int dosinit(Dos*, int, int);
106extern long dosread(Dosfile*, void*, long);
107extern int dosstat(Dos*, char*, Dosfile*);
108extern int doswalk(Dosfile*, char*);
109
110extern int plan9ini(Dos*, char*);
os/boot/mpc/etherif.h+59−0
@@ -0,0 +1,59 @@
1/*
2 * All the goo for PC ethernet cards.
3 */
4typedef struct Card Card;
5typedef struct Type Type;
6typedef struct Ctlr Ctlr;
7
8/*
9 * Hardware interface.
10 */
11struct Card {
12 ISAConf;
13
14 int (*reset)(Ctlr*);
15 void (*attach)(Ctlr*);
16
17 void *(*read)(Ctlr*, void*, ulong, ulong);
18 void *(*write)(Ctlr*, ulong, void*, ulong);
19
20 void (*receive)(Ctlr*);
21 void (*transmit)(Ctlr*);
22 void (*intr)(Ureg*, void*);
23 void (*overflow)(Ctlr*);
24
25 uchar bit16; /* true if a 16 bit interface */
26 uchar ram; /* true if card has shared memory */
27
28 ulong dp8390; /* I/O address of 8390 (if any) */
29 ulong data; /* I/O data port if no shared memory */
30 uchar nxtpkt; /* software bndry */
31 uchar tstart; /* 8390 ring addresses */
32 uchar pstart;
33 uchar pstop;
34
35 uchar dummyrr; /* do dummy remote read */
36};
37
38/*
39 * Software controller.
40 */
41struct Ctlr {
42 Card card; /* hardware info */
43 int ctlrno;
44 int present;
45
46 Queue* iq;
47 Queue* oq;
48
49 int inpackets;
50 int outpackets;
51 int crcs; /* input crc errors */
52 int oerrs; /* output errors */
53 int frames; /* framing errors */
54 int overflows; /* packet overflows */
55 int buffs; /* buffering errors */
56};
57
58extern int sccethreset(Ctlr*);
59extern int etheriq(Ctlr*, Block*, int);
os/boot/mpc/etherscc.c+411−0
@@ -0,0 +1,411 @@
1/*
2 * SCCn ethernet
3 */
4
5#include "u.h"
6#include "lib.h"
7#include "mem.h"
8#include "dat.h"
9#include "fns.h"
10#include "io.h"
11
12#include "etherif.h"
13
14enum {
15 Nrdre = 32, /* receive descriptor ring entries */
16 Ntdre = 4, /* transmit descriptor ring entries */
17
18 Rbsize = ETHERMAXTU+4, /* ring buffer size (+4 for CRC) */
19 Bufsize = (Rbsize+7)&~7, /* aligned */
20};
21
22enum {
23 /* ether-specific Rx BD bits */
24 RxMiss= 1<<8,
25 RxeLG= 1<<5,
26 RxeNO= 1<<4,
27 RxeSH= 1<<3,
28 RxeCR= 1<<2,
29 RxeOV= 1<<1,
30 RxeCL= 1<<0,
31 RxError= (RxeLG|RxeNO|RxeSH|RxeCR|RxeOV|RxeCL), /* various error flags */
32
33 /* ether-specific Tx BD bits */
34 TxPad= 1<<14, /* pad short frames */
35 TxTC= 1<<10, /* transmit CRC */
36 TxeDEF= 1<<9,
37 TxeHB= 1<<8,
38 TxeLC= 1<<7,
39 TxeRL= 1<<6,
40 TxeUN= 1<<1,
41 TxeCSL= 1<<0,
42
43 /* scce */
44 RXB= 1<<0,
45 TXB= 1<<1,
46 BSY= 1<<2,
47 RXF= 1<<3,
48 TXE= 1<<4,
49
50 /* gsmrl */
51 ENR= 1<<5,
52 ENT= 1<<4,
53
54 /* port A */
55 RXD1= SIBIT(15),
56 TXD1= SIBIT(14),
57
58 /* port B */
59 RTS1= IBIT(19),
60
61 /* port C */
62 CTS1= SIBIT(11),
63 CD1= SIBIT(10),
64};
65
66typedef struct Etherparam Etherparam;
67struct Etherparam {
68 SCCparam;
69 ulong c_pres; /* preset CRC */
70 ulong c_mask; /* constant mask for CRC */
71 ulong crcec; /* CRC error counter */
72 ulong alec; /* alighnment error counter */
73 ulong disfc; /* discard frame counter */
74 ushort pads; /* short frame PAD characters */
75 ushort ret_lim; /* retry limit threshold */
76 ushort ret_cnt; /* retry limit counter */
77 ushort mflr; /* maximum frame length reg */
78 ushort minflr; /* minimum frame length reg */
79 ushort maxd1; /* maximum DMA1 length reg */
80 ushort maxd2; /* maximum DMA2 length reg */
81 ushort maxd; /* rx max DMA */
82 ushort dma_cnt; /* rx dma counter */
83 ushort max_b; /* max bd byte count */
84 ushort gaddr[4]; /* group address filter */
85 ulong tbuf0_data0; /* save area 0 - current frm */
86 ulong tbuf0_data1; /* save area 1 - current frm */
87 ulong tbuf0_rba0;
88 ulong tbuf0_crc;
89 ushort tbuf0_bcnt;
90 ushort paddr[3]; /* physical address LSB to MSB increasing */
91 ushort p_per; /* persistence */
92 ushort rfbd_ptr; /* rx first bd pointer */
93 ushort tfbd_ptr; /* tx first bd pointer */
94 ushort tlbd_ptr; /* tx last bd pointer */
95 ulong tbuf1_data0; /* save area 0 - next frame */
96 ulong tbuf1_data1; /* save area 1 - next frame */
97 ulong tbuf1_rba0;
98 ulong tbuf1_crc;
99 ushort tbuf1_bcnt;
100 ushort tx_len; /* tx frame length counter */
101 ushort iaddr[4]; /* individual address filter*/
102 ushort boff_cnt; /* back-off counter */
103 ushort taddr[3]; /* temp address */
104};
105
106typedef struct {
107 SCC* scc;
108 int port;
109 int cpm;
110
111 BD* rdr; /* receive descriptor ring */
112 void* rrb; /* receive ring buffers */
113 int rdrx; /* index into rdr */
114
115 BD* tdr; /* transmit descriptor ring */
116 void* trb; /* transmit ring buffers */
117 int tdrx; /* index into tdr */
118} Mot;
119static Mot mot[MaxEther];
120
121static int sccid[] = {-1, SCC1ID, SCC2ID, SCC3ID, SCC4ID};
122static int sccparam[] = {-1, SCC1P, SCC2P, SCC3P, SCC4P};
123static int sccreg[] = {-1, 0xA00, 0xA20, 0xA40, 0xA60};
124static int sccirq[] = {-1, 0x1E, 0x1D, 0x1C, 0x1B};
125
126static void
127attach(Ctlr *ctlr)
128{
129 mot[ctlr->ctlrno].scc->gsmrl |= ENR|ENT;
130 eieio();
131}
132
133static void
134transmit(Ctlr *ctlr)
135{
136 int len;
137 Mot *motp;
138 Block *b;
139 BD *tdre;
140
141 motp = &mot[ctlr->ctlrno];
142 while(((tdre = &motp->tdr[motp->tdrx])->status & BDReady) == 0){
143 b = qget(ctlr->oq);
144 if(b == 0)
145 break;
146
147 /*
148 * Copy the packet to the transmit buffer.
149 */
150 len = BLEN(b);
151 memmove(KADDR(tdre->addr), b->rp, len);
152
153 /*
154 * Give ownership of the descriptor to the chip, increment the
155 * software ring descriptor pointer and tell the chip to poll.
156 */
157 tdre->length = len;
158 eieio();
159 tdre->status = (tdre->status & BDWrap) | BDReady|TxPad|BDInt|BDLast|TxTC;
160 eieio();
161 motp->scc->todr = 1<<15; /* transmit now */
162 eieio();
163 motp->tdrx = NEXT(motp->tdrx, Ntdre);
164
165 freeb(b);
166
167 }
168}
169
170static void
171interrupt(Ureg*, void *ap)
172{
173 int len, events, status;
174 Mot *motp;
175 BD *rdre;
176 Block *b;
177 Ctlr *ctlr;
178
179 ctlr = ap;
180 motp = &mot[ctlr->ctlrno];
181
182 /*
183 * Acknowledge all interrupts and whine about those that shouldn't
184 * happen.
185 */
186 events = motp->scc->scce;
187 eieio();
188 motp->scc->scce = events;
189 eieio();
190 if(events & (TXE|BSY|RXB))
191 print("ETHER.SCC#%d: scce = 0x%uX\n", ctlr->ctlrno, events);
192 //print(" %ux|", events);
193 /*
194 * Receiver interrupt: run round the descriptor ring logging
195 * errors and passing valid receive data up to the higher levels
196 * until we encounter a descriptor still owned by the chip.
197 */
198 if(events & (RXF|RXB) || 1){
199 rdre = &motp->rdr[motp->rdrx];
200 while(((status = rdre->status) & BDEmpty) == 0){
201 if(status & RxError || (status & (BDFirst|BDLast)) != (BDFirst|BDLast)){
202 //if(status & RxBuff)
203 // ctlr->buffs++;
204 if(status & (1<<2))
205 ctlr->crcs++;
206 if(status & (1<<1))
207 ctlr->overflows++;
208 //print("eth rx: %ux\n", status);
209 if(status & RxError)
210 print("~");
211 else if((status & BDLast) == 0)
212 print("@");
213 }
214 else{
215 /*
216 * We have a packet. Read it into the next
217 * free ring buffer, if any.
218 */
219 len = rdre->length-4;
220 if((b = iallocb(len)) != 0){
221 memmove(b->wp, KADDR(rdre->addr), len);
222 b->wp += len;
223 etheriq(ctlr, b, 1);
224 }
225 }
226
227 /*
228 * Finished with this descriptor, reinitialise it,
229 * give it back to the chip, then on to the next...
230 */
231 rdre->length = 0;
232 rdre->status = (rdre->status & BDWrap) | BDEmpty | BDInt;
233 eieio();
234
235 motp->rdrx = NEXT(motp->rdrx, Nrdre);
236 rdre = &motp->rdr[motp->rdrx];
237 }
238 }
239
240 /*
241 * Transmitter interrupt: handle anything queued for a free descriptor.
242 */
243 if(events & TXB)
244 transmit(ctlr);
245 if(events & TXE)
246 cpmop(RestartTx, motp->cpm, 0);
247}
248
249static void
250ringinit(Mot* motp)
251{
252 int i, x;
253
254 /*
255 * Initialise the receive and transmit buffer rings. The ring
256 * entries must be aligned on 16-byte boundaries.
257 */
258 if(motp->rdr == 0)
259 motp->rdr = bdalloc(Nrdre);
260 if(motp->rrb == 0)
261 motp->rrb = ialloc(Nrdre*Bufsize, 0);
262 x = PADDR(motp->rrb);
263 for(i = 0; i < Nrdre; i++){
264 motp->rdr[i].length = 0;
265 motp->rdr[i].addr = x;
266 motp->rdr[i].status = BDEmpty|BDInt;
267 x += Bufsize;
268 }
269 motp->rdr[i-1].status |= BDWrap;
270 motp->rdrx = 0;
271
272 if(motp->tdr == 0)
273 motp->tdr = bdalloc(Ntdre);
274 if(motp->trb == 0)
275 motp->trb = ialloc(Ntdre*Bufsize, 0);
276 x = PADDR(motp->trb);
277 for(i = 0; i < Ntdre; i++){
278 motp->tdr[i].addr = x;
279 motp->tdr[i].length = 0;
280 motp->tdr[i].status = TxPad|BDInt|BDLast|TxTC;
281 x += Bufsize;
282 }
283 motp->tdr[i-1].status |= BDWrap;
284 motp->tdrx = 0;
285}
286
287/*
288 * This follows the MPC823 user guide: section16.9.23.7's initialisation sequence,
289 * except that it sets the right bits for the MPC823ADS board when SCC2 is used,
290 * and those for the 860/821 development board for SCC1.
291 */
292static void
293sccsetup(Mot *ctlr, SCC *scc, uchar *ea)
294{
295 int i, rcs, tcs, w;
296 Etherparam *p;
297 IMM *io;
298
299
300 i = 2*(ctlr->port-1);
301 io = ioplock();
302 w = (TXD1|RXD1)<<i; /* TXDn and RXDn in port A */
303 io->papar |= w; /* enable TXDn and RXDn pins */
304 io->padir &= ~w;
305 io->paodr &= ~w; /* not open drain */
306
307 w = (CD1|CTS1)<<i; /* CLSN and RENA: CDn and CTSn in port C */
308 io->pcpar &= ~w; /* enable CLSN (CTSn) and RENA (CDn) */
309 io->pcdir &= ~w;
310 io->pcso |= w;
311 iopunlock();
312
313 /* clocks and transceiver control: details depend on the board's wiring */
314 archetherenable(ctlr->cpm, &rcs, &tcs);
315
316 sccnmsi(ctlr->port, rcs, tcs); /* connect the clocks */
317
318 p = (Etherparam*)KADDR(sccparam[ctlr->port]);
319 memset(p, 0, sizeof(*p));
320 p->rfcr = 0x18;
321 p->tfcr = 0x18;
322 p->mrblr = Bufsize;
323 p->rbase = PADDR(ctlr->rdr);
324 p->tbase = PADDR(ctlr->tdr);
325
326 cpmop(InitRxTx, ctlr->cpm, 0);
327
328 p->c_pres = ~0;
329 p->c_mask = 0xDEBB20E3;
330 p->crcec = 0;
331 p->alec = 0;
332 p->disfc = 0;
333 p->pads = 0x8888;
334 p->ret_lim = 0xF;
335 p->mflr = Rbsize;
336 p->minflr = ETHERMINTU+4;
337 p->maxd1 = Bufsize;
338 p->maxd2 = Bufsize;
339 p->p_per = 0; /* only moderate aggression */
340
341 for(i=0; i<Eaddrlen; i+=2)
342 p->paddr[2-i/2] = (ea[i+1]<<8)|ea[i]; /* it's not the obvious byte order */
343
344 scc->psmr = (2<<10)|(5<<1); /* 32-bit CRC, ignore 22 bits before SFD */
345 scc->dsr = 0xd555;
346 scc->gsmrh = 0; /* normal operation */
347 scc->gsmrl = (1<<28)|(4<<21)|(1<<19)|0xC; /* transmit clock invert, 48 bit preamble, repetitive 10 preamble, ethernet */
348 eieio();
349 scc->scce = ~0; /* clear all events */
350 eieio();
351 scc->sccm = TXE | RXF | TXB; /* enable interrupts */
352 eieio();
353
354 io = ioplock();
355 w = RTS1<<(ctlr->port-1); /* enable TENA pin (RTSn) */
356 io->pbpar |= w;
357 io->pbdir |= w;
358 iopunlock();
359
360 /* gsmrl enable is deferred until attach */
361}
362
363/*
364 * Prepare the SCCx ethernet for booting.
365 */
366int
367sccethreset(Ctlr* ctlr)
368{
369 uchar ea[Eaddrlen];
370 Mot *motp;
371 SCC *scc;
372 char line[50], def[50];
373
374 /*
375 * Since there's no EPROM, insist that the configuration entry
376 * (see conf.c and flash.c) holds the Ethernet address.
377 */
378 memset(ea, 0, Eaddrlen);
379 if(memcmp(ea, ctlr->card.ea, Eaddrlen) == 0){
380 print("no preset Ether address\n");
381 for(;;){
382 strcpy(def, "00108bf12900"); /* valid MAC address to be used only for initial configuration */
383 if(getstr("ether MAC address", line, sizeof(line), def) < 0)
384 return -1;
385 if(parseether(ctlr->card.ea, line) >= 0 || ctlr->card.ea[0] == 0xFF)
386 break;
387 print("invalid MAC address\n");
388 }
389 }
390
391 scc = IOREGS(sccreg[ctlr->card.port], SCC);
392 ctlr->card.irq = VectorCPIC+sccirq[ctlr->card.port];
393
394 motp = &mot[ctlr->ctlrno];
395 motp->scc = scc;
396 motp->port = ctlr->card.port;
397 motp->cpm = sccid[ctlr->card.port];
398
399 ringinit(motp);
400
401 sccsetup(motp, scc, ctlr->card.ea);
402
403 /* enable is deferred until attach */
404
405 ctlr->card.reset = sccethreset;
406 ctlr->card.attach = attach;
407 ctlr->card.transmit = transmit;
408 ctlr->card.intr = interrupt;
409
410 return 0;
411}
os/boot/mpc/fblt.c+531−0
@@ -0,0 +1,531 @@
1#include <u.h>
2#include <libc.h>
3#include <libg.h>
4#include <gnot.h>
5
6/*
7 * bitblt operates a 'word' at a time.
8 * WBITS is the number of bits in a word
9 * LWBITS=log2(WBITS),
10 * W2L is the number of words in a long
11 * WMASK has bits set for the low order word of a long
12 * WType is a pointer to a word
13 */
14#ifndef WBITS
15#define WBITS 32
16#define LWBITS 5
17#define W2L 1
18#define WMASK ~0UL
19typedef ulong *WType;
20#endif
21
22#define DEBUG
23
24#ifdef TEST
25/*
26 * globals used for testing
27 */
28int FORCEFORW;
29int FORCEBAKW;
30GBitmap *curdm, *cursm;
31Point curpt;
32Rectangle curr;
33Fcode curf;
34void *mem;
35#endif
36
37static void
38gbitexplode(ulong sw, ulong *buf, int sdep, int x)
39{
40 int j, o, q, n, nw, inc, qinc;
41 ulong s, dw, pix;
42
43 inc = 1 << sdep;
44 pix = (1 << inc) - 1;
45 nw = 1 << x;
46 n = 32 >> x;
47 qinc = (nw << sdep) - inc;
48 for(o = 32 - n; o >= 0; o -= n){
49 dw = 0;
50 s = sw >> o;
51 q = 0;
52 for(j = 0; j < n; j += inc){
53 dw |= (s & (pix << j)) << q;
54 q += qinc;
55 }
56 for(j = 0; j < x; j++)
57 dw |= dw << (inc << j);
58 *buf++ = dw;
59 }
60}
61
62/*
63void
64main(void)
65{
66 ulong buf[128];
67
68 gbitexplode(0x7777, buf, 0, 3);
69 exits(0);
70}
71*/
72
73void
74gbitblt(GBitmap *dm, Point pt, GBitmap *sm, Rectangle r, Fcode fcode)
75{
76 int width; /* width in bits of dst */
77 int wwidth; /* floor width in words */
78 int height; /* height in pixels minus 1 */
79 int sdep; /* src ldepth */
80 int ddep; /* dst ldepth */
81 int deltadep; /* diff between ldepths */
82 int sspan; /* words between scanlines in src */
83 int dspan; /* words between scanlines in dst */
84 int soff; /* bit offset of src start point */
85 int sdest; /* bit offset of src start point that matches doff when expanded */
86 int doff; /* bit offset of dst start point */
87 int delta; /* amount to shift src by */
88 int sign; /* of delta */
89 ulong *saddr;
90 ulong *daddr;
91 ulong *s;
92 ulong *d;
93 ulong mask;
94 ulong tmp; /* temp storage source word */
95 ulong sw; /* source word constructed */
96 ulong dw; /* dest word fetched */
97 ulong lmask; /* affected pixels in leftmost dst word */
98 ulong rmask; /* affected pixels in rightmost dst word */
99 int i;
100 int j;
101 ulong buf[32]; /* for expanding a source */
102 ulong *p; /* pointer into buf */
103 int spare; /* number of words already converted */
104
105
106#ifdef TEST
107 curdm = dm;
108 cursm = sm;
109 curpt = pt;
110 curr = r;
111 curf = fcode;
112#endif
113
114 gbitbltclip(&dm);
115
116 width = r.max.x - r.min.x;
117 if(width <= 0)
118 return;
119 height = r.max.y - r.min.y - 1;
120 if(height < 0)
121 return;
122
123 ddep = dm->ldepth;
124 pt.x <<= ddep;
125 width <<= ddep;
126
127 sdep = sm->ldepth;
128 r.min.x <<= sdep;
129 r.max.x <<= sdep;
130
131 dspan = dm->width * W2L;
132 sspan = sm->width * W2L;
133
134 daddr = (ulong*)((WType)dm->base
135 + dm->zero*W2L + pt.y*dspan
136 + (pt.x >> LWBITS));
137 saddr = (ulong*)((WType)sm->base
138 + sm->zero*W2L + r.min.y*sspan
139 + (r.min.x >> LWBITS));
140
141 doff = pt.x & (WBITS - 1);
142 lmask = WMASK >> doff;
143 rmask = (WMASK << (WBITS - ((doff+width) & (WBITS-1))))&WMASK;
144 if(!rmask)
145 rmask = WMASK;
146 soff = r.min.x & (WBITS-1);
147 wwidth = ((pt.x+width-1)>>LWBITS) - (pt.x>>LWBITS);
148
149 if(sm == dm){
150#ifdef TEST
151 if(!FORCEBAKW &&
152 (FORCEFORW || sm != dm || saddr > daddr ||
153 (saddr == daddr && soff > doff)))
154 ;
155 else{
156 daddr += height * dspan;
157 saddr += height * sspan;
158 sspan -= 2 * W2L * sm->width;
159 dspan -= 2 * W2L * dm->width;
160 }
161#else
162 if(r.min.y < pt.y){ /* bottom to top */
163 daddr += height * dspan;
164 saddr += height * sspan;
165 sspan -= 2 * W2L * sm->width;
166 dspan -= 2 * W2L * dm->width;
167 }else if(r.min.y == pt.y && r.min.x < pt.x)
168 abort()/*goto right*/;
169#endif
170 }
171 if(wwidth == 0) /* collapse masks for narrow cases */
172 lmask &= rmask;
173 fcode &= F;
174
175 deltadep = ddep - sdep;
176 sdest = doff >> deltadep;
177 delta = soff - sdest;
178 sign = 0;
179 if(delta < 0){
180 sign = 1;
181 delta = -delta;
182 }
183
184 p = 0;
185 for(j = 0; j <= height; j++){
186 d = daddr;
187 s = saddr;
188 mask = lmask;
189 tmp = 0;
190 if(!sign)
191 tmp = *s++;
192 spare = 0;
193 for(i = wwidth; i >= 0; i--){
194 if(spare)
195 sw = *p++;
196 else{
197 if(sign){
198 sw = tmp << (WBITS-delta);
199 tmp = *s++;
200 sw |= tmp >> delta;
201 }else{
202 sw = tmp << delta;
203 tmp = *s++;
204 if(delta)
205 sw |= tmp >> (WBITS-delta);
206 }
207 spare = 1 << deltadep;
208 if(deltadep >= 1){
209 gbitexplode(sw, buf, sdep, deltadep);
210 p = buf;
211 sw = *p++;
212 }
213 }
214
215 dw = *d;
216 switch(fcode){ /* ltor bit aligned */
217 case Zero: *d = dw & ~mask; break;
218 case DnorS: *d = dw ^ ((~sw | dw) & mask); break;
219 case DandnotS: *d = dw ^ ((sw & dw) & mask); break;
220 case notS: *d = dw ^ ((~sw ^ dw) & mask); break;
221 case notDandS: *d = dw ^ ((sw | dw) & mask); break;
222 case notD: *d = dw ^ mask; break;
223 case DxorS: *d = dw ^ (sw & mask); break;
224 case DnandS: *d = dw ^ ((sw | ~dw) & mask); break;
225 case DandS: *d = dw ^ ((~sw & dw) & mask); break;
226 case DxnorS: *d = dw ^ (~sw & mask); break;
227 case D: break;
228 case DornotS: *d = dw | (~sw & mask); break;
229 case S: *d = dw ^ ((sw ^ dw) & mask); break;
230 case notDorS: *d = dw ^ (~(sw & dw) & mask); break;
231 case DorS: *d = dw | (sw & mask); break;
232 case F: *d = dw | mask; break;
233 }
234 d++;
235
236 mask = WMASK;
237 if(i == 1)
238 mask = rmask;
239 spare--;
240 }
241 saddr += sspan;
242 daddr += dspan;
243 }
244}
245
246#ifdef TEST
247void prprog(void);
248GBitmap *bb1, *bb2;
249ulong *src, *dst, *xdst, *xans;
250int swds, dwds;
251long ticks;
252int timeit;
253
254long
255func(int f, long s, int sld, long d, int dld)
256{
257 long a;
258 int sh, i, db, sb;
259
260 db = 1 << dld;
261 sb = 1 << sld;
262 sh = db - sb;
263 if(sh > 0) {
264 a = s;
265 for(i = sb; i<db; i += sb){
266 a <<= sb;
267 s |= a;
268 }
269 } else if(sh < 0)
270 s >>= -sh;
271
272 switch(f){
273 case Zero: d = 0; break;
274 case DnorS: d = ~(d|s); break;
275 case DandnotS: d = d & ~s; break;
276 case notS: d = ~s; break;
277 case notDandS: d = ~d & s; break;
278 case notD: d = ~d; break;
279 case DxorS: d = d ^ s; break;
280 case DnandS: d = ~(d&s); break;
281 case DandS: d = d & s; break;
282 case DxnorS: d = ~(d^s); break;
283 case S: d = s; break;
284 case DornotS: d = d | ~s; break;
285 case D: d = d; break;
286 case notDorS: d = ~d | s; break;
287 case DorS: d = d | s; break;
288 case F: d = ~0; break;
289 }
290
291 d &= ((1<<db)-1);
292 return d;
293}
294
295void
296run(int fr, int to, int w, int op)
297{
298 int i, j, f, t, fy, ty;
299 extern long *_clock;
300
301 fr += bb2->r.min.x;
302 to += bb1->r.min.x;
303 fy = bb2->r.min.y + 1;
304 ty = bb1->r.min.y + 1;
305 if(timeit) {
306 memcpy(dst, xdst, dwds * sizeof(long));
307 ticks -= *_clock;
308 gbitblt(bb1, Pt(to,ty), bb2, Rect(fr,fy,fr+w,fy+2), op);
309 ticks += *_clock;
310 return;
311 }
312 f = fr;
313 t = to;
314 memcpy(dst, xdst, dwds * sizeof(long));
315 for(i=0; i<w; i++) {
316 gbitblt(bb1, Pt(t,ty), bb2, Rect(f,fy,f+1,fy+1), op);
317 gbitblt(bb1, Pt(t,ty+1), bb2, Rect(f,fy+1,f+1,fy+2), op);
318 f++;
319 t++;
320 }
321 memcpy(xans, dst, dwds * sizeof(long));
322
323 memcpy(dst, xdst, dwds * sizeof(long));
324 gbitblt(bb1, Pt(to,ty), bb2, Rect(fr,fy,fr+w,fy+2), op);
325
326 if(memcmp(xans, dst, dwds * sizeof(long))) {
327 /*
328 * print src and dst row offset, width in bits, and forw/back
329 * then print for each of the four rows: the source (s),
330 * the dest (d), the good value of the answer (g),
331 * and the actual bad value of the answer (b)
332 */
333 print("fr=%d to=%d w=%d fb=%d%d\n",
334 fr, to, w, FORCEFORW, FORCEBAKW);
335 print("dst bitmap b %#lux, z %d, w %d, ld %d, r [%d,%d][%d,%d]\n",
336 bb1->base, bb1->zero, bb1->width, bb1->ldepth,
337 bb1->r.min.x, bb1->r.min.y, bb1->r.max.x, bb1->r.max.y);
338 print("src bitmap b %#lux, z %d, w %d, ld %d, r [%d,%d][%d,%d]\n",
339 bb2->base, bb2->zero, bb2->width, bb2->ldepth,
340 bb2->r.min.x, bb2->r.min.y, bb2->r.max.x, bb2->r.max.y);
341 for(j=0; 7*j < dwds; j++) {
342 print("\ns");
343 for(i=0; i<7 && 7*j+i < dwds; i++)
344 print(" %.8lux", src[7*j + i]);
345 print("\nd");
346 for(i=0; i<7 && 7*j+i < dwds; i++)
347 print(" %.8lux", xdst[7*j + i]);
348 print("\ng");
349 for(i=0; i<7 && 7*j+i < dwds; i++)
350 print(" %.8lux", xans[7*j + i]);
351 print("\nb");
352 for(i=0; i<7 && 7*j+i < dwds; i++)
353 print(" %.8lux", dst[7*j + i]);
354 print("\n");
355 }
356 prprog();
357 }
358}
359
360void
361prprog(void)
362{
363 exits(0);
364}
365
366int
367main(int argc, char *argv[])
368{
369 int f, t, w, i, sld, dld, op, iters, simple;
370 ulong s, d, spix, dpix, apix, fpix, m, *ps, *pd;
371 Point sorg, dorg;
372 GBitmap *bs, *bd;
373 long seed;
374 char *ct;
375
376 sld = 0;
377 dld = 0;
378 timeit = 0;
379 iters = 200;
380 simple = 0;
381 ARGBEGIN {
382 case 'i':
383 iters = atoi(ARGF());
384 break;
385 case 's':
386 simple = 1;
387 break;
388 case 't':
389 timeit = 1;
390 ct = ARGF();
391 if(ct)
392 iters = atoi(ct);
393 break;
394 } ARGEND
395 if(argc > 0)
396 sld = atoi(argv[0]);
397 if(argc > 1)
398 dld = atoi(argv[1]);
399 if(!timeit && !simple) {
400 seed = time(0);
401 print("seed %lux\n", seed); srand(seed); /**/
402 }
403
404 print("sld %d dld %d\n", sld, dld);
405 op = 1;
406
407 /* bitmaps for 1-bit tests */
408 bd = gballoc(Rect(0,0,32,1), dld);
409 bs = gballoc(Rect(0,0,32,1), sld);
410 for(i=0; i<bs->width; i++)
411 bs->base[i] = lrand();
412
413 /* bitmaps for rect tests */
414 if(simple) {
415 dorg = Pt(0,0);
416 sorg = Pt(0,0);
417 } else {
418 dorg = Pt(nrand(63)-31,nrand(63)-31);
419 sorg = Pt(nrand(63)-31,nrand(63)-31);
420 }
421 bb1 = gballoc(Rpt(dorg,add(dorg,Pt(200,4))), dld);
422 bb2 = gballoc(Rpt(sorg,add(sorg,Pt(200,4))), sld);
423 dwds = bb1->width * Dy(bb1->r);
424 swds = bb2->width * Dy(bb2->r);
425 dst = bb1->base;
426 src = bb2->base;
427 xdst = malloc(dwds * sizeof(long));
428 xans = malloc(dwds * sizeof(long));
429 for(i=0; i<swds; i++)
430 src[i] = lrand();
431 for(i=0; i<dwds; i++)
432 xdst[i] = lrand();
433
434loop:
435 print("Op %d\n", op);
436 if(!timeit) {
437 print("one pixel\n");
438 ps = bs->base;
439 pd = bd->base;
440 FORCEFORW = 1;
441 FORCEBAKW = 0;
442 for(i=0; i<1000; i++, FORCEFORW = !FORCEFORW, FORCEBAKW = !FORCEBAKW) {
443 f = nrand(32 >> sld);
444 t = nrand(32 >> dld);
445 s = lrand();
446 d = lrand();
447 ps[0] = s;
448 pd[0] = d;
449#ifdef T386
450 spix = (byterev(s) >> (32 - ((f+1)<<sld))) & ((1 << (1<<sld)) - 1);
451 dpix = (byterev(d) >> (32 - ((t+1)<<dld))) & ((1 << (1<<dld)) - 1);
452#else
453 spix = (s >> (32 - ((f+1)<<sld))) & ((1 << (1<<sld)) - 1);
454 dpix = (d >> (32 - ((t+1)<<dld))) & ((1 << (1<<dld)) - 1);
455#endif
456#ifdef T386
457 apix = byterev(func(op, spix, sld, dpix, dld) << (32 - ((t+1)<<dld)));
458#else
459 apix = func(op, spix, sld, dpix, dld) << (32 - ((t+1)<<dld));
460#endif
461 gbitblt(bd, Pt(t,0), bs, Rect(f,0,f+1,1), op);
462 if(ps[0] != s) {
463 print("bb src %.8lux %.8lux %d %d\n", ps[0], s, f, t);
464 exits("error");
465 }
466 m = ((1 << (1<<dld)) - 1) << (32 - ((t+1)<<dld));
467#ifdef T386
468 m = byterev(m);
469#endif
470 if((pd[0] & ~m) != (d & ~m)) {
471 print("bb dst1 %.8lux %.8lux\n",
472 s, d);
473 print("bb %.8lux %.8lux %d %d\n",
474 ps[0], pd[0], f, t);
475 prprog();
476 exits("error");
477 }
478 if((pd[0] & m) != apix) {
479 spix <<= 32 - ((f+1)<<sld);
480 dpix <<= 32 - ((t+1)<<dld);
481#ifdef T386
482 spix = byterev(spix);
483 dpix = byterev(dpix);
484#endif
485 print("bb dst2 %.8lux %.8lux\n",
486 s, d);
487 print("bb %.8lux %.8lux %d %d\n",
488 ps[0], pd[0], f, t);
489 print("bb %.8lux %.8lux %.8lux %.8lux\n",
490 spix, dpix, apix, pd[0] & m);
491 prprog();
492 exits("error");
493 }
494 }
495 }
496
497 print("for\n");
498 FORCEFORW = 1;
499 FORCEBAKW = 0;
500
501 for(i=0; i<iters; i++) {
502 f = nrand(64);
503 t = nrand(64);
504 w = nrand(130);
505 run(f, t, w, op);
506 }
507
508 if(sld == dld) {
509 print("bak\n");
510 FORCEFORW = 0;
511 FORCEBAKW = 1;
512
513 for(i=0; i<iters; i++) {
514 f = nrand(64);
515 t = nrand(64);
516 w = nrand(130);
517 run(f, t, w, op);
518 }
519 }
520
521 if(op < F) {
522 op++;
523 goto loop;
524 }
525 if(timeit)
526 print("time: %d ticks\n", ticks);
527 exits(0);
528}
529
530
531#endif
os/boot/mpc/flash.c+212−0
@@ -0,0 +1,212 @@
1#include "boot.h"
2
3typedef struct Flashdev Flashdev;
4struct Flashdev {
5 uchar* base;
6 int size;
7 uchar* exec;
8 char* config;
9 int conflen;
10};
11
12enum {
13 FLASHSEG = 256*1024,
14 CONFIGLIM = FLASHSEG,
15 BOOTOFF = FLASHSEG,
16 BOOTLEN = 3*FLASHSEG, /* third segment might be filsys */
17 /* rest of flash is free */
18};
19
20static Flashdev flash;
21
22/*
23 * configuration data is written between the bootstrap and
24 * the end of region 0. the region ends with allocation descriptors
25 * of the following form:
26 *
27 * byte order is big endian
28 *
29 * the last valid region found that starts with the string "#plan9.ini\n" is plan9.ini
30 */
31typedef struct Flalloc Flalloc;
32struct Flalloc {
33 ulong check; /* checksum of data, or ~0 */
34 ulong base; /* base of region; ~0 if unallocated, 0 if deleted */
35 uchar len[3];
36 uchar tag; /* see below */
37 uchar sig[4];
38};
39
40enum {
41 /* tags */
42 Tdead= 0,
43 Tboot= 0x01, /* space reserved for boot */
44 Tconf= 0x02, /* configuration data */
45 Tnone= 0xFF,
46
47 Noval= ~0,
48};
49
50static char flashsig[] = {0xF1, 0xA5, 0x5A, 0x1F};
51static char conftag[] = "#plan9.ini\n";
52
53static ulong
54checksum(uchar* p, int n)
55{
56 ulong s;
57
58 for(s=0; --n >= 0;)
59 s += *p++;
60 return s;
61}
62
63static int
64validptr(Flalloc *ap, uchar *p)
65{
66 return p > (uchar*)&end && p < (uchar*)ap;
67}
68
69static int
70flashcheck(Flalloc *ap, char **val, int *len)
71{
72 uchar *base;
73 int n;
74
75 if(ap->base == Noval || ap->base >= FLASHSEG || ap->tag == Tnone)
76 return 0;
77 base = flash.base+ap->base;
78 if(!validptr(ap, base))
79 return 0;
80 n = (((ap->len[0]<<8)|ap->len[1])<<8)|ap->len[2];
81 if(n == 0xFFFFFF)
82 n = 0;
83 if(n < 0)
84 return 0;
85 if(n > 0 && !validptr(ap, base+n-1))
86 return 0;
87 if(ap->check != Noval && checksum(base, n) != ap->check){
88 print("flash: bad checksum\n");
89 return 0;
90 }
91 *val = (char*)base;
92 *len = n;
93 return 1;
94}
95
96int
97flashinit(void)
98{
99 int len;
100 char *val;
101 Flalloc *ap;
102 void *addr;
103 long mbytes;
104 char type[20];
105
106 flash.base = 0;
107 flash.exec = 0;
108 flash.size = 0;
109 if(archflashreset(type, &addr, &mbytes) < 0){
110 print("flash: flash not present or not enabled\n"); /* shouldn't happen */
111 return 0;
112 }
113 flash.size = mbytes;
114 flash.base = addr;
115 flash.exec = flash.base + BOOTOFF;
116 flash.config = nil;
117 flash.conflen = 0;
118
119 for(ap = (Flalloc*)(flash.base+CONFIGLIM)-1; memcmp(ap->sig, flashsig, 4) == 0; ap--){
120 if(0)
121 print("conf #%8.8lux: #%x #%6.6lux\n", ap, ap->tag, ap->base);
122 if(ap->tag == Tconf &&
123 flashcheck(ap, &val, &len) &&
124 len >= sizeof(conftag)-1 &&
125 memcmp(val, conftag, sizeof(conftag)-1) == 0){
126 flash.config = val;
127 flash.conflen = len;
128 if(0)
129 print("flash: found config %8.8lux(%d):\n%s\n", val, len, val);
130 }
131 }
132 if(flash.config == nil)
133 print("flash: no config\n");
134 else
135 print("flash config %8.8lux(%d):\n%s\n", flash.config, flash.conflen, flash.config);
136 if(issqueezed(flash.exec) == Q_MAGIC){
137 print("flash: squeezed powerpc kernel installed\n");
138 return 1<<0;
139 }
140 if(GLLONG(flash.exec) == Q_MAGIC){
141 print("flash: unsqueezed powerpc kernel installed\n");
142 return 1<<0;
143 }
144 flash.exec = 0;
145 print("flash: no powerpc kernel in Flash\n");
146 return 0;
147}
148
149char*
150flashconfig(int)
151{
152 return flash.config;
153}
154
155int
156flashbootable(int)
157{
158 return flash.exec != nil && (issqueezed(flash.exec) || GLLONG(flash.exec) == Q_MAGIC);
159}
160
161int
162flashboot(int)
163{
164 ulong entry, addr;
165 void (*b)(void);
166 Exec *ep;
167 Block in;
168 long n;
169 uchar *p;
170
171 if(flash.exec == 0)
172 return -1;
173 p = flash.exec;
174 if(GLLONG(p) == Q_MAGIC){
175 /* unsqueezed: copy data and perhaps text, then jump to it */
176 ep = (Exec*)p;
177 entry = PADDR(GLLONG(ep->entry));
178 p += sizeof(Exec);
179 addr = entry;
180 n = GLLONG(ep->text);
181 if(addr != (ulong)p){
182 memmove((void*)addr, p, n);
183 print("text: %8.8lux <- %8.8lux [%ld]\n", addr, p, n);
184 }
185 p += n;
186 if(entry >= FLASHMEM)
187 addr = 3*BY2PG; /* kernel text is in Flash, data in RAM */
188 else
189 addr = PGROUND(addr+n);
190 n = GLLONG(ep->data);
191 memmove((void*)addr, p, n);
192 print("data: %8.8lux <- %8.8lux [%ld]\n", addr, p, n);
193 }else{
194 in.data = p;
195 in.rp = in.data;
196 in.lim = p+BOOTLEN;
197 in.wp = in.lim;
198 n = unsqueezef(&in, &entry);
199 if(n < 0)
200 return -1;
201 }
202 print("entry=0x%lux\n", entry);
203 uartwait();
204 scc2stop();
205 /*
206 * Go to new code. It's up to the program to get its PC relocated to
207 * the right place.
208 */
209 b = (void (*)(void))KADDR(PADDR(entry));
210 (*b)();
211 return -1;
212}
os/boot/mpc/fns.h+117−0
@@ -0,0 +1,117 @@
1Alarm* alarm(int, void (*)(Alarm*), void*);
2void alarminit(void);
3void archbacklight(int);
4char* archconfig(void);
5void archdisableuart(int);
6void archenableuart(int, int);
7void archenableusb(int);
8void archetherdisable(int);
9int archetherenable(int, int*, int*);
10int archflashreset(char*, void**, long*);
11void archinit(void);
12int archoptionsw(void);
13int bootp(int, char*);
14void cancel(Alarm*);
15void checkalarms(void);
16void clockinit(void);
17void clockintr(Ureg*, void*);
18void consinit(void);
19void cpminit(void);
20void cpuidprint(void);
21#define dcflush(a,b)
22void delay(int);
23void eieio(void);
24uchar* etheraddr(int);
25int etherinit(void);
26int etherrxpkt(int, Etherpkt*, int);
27int ethertxpkt(int, Etherpkt*, int, int);
28void exception(void);
29int flashboot(int);
30int flashbootable(int);
31char* flashconfig(int);
32int flashinit(void);
33void free(void*);
34void freeb(Block*);
35int getcfields(char*, char**, int, char*);
36char* getconf(char*);
37ulong getdec(void);
38ulong gethid0(void);
39ulong getimmr(void);
40ulong getmsr(void);
41ulong getpvr(void);
42int getstr(char*, char*, int, char*);
43ulong gettbl(void);
44ulong gettbu(void);
45int hardinit(void);
46long hardread(int, void*, long);
47long hardseek(int, long);
48long hardwrite(int, void*, long);
49long i2csend(int, void*, long);
50void i2csetup(void);
51void* ialloc(ulong, int);
52Block* iallocb(int);
53void idle(void);
54int isaconfig(char*, int, ISAConf*);
55int issqueezed(uchar*);
56void kbdchar(Queue*, int);
57void kbdinit(void);
58void kbdreset(void);
59void machinit(void);
60void* malloc(ulong);
61ulong mapalloc(RMap*, ulong, int, int);
62void mapfree(RMap*, ulong, int);
63void mapinit(RMap*, Map*, int);
64void meminit(void);
65void microdelay(int);
66void mmuinit(void);
67int optionsw(void);
68void panic(char*, ...);
69int parseether(uchar*, char*);
70int plan9boot(int, long (*)(int, long), long (*)(int, void*, long));
71void putdec(ulong);
72void puthid0(ulong);
73void putmsr(ulong);
74int qbgetc(Queue*);
75void qbputc(Queue*, int);
76void qbwrite(Queue*, Block*);
77Block* qget(Queue*);
78long qlen(Queue*);
79Queue* qopen(int, int, void (*)(void*), void*);
80#define qpass qbwrite
81void scc2stop(void);
82void sccnmsi(int, int, int);
83void sched(void);
84void screeninit(void);
85void screenputs(char*, int);
86void sdraminit(ulong);
87Partition* sethardpart(int, char*);
88Partition* setscsipart(int, char*);
89void setvec(int, void (*)(Ureg*, void*), void*);
90int splhi(void);
91int spllo(void);
92void splx(int);
93void trapinit(void);
94void uartputs(char*, int);
95void uartsetboot(void (*f)(uchar*, int));
96void uartspecial(int, int, Queue**, Queue**, void(*)(Queue*,int));
97void uartwait(void);
98long unsqueezef(Block*, ulong*);
99
100#define GSHORT(p) (((p)[1]<<8)|(p)[0])
101#define GLONG(p) ((GSHORT(p+2)<<16)|GSHORT(p))
102#define GLSHORT(p) (((p)[0]<<8)|(p)[1])
103#define GLLONG(p) ((GLSHORT(p)<<16)|GLSHORT(p+2))
104
105#define KADDR(a) ((void*)((ulong)(a)|KZERO))
106#define PADDR(a) ((ulong)(a)&~KSEGM)
107
108/* IBM bit field order */
109#define IBIT(b) ((ulong)1<<(31-(b)))
110#define SIBIT(n) ((ushort)1<<(15-(n)))
111
112#define IOREGS(x, T) ((T*)((char*)m->iomem+(x)))
113
114int uartinit(void);
115Partition* setuartpart(int, char*);
116long uartread(int, void*, long);
117long uartseek(int, long);
os/boot/mpc/gbitbltclip.c+52−0
@@ -0,0 +1,52 @@
1#include <u.h>
2#include <libc.h>
3#include <libg.h>
4#include <gnot.h>
5
6void
7gbitbltclip(void *vp)
8{
9 int dx, dy;
10 int i;
11 struct{
12 GBitmap *dm;
13 Point p;
14 GBitmap *sm;
15 Rectangle r;
16 Fcode f;
17 }*bp;
18
19 bp = vp;
20 dx = Dx(bp->r);
21 dy = Dy(bp->r);
22 if(bp->p.x < bp->dm->clipr.min.x){
23 i = bp->dm->clipr.min.x-bp->p.x;
24 bp->r.min.x += i;
25 bp->p.x += i;
26 dx -= i;
27 }
28 if(bp->p.y < bp->dm->clipr.min.y){
29 i = bp->dm->clipr.min.y-bp->p.y;
30 bp->r.min.y += i;
31 bp->p.y += i;
32 dy -= i;
33 }
34 if(bp->p.x+dx > bp->dm->clipr.max.x)
35 bp->r.max.x -= bp->p.x+dx-bp->dm->clipr.max.x;
36 if(bp->p.y+dy > bp->dm->clipr.max.y)
37 bp->r.max.y -= bp->p.y+dy-bp->dm->clipr.max.y;
38 if(bp->r.min.x < bp->sm->clipr.min.x){
39 i = bp->sm->clipr.min.x-bp->r.min.x;
40 bp->p.x += i;
41 bp->r.min.x += i;
42 }
43 if(bp->r.min.y < bp->sm->clipr.min.y){
44 i = bp->sm->clipr.min.y-bp->r.min.y;
45 bp->p.y += i;
46 bp->r.min.y += i;
47 }
48 if(bp->r.max.x > bp->sm->clipr.max.x)
49 bp->r.max.x = bp->sm->clipr.max.x;
50 if(bp->r.max.y > bp->sm->clipr.max.y)
51 bp->r.max.y = bp->sm->clipr.max.y;
52}
os/boot/mpc/gnot.h+71−0
@@ -0,0 +1,71 @@
1
2extern void *bbmalloc(int);
3extern void bbfree(void *, int);
4extern int bbonstack(void);
5extern void bbexec(void(*)(void), int, int);
6
7/*
8 * Graphics types
9 */
10
11typedef struct GBitmap GBitmap;
12typedef struct GFont GFont;
13typedef struct GSubfont GSubfont;
14typedef struct GCacheinfo GCacheinfo;
15
16struct GBitmap
17{
18 ulong *base; /* pointer to start of data */
19 long zero; /* base+zero=&word containing (0,0) */
20 ulong width; /* width in 32 bit words of total data area */
21 int ldepth; /* log base 2 of number of bits per pixel */
22 Rectangle r; /* rectangle in data area, local coords */
23 Rectangle clipr; /* clipping region */
24 GBitmap *cache; /* zero; distinguishes bitmap from layer */
25};
26
27
28/*
29 * GFont etc. are not used in the library, only in devbit.c.
30 * GSubfont is only barely used.
31 */
32struct GSubfont
33{
34 short n; /* number of chars in font */
35 char height; /* height of bitmap */
36 char ascent; /* top of bitmap to baseline */
37 Fontchar *info; /* n+1 character descriptors */
38 GBitmap *bits; /* where the characters are */
39};
40struct GCacheinfo
41{
42 ulong xright; /* right edge of bits */
43 Fontchar;
44};
45
46struct GFont
47{
48 uchar height; /* max height of bitmap, interline spacing */
49 char ascent; /* top of bitmap to baseline */
50 char width; /* widest so far; used in caching only */
51 char ldepth; /* of images */
52 short id; /* of font */
53 int ncache; /* number of entries in cache */
54 GCacheinfo *cache; /* cached characters */
55 GBitmap *b; /* cached images */
56};
57
58extern ulong *gaddr(GBitmap*, Point);
59extern uchar *gbaddr(GBitmap*, Point);
60extern void gbitblt(GBitmap*, Point, GBitmap*, Rectangle, Fcode);
61extern void gbitbltclip(void*);
62extern void gtexture(GBitmap*, Rectangle, GBitmap*, Fcode);
63extern Point gsubfstrsize(GSubfont*, char*);
64extern int gsubfstrwidth(GSubfont*, char*);
65extern Point gsubfstring(GBitmap*, Point, GSubfont*, char*, Fcode);
66extern Point gbitbltstring(GBitmap*, Point, GSubfont*, char*, Fcode);
67extern void gsegment(GBitmap*, Point, Point, int, Fcode);
68extern void gpoint(GBitmap*, Point, int, Fcode);
69extern void gflushcpucache(void);
70extern GBitmap* gballoc(Rectangle, int);
71extern void gbfree(GBitmap*);
os/boot/mpc/i2c.c+351−0
@@ -0,0 +1,351 @@
1#include "boot.h"
2
3/*
4 * basic read/write interface to mpc8xx I2C bus (master mode)
5 */
6
7typedef struct I2C I2C;
8
9struct I2C {
10 uchar i2mod;
11 uchar rsv12a[3];
12 uchar i2add;
13 uchar rsv12b[3];
14 uchar i2brg;
15 uchar rsv12c[3];
16 uchar i2com;
17 uchar rsv12d[3];
18 uchar i2cer;
19 uchar rsv12e[3];
20 uchar i2cmr;
21};
22
23enum {
24 /* i2c-specific BD flags */
25 RxeOV= 1<<1, /* overrun */
26 TxS= 1<<10, /* transmit start condition */
27 TxeNAK= 1<<2, /* last transmitted byte not acknowledged */
28 TxeUN= 1<<1, /* underflow */
29 TxeCL= 1<<0, /* collision */
30 TxERR= (TxeNAK|TxeUN|TxeCL),
31
32 /* i2cmod */
33 REVD= 1<<5, /* =1, LSB first */
34 GCD= 1<<4, /* =1, general call address disabled */
35 FLT= 1<<3, /* =0, not filtered; =1, filtered */
36 PDIV= 3<<1, /* predivisor field */
37 EN= 1<<0, /* enable */
38
39 /* i2com */
40 STR= 1<<7, /* start transmit */
41 I2CM= 1<<0, /* master */
42 I2CS= 0<<0, /* slave */
43
44 /* i2cer */
45 TXE = 1<<4,
46 BSY = 1<<2,
47 TXB = 1<<1,
48 RXB = 1<<0,
49
50 /* port B bits */
51 I2CSDA = IBIT(27),
52 I2CSCL = IBIT(26),
53
54 Rbit = 1<<0, /* bit in address byte denoting read */
55
56 /* maximum I2C I/O (can change) */
57 Bufsize = 64,
58 Tbuflen= Bufsize+4, /* extra address bytes and alignment */
59 Freq = 100000,
60 I2CTimeout = 250, /* msec */
61};
62
63/* data cache needn't be flushed if buffers allocated in uncached INTMEM */
64#define DCFLUSH(a,n)
65
66/*
67 * I2C software structures
68 */
69
70struct Ctlr {
71 Lock;
72 QLock io;
73 int init;
74 I2C* i2c;
75 IOCparam* sp;
76
77 BD* rd;
78 BD* td;
79 int phase;
80 char* addr;
81 char* txbuf;
82 char* rxbuf;
83};
84typedef struct Ctlr Ctlr;
85
86static Ctlr i2ctlr[1];
87extern int predawn;
88
89static void interrupt(Ureg*, void*);
90
91static void
92enable(void)
93{
94 I2C *i2c;
95
96 i2c = i2ctlr->i2c;
97 i2c->i2cer = ~0; /* clear events */
98 eieio();
99 i2c->i2mod |= EN;
100 eieio();
101 i2c->i2cmr = TXE|BSY|TXB|RXB; /* enable all interrupts */
102 eieio();
103}
104
105static void
106disable(void)
107{
108 I2C *i2c;
109
110 i2c = i2ctlr->i2c;
111 i2c->i2cmr = 0; /* mask all interrupts */
112 i2c->i2mod &= ~EN;
113}
114
115/*
116 * called by the reset routine of any driver using the I2C
117 */
118void
119i2csetup(void)
120{
121 IMM *io;
122 I2C *i2c;
123 IOCparam *sp;
124 Ctlr *ctlr;
125 long f, e, emin;
126 int p, d, dmax;
127
128 ctlr = i2ctlr;
129 if(ctlr->init)
130 return;
131 print("i2c setup...\n");
132 ctlr->init = 1;
133 i2c = KADDR(INTMEM+0x860);
134 ctlr->i2c = i2c;
135 sp = KADDR(INTMEM+0x3c80);
136 ctlr->sp = sp;
137 disable();
138
139 if(ctlr->txbuf == nil){
140 ctlr->txbuf = ialloc(Tbuflen, 2);
141 ctlr->addr = ctlr->txbuf+Bufsize;
142 }
143 if(ctlr->rxbuf == nil)
144 ctlr->rxbuf = ialloc(Bufsize, 2);
145 if(ctlr->rd == nil){
146 ctlr->rd = bdalloc(1);
147 ctlr->rd->addr = PADDR(ctlr->rxbuf);
148 ctlr->rd->length = 0;
149 ctlr->rd->status = BDWrap;
150 }
151 if(ctlr->td == nil){
152 ctlr->td = bdalloc(2);
153 ctlr->td->addr = PADDR(ctlr->txbuf);
154 ctlr->td->length = 0;
155 ctlr->td->status = BDWrap|BDLast;
156 }
157
158 /* select port pins */
159 io = ioplock();
160 io->pbdir |= I2CSDA | I2CSCL;
161 io->pbodr |= I2CSDA | I2CSCL;
162 io->pbpar |= I2CSDA | I2CSCL;
163 iopunlock();
164
165 /* explicitly initialise parameters, because InitRxTx can't be used (see i2c/spi relocation errata) */
166 sp = ctlr->sp;
167 sp->rbase = PADDR(ctlr->rd);
168 sp->tbase = PADDR(ctlr->td);
169 sp->rfcr = 0x18;
170 sp->tfcr = 0x18;
171 sp->mrblr = Bufsize;
172 sp->rstate = 0;
173 sp->rptr = 0;
174 sp->rbptr = sp->rbase;
175 sp->rcnt = 0;
176 sp->tstate = 0;
177 sp->tbptr = sp->tbase;
178 sp->tptr = 0;
179 sp->tcnt = 0;
180 eieio();
181
182 i2c->i2com = I2CM;
183 i2c->i2mod = 0; /* normal mode */
184 i2c->i2add = 0;
185
186 emin = Freq;
187 dmax = (m->cpuhz/Freq)/2-3;
188 for(d=0; d < dmax; d++){
189 for(p=3; p>=0; p--){
190 f = (m->cpuhz>>(p+2))/(2*(d+3));
191 e = Freq - f;
192 if(e < 0)
193 e = -e;
194 if(e < emin){
195 emin = e;
196 i2c->i2brg = d;
197 i2c->i2mod = (i2c->i2mod&~PDIV)|((3-p)<<1); /* set PDIV */
198 }
199 }
200 }
201 //print("i2brg=%d i2mod=#%2.2ux\n", i2c->i2brg, i2c->i2mod);
202 setvec(VectorCPIC+0x10, interrupt, i2ctlr);
203}
204
205enum {
206 Idling,
207 Done,
208 Busy,
209 Sending,
210 Recving,
211};
212
213static void
214interrupt(Ureg*, void *arg)
215{
216 int events;
217 Ctlr *ctlr;
218 I2C *i2c;
219
220 ctlr = arg;
221 i2c = ctlr->i2c;
222 events = i2c->i2cer;
223 eieio();
224 i2c->i2cer = events;
225 if(events & (BSY|TXE)){
226 //print("I2C#%x\n", events);
227 if(ctlr->phase != Idling){
228 ctlr->phase = Idling;
229 }
230 }else{
231 if(events & TXB){
232 //print("i2c: xmt %d %4.4ux %4.4ux\n", ctlr->phase, ctlr->td->status, ctlr->td[1].status);
233 if(ctlr->phase == Sending){
234 ctlr->phase = Done;
235 }
236 }
237 if(events & RXB){
238 //print("i2c: rcv %d %4.4ux %d\n", ctlr->phase, ctlr->rd->status, ctlr->rd->length);
239 if(ctlr->phase == Recving){
240 ctlr->phase = Done;
241 }
242 }
243 }
244}
245
246static int
247done(void *a)
248{
249 return ((Ctlr*)a)->phase < Busy;
250}
251
252static void
253i2cwait(Ctlr *ctlr)
254{
255 /* TO DO: timeout */
256 while(!done(ctlr)){
257 if(predawn)
258 interrupt(nil, ctlr);
259 }
260}
261
262long
263i2csend(int addr, void *buf, long n)
264{
265 Ctlr *ctlr;
266 int i, p, s;
267
268 ctlr = i2ctlr;
269 if(n > Bufsize)
270 return -1;
271 i = 1;
272 ctlr->txbuf[0] = addr & ~1;
273 if(addr & 1){
274 ctlr->txbuf[1] = addr>>8;
275 i++;
276 }
277 memmove(ctlr->txbuf+i, buf, n);
278 DCFLUSH(ctlr->txbuf, Tbuflen);
279 ctlr->phase = Sending;
280 ctlr->rd->status = BDEmpty|BDWrap|BDInt;
281 ctlr->td->addr = PADDR(ctlr->txbuf);
282 ctlr->td->length = n+i;
283 ctlr->td->status = BDReady|BDWrap|BDLast|BDInt;
284 enable();
285 ctlr->i2c->i2com = STR|I2CM;
286 eieio();
287 i2cwait(ctlr);
288 disable();
289 p = ctlr->phase;
290 s = ctlr->td->status;
291 if(s & BDReady || s & TxERR || p != Done)
292 return -1;
293 return n;
294}
295
296long
297i2crecv(int addr, void *buf, long n)
298{
299 Ctlr *ctlr;
300 int p, s, flag;
301 BD *td;
302 long nr;
303
304 ctlr = i2ctlr;
305 if(n > Bufsize)
306 return -1;
307 ctlr->txbuf[0] = addr|Rbit;
308 if(addr & 1){ /* special select sequence */
309 ctlr->addr[0] = addr &~ 1;
310 ctlr->addr[1] = addr>>8;
311 }
312 DCFLUSH(ctlr->txbuf, Tbuflen);
313 DCFLUSH(ctlr->rxbuf, Bufsize);
314 ctlr->phase = Recving;
315 ctlr->rd->addr = PADDR(ctlr->rxbuf);
316 ctlr->rd->status = BDEmpty|BDWrap|BDInt;
317 flag = 0;
318 td = ctlr->td;
319 td[1].status = 0;
320 if(addr & 1){
321 /* special select sequence */
322 td->addr = PADDR(ctlr->addr);
323 td->length = 2;
324 /* td->status made BDReady below */
325 td++;
326 flag = TxS;
327 }
328 td->addr = PADDR(ctlr->txbuf);
329 td->length = n+1;
330 td->status = BDReady|BDWrap|BDLast | flag; /* not BDInt: leave that to receive */
331 if(flag)
332 ctlr->td->status = BDReady;
333 enable();
334 ctlr->i2c->i2com = STR|I2CM;
335 eieio();
336 i2cwait(ctlr);
337 disable();
338 p = ctlr->phase;
339 s = ctlr->td->status;
340 if(flag)
341 s |= ctlr->td[1].status;
342 nr = ctlr->rd->length;
343 if(nr > n)
344 nr = n; /* shouldn't happen */
345 if(s & TxERR || s & BDReady || ctlr->rd->status & BDEmpty)
346 return -1;
347 if(p != Done)
348 return -1;
349 memmove(buf, ctlr->rxbuf, nr);
350 return nr;
351}
os/boot/mpc/initfads.c+187−0
@@ -0,0 +1,187 @@
1/*
2 * Called from l.s in EPROM to set up a minimal working environment.
3 * Since there is no DRAM yet, and therefore no stack, no function
4 * calls may be made from sysinit0, and values can't be stored,
5 * except to INTMEM. Global values are accessed by offset from SB,
6 * which has been set by l.s to point into EPROM.
7 *
8 * This is FADS-specific in CS assignment and access of the FADS BCSR
9 * to discover memory size and speed.
10 */
11
12#include "u.h"
13#include "lib.h"
14#include "mem.h"
15#include "dat.h"
16#include "fns.h"
17#include "io.h"
18
19#include "archfads.h"
20
21#define MB (1024*1024)
22
23enum {
24 UPMSIZE = 64, /* memory controller instruction RAM */
25 SPEED = 50, /* maximum memory clock in MHz */
26 SDRAMSIZE = 4*MB,
27
28 /* mcr */
29 WriteRAM = 0<<30,
30 ReadRAM = 1<<30,
31 ExecRAM = 2<<30,
32
33 SelUPMA = 0<<23,
34 SelUPMB = 1<<23,
35
36 Once = 1<<8,
37};
38
39/*
40 * mpc8bug uses the following for 60ns EDO DRAMs 32-50MHz
41 */
42static ulong upma50[UPMSIZE] = {
43 0x8FFFEC24, 0xFFFEC04, 0xCFFEC04, 0xFFEC04,
44 0xFFEC00, 0x37FFEC47, 0xFFFFFFFF, 0xFFFFFFFF,
45 0x8FFFEC24, 0xFFFEC04, 0x8FFEC04, 0xFFEC0C,
46 0x3FFEC00, 0xFFEC44, 0xFFCC08, 0xCFFCC44,
47 0xFFEC0C, 0x3FFEC00, 0xFFEC44, 0xFFCC00,
48 0x3FFFC847, 0x3FFFEC47, 0xFFFFFFFF, 0xFFFFFFFF,
49 0x8FAFCC24, 0xFAFCC04, 0xCAFCC00, 0x11BFCC47,
50 0xC0FFCC84, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
51 0x8FAFCC24, 0xFAFCC04, 0xCAFCC00, 0x3AFCC4C,
52 0xCAFCC00, 0x3AFCC4C, 0xCAFCC00, 0x3AFCC4C,
53 0xCAFCC00, 0x33BFCC4F, 0xFFFFFFFF, 0xFFFFFFFF,
54 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
55 0xC0FFCC84, 0xFFCC04, 0x7FFCC04, 0x3FFFCC06,
56 0xFFFFCC85, 0xFFFFCC05, 0xFFFFCC05, 0xFFFFFFFF,
57 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
58 0x33FFCC07, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
59};
60
61/*
62 * the FADS manual table 3-7 suggests the following for 60ns EDO DRAMs at 20MHz
63 */
64static ulong upma20[UPMSIZE] = {
65 0x8FFFCC04, 0x08FFCC00, 0x33FFCC47, ~0, ~0, ~0, ~0, ~0,
66 [0x08] 0x8FFFCC04, 0x08FFCC08, 0x08FFCC08, 0x08FFCC08, 0x08FFCC00, 0x3FFFCC47, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
67 [0x18] 0x8FEFCC00, 0x39BFCC47, ~0, ~0, ~0, ~0, ~0, ~0,
68 [0x20] 0x8FEFCC00, 0x09AFCC48, 0x09AFCC48, 0x08AFCC48, 0x39BFCC47, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
69 [0x30] 0x80FFCC84, 0x17FFCC04, 0xFFFFCC86, 0xFFFFCC05, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
70 [0x3C] 0x33FFCC07, ~0, ~0, ~0,
71};
72
73void
74sysinit0(int inrom)
75{
76 ulong *upm, *bcsr;
77 IMM *io;
78 int i, mb;
79
80 io = (IMM*)INTMEM; /* running before maps, no KADDR */
81
82 /* system interface unit initialisation, FADS manual table 3-2, except as noted */
83 io->siumcr = 0x01012440;
84 io->sypcr = 0xFFFFFF88;
85 io->tbscrk = KEEP_ALIVE_KEY;
86 io->tbscr = 0xC3; /* time base enabled */
87 io->rtcsck = KEEP_ALIVE_KEY;
88 io->rtcsc = 0xC1; /* don't FRZ, real-time clock enabled */
89 io->rtcsck = ~KEEP_ALIVE_KEY;
90 io->piscrk = KEEP_ALIVE_KEY;
91 io->piscr = 0x82;
92
93 io->memc[BCSRCS].option = 0xFFFF8110; /* 32k block, all types access, CS early negate, 1 ws */
94 io->memc[BCSRCS].base = BCSRMEM | 1; /* base, 32-bit port, no parity, GPCM */
95
96 io->memc[BOOTCS].base = FLASHMEM | 1;
97 io->memc[BOOTCS].option = 0xFF800D54;
98
99 if(!inrom)
100 return; /* can't initialise DRAM controller from DRAM */
101
102 bcsr = (ulong*)BCSRMEM;
103// bcsr[1] &= ~DisableDRAM;
104 /* could check DRAM speed here; assume 60ns */
105 switch((bcsr[2]>>23)&3){
106 default: return; /* can't happen; for the compiler */
107 case 0: mb = 4; break;
108 case 1: mb = 32; break;
109 case 2: mb = 16; break;
110 case 3: mb = 8; break;
111 }
112
113 upm = upma50;
114 for(i=0; i<UPMSIZE; i++){
115 io->mdr = upm[i];
116 io->mcr = WriteRAM | SelUPMA | i;
117 }
118 io->mptpr = 0x0400;
119 if(SPEED >= 32)
120 io->mamr = (0x9C<<24) | 0xA21114; /* 50MHz BRGCLK; FADS manual says 0xC0, mpc8bug sets 0x9C */
121 else if(SPEED >= 20)
122 io->mamr = (0x60<<24) | 0xA21114; /* 25MHz BRGCLK */
123 else
124 io->mamr = (0x40<<24) | 0xA21114; /* 16.67MHz BRGCLK */
125 io->memc[DRAM1].option = ~((mb<<20)-1)|0x0800; /* address mask, SAM=1 */
126 io->memc[DRAM1].base = 0 | 0x81; /* base at 0, 32-bit port size, no parity, UPMA */
127}
128
129/*
130 * the FADS manual table 3-9's suggestion for MB811171622A-100 32+MHz-50MHz
131 */
132static ulong upmb50[UPMSIZE] = {
133 [0x00] 0x1F07FC04, 0xEEAEFC04, 0x11ADFC04, 0xEFBBBC00, 0x1FF77C47,
134 [0x05] 0x1FF77C34, 0xEFEABC34, 0x1FB57C35,
135 [0x08] 0x1F07FC04, 0xEEAEFC04, 0x10ADFC04, 0xF0AFFC00, 0xF0AFFC00, 0xF1AFFC00, 0xEFBBBC00, 0x1FF77C47, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
136 [0x18] 0x1F27FC04, 0xEEAEBC00, 0x01B93C04, 0x1FF77C47, ~0, ~0, ~0, ~0,
137 [0x20] 0x1F07FC04, 0xEEAEBC00, 0x10AD7C00, 0xF0AFFC00, 0xF0AFFC00, 0xE1BBBC04, 0x1FF77C47, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
138 [0x30] 0x1FF5FC84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC84, 0xFFFFFC07, ~0, ~0, ~0, ~0, ~0, ~0,
139 [0x3C] 0x7FFFFC07, ~0, ~0, ~0,
140};
141
142/*
143 * the FADS manual table 3-8's suggestion for MB811171622A-100 up to 32MHz
144 */
145static ulong upmb32[UPMSIZE] = {
146 [0x00] 0x126CC04, 0xFB98C00, 0x1FF74C45, ~0, ~0,
147 [0x05] 0x1FE77C34, 0xEFAABC34, 0x1FA57C35,
148 [0x08] 0x0026FC04, 0x10ADFC00, 0xF0AFFC00, 0xF1AFFC00, 0xEFBBBC00, 0x1FF77C45, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
149 [0x18] 0x0E26BC04, 0x01B93C00, 0x1FF77C45, ~0, ~0, ~0, ~0, ~0,
150 [0x20] 0x0E26BC00, 0x10AD7C00, 0xF0AFFC00, 0xF0AFFC00, 0xE1BBBC04, 0x1FF77C45, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
151 [0x30] 0x1FF5FC84, 0xFFFFFC04, 0xFFFFFC84, 0xFFFFFC05, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
152 [0x3C] 0x7FFFFC07, ~0, ~0, ~0,
153};
154
155/*
156 * optionally called by archfads.c:/^archinit to initialise access to SDRAM
157 */
158void
159sdraminit(ulong base)
160{
161 ulong *upm;
162 IMM *io;
163 int i;
164
165 io = (IMM*)INTMEM; /* running before maps, no KADDR */
166 if(SPEED > 32)
167 upm = upmb50;
168 else
169 upm = upmb32;
170 for(i=0; i<UPMSIZE; i++){
171 io->mdr = upm[i];
172 io->mcr = WriteRAM | SelUPMB | i;
173 }
174 io->memc[SDRAM].option = ~(SDRAMSIZE-1)|0x0A00; /* address mask, SAM=1, G5LS=1 */
175 io->memc[SDRAM].base = base | 0xC1;
176 if(SPEED > 32){
177 io->mbmr = 0xD0802114; /* 50MHz BRGCLK */
178 io->mar = 0x88;
179 }else{
180 io->mbmr = 0x80802114; /* 32MHz BRGCLK */
181 io->mar = 0x48;
182 }
183 io->mcr = ExecRAM | SelUPMB | (SDRAM<<13) | Once | 5; /* run MRS command in locations 5-8 of UPMB */
184 io->mbmr = (io->mbmr & ~0xF) | 8;
185 io->mcr = ExecRAM | SelUPMB | (SDRAM<<13) | Once | 0x30; /* run refresh sequence */
186 io->mbmr = (io->mbmr & ~0xF) | 4; /* 4-beat refresh bursts */
187}
os/boot/mpc/initpaq.c+101−0
@@ -0,0 +1,101 @@
1/*
2 * Called from l.s in EPROM to set up a minimal working environment.
3 * Since there is no DRAM yet, and therefore no stack, no function
4 * calls may be made from sysinit0, and values can't be stored,
5 * except to INTMEM. Global values are accessed by offset from SB,
6 * which has been set by l.s to point into EPROM.
7 *
8 * This is PowerPAQ-specific:
9 * - assumes 8mbytes
10 * - powerpaq CS assignment
11 */
12
13#include "u.h"
14#include "lib.h"
15#include "mem.h"
16#include "dat.h"
17#include "fns.h"
18#include "io.h"
19
20#include "archpaq.h"
21
22#define MB (1024*1024)
23
24enum {
25 DRAMSIZE = 8*MB,
26 FLASHSIZE = 8*MB,
27
28 UPMSIZE = 64, /* memory controller instruction RAM */
29 SPEED = 50, /* maximum memory clock in MHz */
30
31 /* mcr */
32 WriteRAM = 0<<30,
33 ReadRAM = 1<<30,
34 ExecRAM = 2<<30,
35
36 SelUPMA = 0<<23,
37 SelUPMB = 1<<23,
38
39 Once = 1<<8,
40};
41
42/*
43 * mpc8bug uses the following for 60ns EDO DRAMs 32-50MHz
44 */
45static ulong upmb50[UPMSIZE] = {
46 0x8FFFEC24, 0xFFFEC04, 0xCFFEC04, 0xFFEC04,
47 0xFFEC00, 0x37FFEC47, 0xFFFFFFFF, 0xFFFFFFFF,
48 0x8FFFEC24, 0xFFFEC04, 0x8FFEC04, 0xFFEC0C,
49 0x3FFEC00, 0xFFEC44, 0xFFCC08, 0xCFFCC44,
50 0xFFEC0C, 0x3FFEC00, 0xFFEC44, 0xFFCC00,
51 0x3FFFC847, 0x3FFFEC47, 0xFFFFFFFF, 0xFFFFFFFF,
52 0x8FAFCC24, 0xFAFCC04, 0xCAFCC00, 0x11BFCC47,
53 0xC0FFCC84, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
54 0x8FAFCC24, 0xFAFCC04, 0xCAFCC00, 0x3AFCC4C,
55 0xCAFCC00, 0x3AFCC4C, 0xCAFCC00, 0x3AFCC4C,
56 0xCAFCC00, 0x33BFCC4F, 0xFFFFFFFF, 0xFFFFFFFF,
57 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
58 0xC0FFCC84, 0xFFCC04, 0x7FFCC04, 0x3FFFCC06,
59 0xFFFFCC85, 0xFFFFCC05, 0xFFFFCC05, 0xFFFFFFFF,
60 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
61 0x33FFCC07, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
62};
63
64void
65sysinit0(int inrom)
66{
67 ulong *upm;
68 IMM *io;
69 int i;
70
71 io = (IMM*)INTMEM; /* running before maps, no KADDR */
72
73 /* system interface unit initialisation, FADS manual table 3-2, except as noted */
74 io->siumcr = 0x01012440;
75 io->sypcr = 0xFFFFFF88;
76 io->tbscrk = KEEP_ALIVE_KEY;
77 io->tbscr = 0xC3; /* time base enabled */
78 io->rtcsck = KEEP_ALIVE_KEY;
79 io->rtcsc = 0xC1; /* don't FRZ, real-time clock enabled */
80 io->rtcsck = ~KEEP_ALIVE_KEY;
81 io->piscrk = KEEP_ALIVE_KEY;
82 io->piscr = 0x82;
83
84 io->memc[BOOTCS].base = FLASHMEM | 1;
85 io->memc[BOOTCS].option = ~(FLASHSIZE-1)|(1<<8)|(2<<4); /* mask, BIH, 2 wait states */
86
87 if(!inrom)
88 return; /* can't initialise DRAM controller from DRAM */
89
90 /* could check DRAM speed here; assume 60ns */
91 /* could probe DRAM for size here; assume DRAMSIZE */
92 io->mptpr = 0x400; /* powerpaq flash has 0x1000 */
93 io->mbmr = (0xC0<<24) | 0xA21114; /* 50MHz BRGCLK */
94 upm = upmb50;
95 for(i=0; i<UPMSIZE; i++){
96 io->mdr = upm[i];
97 io->mcr = WriteRAM | SelUPMB | i;
98 }
99 io->memc[DRAM1].option = ~(DRAMSIZE-1)|0x0800; /* address mask, SAM=1 */
100 io->memc[DRAM1].base = 0 | 0xC1; /* base at 0, 32-bit port size, no parity, UPMB */
101}
os/boot/mpc/initrpcg.c+91−0
@@ -0,0 +1,91 @@
1
2/*
3 * Called from l.s in EPROM to set up a minimal working environment.
4 * Since there is no DRAM yet, and therefore no stack, no function
5 * calls may be made from sysinit, and values can't be stored,
6 * except to INTMEM. Global values are accessed by offset from SB,
7 * which has been set by l.s to point into EPROM.
8 */
9
10#include "u.h"
11#include "lib.h"
12#include "mem.h"
13#include "dat.h"
14#include "fns.h"
15#include "io.h"
16
17#include "archrpcg.h"
18
19#define MB (1024*1024)
20
21enum {
22 UPMSIZE = 64, /* memory controller instruction RAM */
23 DRAMSIZE = 16*MB,
24 FLASHSIZE = 4*MB,
25
26 WriteRAM = 0<<30,
27 ReadRAM = 1<<30,
28 ExecRAM = 2<<30,
29
30 SelUPMA = 0<<23,
31 SelUPMB = 1<<23,
32};
33/* RPCG values for RPXLite AW */
34static ulong upma50[UPMSIZE] = {
35 0xCFFFCC24, 0x0FFFCC04, 0x0CAFCC04, 0x03AFCC08,
36 0x3FBFCC27, 0xFFFFCC25, 0xFFFFCC25, 0xFFFFCC25,
37 0xCFFFCC24, 0x0FFFCC04, 0x0CAFCC84, 0x03AFCC88,
38 0x3FBFCC27, 0xFFFFCC25, 0xFFFFCC25, 0xFFFFCC25,
39 0xFFFFCC25, 0xFFFFCC25, 0xFFFFCC25, 0xFFFFCC25,
40 0xFFFFCC25, 0xFFFFCC25, 0xFFFFCC25, 0xFFFFCC25,
41 0xCFFFCC24, 0x0FFFCC04, 0x0CFFCC04, 0x03FFCC00,
42 0x3FFFCC27, 0xFFFFCC25, 0xFFFFCC25, 0xFFFFCC25,
43 0xCFFFCC24, 0x0FFFCC04, 0x0CFFCC84, 0x03FFCC84,
44 0x0CFFCC00, 0x33FFCC27, 0xFFFFCC25, 0xFFFFCC25,
45 0xFFFFCC25, 0xFFFFCC25, 0xFFFFCC25, 0xFFFFCC25,
46 0xFFFFCC25, 0xFFFFCC25, 0xFFFFCC25, 0xFFFFCC25,
47 0xC0FFCC24, 0x03FFCC24, 0x0FFFCC24, 0x0FFFCC24,
48 0x3FFFCC27, 0xFFFFCC25, 0xFFFFCC25, 0xFFFFCC25,
49 0xFFFFCC25, 0xFFFFCC25, 0xFFFFCC25, 0xFFFFCC25,
50 0xFFFFCC25, 0xFFFFCC25, 0xFFFFCC25, 0xFFFFCC25,
51};
52
53void
54sysinit0(int inrom)
55{
56 ulong *upm;
57 IMM *io;
58 int i;
59
60 io = (IMM*)INTMEM; /* running before maps, no KADDR */
61 io->siumcr = 0x01012440;
62 io->sypcr = 0xFFFFFF88;
63 io->tbscrk = KEEP_ALIVE_KEY;
64 io->tbscr = 0xC3;
65 io->rtcsck = KEEP_ALIVE_KEY;
66 io->rtcsc = 0xC1;
67 io->rtcsck = ~KEEP_ALIVE_KEY;
68 io->piscrk = KEEP_ALIVE_KEY;
69 io->piscr = 0x82;
70return;
71 io->memc[BCSRCS].option = 0xFFFF8910; /* 32k block, all types access, CSNT, CS early negate, burst inhibit, 1 ws */
72 io->memc[BCSRCS].base = BCSRMEM | 1; /* base, 32-bit port, no parity, GPCM */
73
74 io->memc[BOOTCS].base = FLASHMEM | 0x801; /* base, 16 bit port */
75 io->memc[BOOTCS].option = ~(FLASHSIZE-1)|(1<<8)|(4<<4); /* mask, BIH, 4 wait states */
76
77 if(1||!inrom)
78 return; /* can't initialise DRAM controller from DRAM */
79
80 /* TO DO: could check DRAM size and speed now */
81
82 upm = upma50;
83 for(i=0; i<nelem(upma50); i++){
84 io->mdr = upm[i];
85 io->mcr = WriteRAM | SelUPMA | i;
86 }
87 io->mptpr = 0x0800; /* divide by 8 */
88 io->mamr = (0x58<<24) | 0xA01430; /* 40MHz BRGCLK */
89 io->memc[DRAM1].option = ~(DRAMSIZE-1)|0x0E00; /* address mask, SAM=1, G5LA/S=3 */
90 io->memc[DRAM1].base = 0 | 0x81; /* base at 0, 32-bit port size, no parity, UPMA */
91}
os/boot/mpc/io.h+463−0
@@ -0,0 +1,463 @@
1enum
2{
3 /* software interrupt vectors (SIU and CPM) */
4 VectorPIC= 0, /* level 0 to level 7, assigned by software */
5 CPIClevel= 4,
6 VectorIRQ= VectorPIC+8, /* IRQ0 to IRQ7 */
7 VectorCPIC= VectorIRQ+8, /* 32 CPM interrupts: 0 (error) to 0x1F (PC15) */
8};
9
10enum
11{
12 BUSUNKNOWN = 0,
13};
14
15/*
16 * Buffer Descriptors and IO Rings
17 */
18
19typedef struct BD BD;
20struct BD {
21 ushort status;
22 ushort length;
23 ulong addr;
24};
25
26BD* bdalloc(int);
27void bdfree(BD*, int);
28
29enum {
30 /* Rx BDs, bits common to all protocols */
31 BDEmpty= 1<<15,
32 BDWrap= 1<<13,
33 BDInt= 1<<12,
34 BDLast= 1<<11,
35 BDFirst= 1<<10,
36
37 /* Tx BDs */
38 BDReady= 1<<15,
39 /* BDWrap, BDInt, BDLast */
40};
41
42typedef struct Ring Ring;
43struct Ring {
44 BD* rdr; /* receive descriptor ring */
45 void* rrb; /* receive ring buffers */
46 int rdrx; /* index into rdr */
47 int nrdre; /* length of rdr */
48
49 BD* tdr; /* transmit descriptor ring */
50 Block** txb; /* corresponding transmit ring buffers */
51 int tdrh; /* host index into tdr */
52 int tdri; /* interface index into tdr */
53 int ntdre; /* length of tdr */
54 int ntq; /* pending transmit requests */
55};
56
57#define NEXT(x, l) (((x)+1)%(l))
58#define PREV(x, l) (((x) == 0) ? (l)-1: (x)-1)
59#define HOWMANY(x, y) (((x)+((y)-1))/(y))
60#define ROUNDUP(x, y) (HOWMANY((x), (y))*(y))
61
62int ioringinit(Ring*, int, int, int);
63
64/*
65 * CPM
66 */
67enum {
68 /* commands */
69 InitRxTx = 0,
70 InitRx = 1,
71 InitTx = 2,
72 EnterHunt= 3,
73 StopTx= 4,
74 GracefulStopTx = 5,
75 InitIDMA = 5,
76 RestartTx = 6,
77 CloseRxBD = 7,
78 SetGroupAddr = 8,
79 SetTimer = 8,
80 GCITimeout = 9,
81 GCIAbort = 10,
82 StopIDMA = 11,
83 StartDSP = 12,
84 ArmIDMA = 13,
85 InitDSP = 13,
86 USBCmd = 15,
87
88 /* channel IDs */
89 SCC1ID= 0,
90 USBID= 0,
91 I2CID= 1,
92 IDMA1ID= 1,
93 SCC2ID= 4,
94 SPIID= 5,
95 IDMA2ID= 5,
96 TIMERID= 5,
97 SCC3ID= 8,
98 SMC1ID= 9,
99 DSP1ID=9,
100 SCC4ID= 12,
101 SMC2ID= 13,
102 DSP2ID= 13,
103
104 BaudEnable = 1<<16,
105
106 /* sicr */
107 CLK1 = 4, /* SCC1,2 */
108 CLK2 = 5,
109 CLK3 = 6,
110 CLK4 = 7,
111 CLK5 = CLK1, /* SCC3,4 */
112 CLK6 = CLK2,
113 CLK7 = CLK3,
114 CLK8 = CLK4,
115};
116
117void cpmop(int, int, int);
118#define ioplock() (m->iomem)
119#define iopunlock()
120
121/*
122 * the structures below follow hardware/firmware layouts in the 8xx manuals:
123 * mind the data types, offsets and alignment
124 */
125
126/*
127 * basic IO controller parameters (SMC and SCC)
128 */
129typedef struct IOCparam IOCparam;
130struct IOCparam {
131 ushort rbase;
132 ushort tbase;
133 uchar rfcr;
134 uchar tfcr;
135 ushort mrblr;
136 ulong rstate;
137 ulong rptr;
138 ushort rbptr;
139 ushort rcnt;
140 ulong rtmp;
141 ulong tstate;
142 ulong tptr;
143 ushort tbptr;
144 ushort tcnt;
145 ulong ttmp;
146};
147
148typedef struct SCCparam SCCparam;
149struct SCCparam {
150 IOCparam;
151 ulong rcrc;
152 ulong tcrc;
153};
154
155typedef struct SCC SCC;
156struct SCC {
157 ulong gsmrl;
158 ulong gsmrh;
159 ushort psmr;
160 uchar rsvscc0[2];
161 ushort todr;
162 ushort dsr;
163 ushort scce;
164 uchar rsvscc1[2];
165 ushort sccm;
166 uchar rsvscc3;
167 uchar sccs;
168 ushort irmode;
169 ushort irsip;
170};
171
172typedef struct SMC SMC;
173struct SMC {
174 uchar pad1[2];
175 ushort smcmr;
176 uchar pad2[2];
177 uchar smce;
178 uchar pad3[3];
179 uchar smcm;
180 uchar pad4[5];
181};
182
183typedef struct SPI SPI;
184struct SPI {
185 ushort spmode;
186 uchar res1[4];
187 uchar spie;
188 uchar res2[3];
189 uchar spim;
190 uchar res3[2];
191 uchar spcom;
192 uchar res4[10];
193};
194
195typedef struct USB USB;
196struct USB { /* 823 only */
197 uchar usmod;
198 uchar usadr;
199 uchar uscom;
200 uchar rsvu1;
201 ushort usep[4];
202 uchar rsvu2[4];
203 ushort usber;
204 uchar rsvu3[2];
205 ushort usbmr;
206 uchar rsvu4;
207 uchar usbs;
208 uchar rsvu5[8];
209};
210
211typedef struct IMM IMM;
212struct IMM {
213 struct { /* general SIU */
214 ulong siumcr;
215 ulong sypcr;
216 uchar rsv0[0xE-0x8];
217 ushort swsr;
218 ulong sipend;
219 ulong simask;
220 ulong siel;
221 uchar sivec;
222 uchar padv[3];
223 ulong tesr;
224 uchar rsv1[0x30-0x24];
225 ulong sdcr;
226 uchar rsv2[0x80-0x34];
227 };
228 struct { /* PCMCIA */
229 struct {
230 ulong base;
231 ulong option;
232 } pcmr[8];
233 uchar rsv3[0xe0-0xc0];
234 ulong pgcra;
235 ulong pgcrb;
236 ulong pscr;
237 uchar rsv4[0xf0-0xec];
238 ulong pipr;
239 uchar rsv5[4];
240 ulong per;
241 uchar rsv6[4];
242 };
243 struct { /* MEMC */
244 struct {
245 ulong base;
246 ulong option;
247 } memc[8];
248 uchar rsv7a[0x24];
249 ulong mar;
250 ulong mcr;
251 uchar rsv7b[4];
252 ulong mamr;
253 ulong mbmr;
254 ushort mstat;
255 ushort mptpr;
256 ulong mdr;
257 uchar rsv7c[0x80];
258 };
259 struct { /* system integration timers */
260 ushort tbscr;
261 uchar rsv8a[2];
262 ulong tbrefu;
263 ulong tbrefl;
264 uchar rsv8b[0x14];
265 ushort rtcsc;
266 uchar rsv8c[2];
267 ulong rtc;
268 ulong rtsec;
269 ulong rtcal;
270 uchar rsv8d[0x10];
271 ushort piscr;
272 ushort rsv8e;
273 ulong pitc;
274 ulong pitr;
275 uchar rsv8f[0x34];
276 };
277 struct { /* 280: clocks and resets */
278 ulong sccr;
279 ulong plprcr;
280 ulong rsr;
281 uchar rsv9[0x300-0x28c];
282 };
283 struct { /* 300: system integration timers keys */
284 ulong tbscrk;
285 ulong tbrefuk;
286 ulong tbreflk;
287 ulong tbk;
288 uchar rsv10a[0x10];
289 ulong rtcsck;
290 ulong rtck;
291 ulong rtseck;
292 ulong rtcalk;
293 uchar rsv10b[0x10];
294 ulong piscrk;
295 ulong pitck;
296 uchar rsv10c[0x38];
297 };
298 struct { /* 380: clocks and resets keys */
299 ulong sccrk;
300 ulong plprcrk;
301 ulong rsrk;
302 uchar rsv11[0x800-0x38C];
303 };
304 struct { /* 800: video controller */
305 ushort vccr;
306 ushort pad11a;
307 uchar vsr;
308 uchar pad11b;
309 uchar vcmr;
310 uchar pad11c;
311 ulong vbcb;
312 ulong pad11d;
313 ulong vfcr0;
314 ulong vfaa0;
315 ulong vfba0;
316 ulong vfcr1;
317 ulong vfaa1;
318 ulong vfba1;
319 uchar rsv11a[0x840-0x828];
320 };
321 struct { /* 840: LCD */
322 ulong lccr;
323 ulong lchcr;
324 ulong lcvcr;
325 ulong rsv11b;
326 ulong lcfaa;
327 ulong lcfba;
328 uchar lcsr;
329 uchar rsv11c[0x860-0x859];
330 };
331 struct { /* 860: I2C */
332 uchar i2mod;
333 uchar rsv12a[3];
334 uchar i2add;
335 uchar rsv12b[3];
336 uchar i2brg;
337 uchar rsv12c[3];
338 uchar i2com;
339 uchar rsv12d[3];
340 uchar i2cer;
341 uchar rsv12e[3];
342 uchar i2cmr;
343 uchar rsv12[0x900-0x875];
344 };
345 struct { /* 900: DMA */
346 uchar rsv13[4];
347 ulong sdar;
348 uchar sdsr;
349 uchar pad1[3];
350 uchar sdmr;
351 uchar pad2[3];
352 uchar idsr1;
353 uchar pad3[3];
354 uchar idmr1;
355 uchar pad4[3];
356 uchar idsr2;
357 uchar pad5[3];
358 uchar idmr2;
359 uchar pad6[0x930-0x91D];
360 };
361 struct { /* CPM interrupt control */
362 ushort civr;
363 uchar pad7[0x940-0x932];
364 ulong cicr;
365 ulong cipr;
366 ulong cimr;
367 ulong cisr;
368 };
369 struct { /* input/output port */
370 ushort padir;
371 ushort papar;
372 ushort paodr;
373 ushort padat;
374 uchar pad8[8];
375 ushort pcdir;
376 ushort pcpar;
377 ushort pcso;
378 ushort pcdat;
379 ushort pcint;
380 uchar pad9[6];
381 ushort pddir;
382 ushort pdpar;
383 ushort rsv14a;
384 ushort pddat;
385 uchar rsv14[0x980-0x978];
386 };
387 struct { /* CPM timers */
388 ushort tgcr;
389 uchar rsv15a[0x990-0x982];
390 ushort tmr1;
391 ushort tmr2;
392 ushort trr1;
393 ushort trr2;
394 ushort tcr1;
395 ushort tcr2;
396 ushort tcn1;
397 ushort tcn2;
398 ushort tmr3;
399 ushort tmr4;
400 ushort trr3;
401 ushort trr4;
402 ushort tcr3;
403 ushort tcr4;
404 ushort tcn3;
405 ushort tcn4;
406 ushort ter1;
407 ushort ter2;
408 ushort ter3;
409 ushort ter4;
410 uchar rsv15[0x9C0-0x9B8];
411 };
412 struct { /* CPM */
413 ushort cpcr;
414 uchar res0[2];
415 ushort rccr;
416 uchar res1;
417 uchar rmds;
418 uchar res2a[4];
419 ushort rctr1;
420 ushort rctr2;
421 ushort rctr3;
422 ushort rctr4;
423 uchar res2[2];
424 ushort rter;
425 uchar res3[2];
426 ushort rtmr;
427 uchar rsv16[0x9F0-0x9DC];
428 };
429 union { /* BRG */
430 struct {
431 ulong brgc1;
432 ulong brgc2;
433 ulong brgc3;
434 ulong brgc4;
435 };
436 ulong brgc[4];
437 };
438 uchar skip0[0xAB2-0xA00]; /* USB, SCC, SMC, SPI: address using cpmdev(CP...)->regs */
439 struct { /* PIP */
440 ushort pipc; /* not 823 */
441 ushort ptpr; /* not 823 */
442 ulong pbdir;
443 ulong pbpar;
444 uchar pad10[2];
445 ushort pbodr;
446 ulong pbdat;
447 uchar pad11[0xAE0-0xAC8];
448 };
449 struct { /* SI */
450 ulong simode;
451 uchar sigmr;
452 uchar pad12;
453 uchar sistr;
454 uchar sicmr;
455 uchar pad13[4];
456 ulong sicr;
457 ulong sirp;
458 uchar pad14[0xB00-0xAF4];
459 };
460 ulong vcram[64];
461 ushort siram[256];
462 ushort lcdmap[256];
463};
os/boot/mpc/ip.h+98−0
@@ -0,0 +1,98 @@
1typedef struct Udphdr Udphdr;
2struct Udphdr
3{
4 uchar d[6]; /* Ethernet destination */
5 uchar s[6]; /* Ethernet source */
6 uchar type[2]; /* Ethernet packet type */
7
8 uchar vihl; /* Version and header length */
9 uchar tos; /* Type of service */
10 uchar length[2]; /* packet length */
11 uchar id[2]; /* Identification */
12 uchar frag[2]; /* Fragment information */
13
14 /* Udp pseudo ip really starts here */
15 uchar ttl;
16 uchar udpproto; /* Protocol */
17 uchar udpplen[2]; /* Header plus data length */
18 uchar udpsrc[4]; /* Ip source */
19 uchar udpdst[4]; /* Ip destination */
20 uchar udpsport[2]; /* Source port */
21 uchar udpdport[2]; /* Destination port */
22 uchar udplen[2]; /* data length */
23 uchar udpcksum[2]; /* Checksum */
24};
25
26typedef struct Etherhdr Etherhdr;
27struct Etherhdr
28{
29 uchar d[6];
30 uchar s[6];
31 uchar type[2];
32
33 /* Now we have the ip fields */
34 uchar vihl; /* Version and header length */
35 uchar tos; /* Type of service */
36 uchar length[2]; /* packet length */
37 uchar id[2]; /* Identification */
38 uchar frag[2]; /* Fragment information */
39 uchar ttl; /* Time to live */
40 uchar proto; /* Protocol */
41 uchar cksum[2]; /* Header checksum */
42 uchar src[4]; /* Ip source */
43 uchar dst[4]; /* Ip destination */
44};
45
46enum
47{
48 IP_VER = 0x40,
49 IP_HLEN = 0x05,
50 UDP_EHSIZE = 22,
51 UDP_PHDRSIZE = 12,
52 UDP_HDRSIZE = 20,
53 ETHER_HDR = 14,
54 IP_UDPPROTO = 17,
55 ET_IP = 0x800,
56 Bcastip = 0xffffffff,
57 BPportsrc = 68,
58 BPportdst = 67,
59 TFTPport = 69,
60 Timeout = 5000, /* milliseconds */
61 Bootrequest = 1,
62 Bootreply = 2,
63 Tftp_READ = 1,
64 Tftp_WRITE = 2,
65 Tftp_DATA = 3,
66 Tftp_ACK = 4,
67 Tftp_ERROR = 5,
68 Segsize = 512,
69 TFTPSZ = Segsize+10,
70};
71
72typedef struct Bootp Bootp;
73struct Bootp
74{
75 uchar op; /* opcode */
76 uchar htype; /* hardware type */
77 uchar hlen; /* hardware address len */
78 uchar hops; /* hops */
79 uchar xid[4]; /* a random number */
80 uchar secs[2]; /* elapsed snce client started booting */
81 uchar pad[2];
82 uchar ciaddr[4]; /* client IP address (client tells server) */
83 uchar yiaddr[4]; /* client IP address (server tells client) */
84 uchar siaddr[4]; /* server IP address */
85 uchar giaddr[4]; /* gateway IP address */
86 uchar chaddr[16]; /* client hardware address */
87 char sname[64]; /* server host name (optional) */
88 char file[128]; /* boot file name */
89 char vend[128]; /* vendor-specific goo */
90};
91
92typedef struct Netaddr Netaddr;
93struct Netaddr
94{
95 ulong ip;
96 ushort port;
97 char ea[Eaddrlen];
98};
os/boot/mpc/l.s+370−0
@@ -0,0 +1,370 @@
1#include "mem.h"
2
3/* special instruction definitions */
4#define BDNE BC 0,2,
5#define BDNZ BC 16,0,
6#define NOOP OR R0,R0,R0
7
8/*
9 * common ppc special purpose registers
10 */
11#define DSISR 18
12#define DAR 19 /* Data Address Register */
13#define DEC 22 /* Decrementer */
14#define SRR0 26 /* Saved Registers (exception) */
15#define SRR1 27
16#define SPRG0 272 /* Supervisor Private Registers */
17#define SPRG1 273
18#define SPRG2 274
19#define SPRG3 275
20#define TBRU 269 /* Time base Upper/Lower (Reading) */
21#define TBRL 268
22#define TBWU 285 /* Time base Upper/Lower (Writing) */
23#define TBWL 284
24#define PVR 287 /* Processor Version */
25
26/*
27 * mpc82x-specific special purpose registers of interest here
28 */
29#define EIE 80
30#define EID 81
31#define NRI 82
32#define IMMR 638
33#define IC_CST 560
34#define IC_ADR 561
35#define IC_DAT 562
36#define DC_CST 568
37#define DC_ADR 569
38#define DC_DAT 570
39#define MI_CTR 784
40#define MI_AP 786
41#define MI_EPN 787
42#define MI_TWC 789
43#define MI_RPN 790
44#define MI_DBCAM 816
45#define MI_DBRAM0 817
46#define MI_DBRAM1 818
47#define MD_CTR 792
48#define M_CASID 793
49#define MD_AP 794
50#define MD_EPN 795
51#define M_TWB 796
52#define MD_TWC 797
53#define MD_RPN 798
54#define M_TW 799
55#define MD_DBCAM 824
56#define MD_DBRAM0 825
57#define MD_DBRAM1 826
58
59/* as on 603e, apparently mtmsr needs help in some chip revisions */
60#define WAITMSR SYNC; ISYNC
61
62/* use of SPRG registers in save/restore */
63#define SAVER0 SPRG0
64#define SAVER1 SPRG1
65#define SAVELR SPRG2
66#define SAVECR SPRG3
67
68#define UREGSIZE ((8+32)*4)
69#define UREGSPACE (UREGSIZE+8) /* allow for arg to trap, and align */
70
71/*
72 * This code is loaded by the ROM loader at location 0x3000,
73 * or lives in flash memory at 0x2800100.
74 * Move it to high memory so that it can load the kernel at 0x0000.
75 */
76
77#define LOADCODEBASE 0x3000 /* when downloaded in S records */
78#define FLASHCODEBASE (FLASHMEM+0x100) /* when in flash */
79
80 TEXT start(SB), $-4
81 MOVW MSR, R3
82 MOVW $(EE|IP|RI), R4
83 ANDN R4, R3
84 OR $ME, R3
85 SYNC
86 MOVW R3, MSR /* turn off interrupts but enable traps */
87 WAITMSR
88
89/*
90 * reset the caches and disable them for now
91 */
92 MOVW SPR(IC_CST), R4 /* read and clear */
93 MOVW $(5<<25), R4
94 MOVW R4, SPR(IC_CST) /* unlock all */
95 ISYNC
96 MOVW $(6<<25), R4
97 MOVW R4, SPR(IC_CST) /* invalidate all */
98 ISYNC
99 MOVW $(2<<25), R4
100 MOVW R4, SPR(IC_CST) /* disable i-cache */
101 ISYNC
102
103 SYNC
104 MOVW SPR(DC_CST), R4 /* read and clear */
105 MOVW $(10<<24), R4
106 MOVW R4, SPR(DC_CST) /* unlock all */
107 ISYNC
108 MOVW $(12<<24), R4
109 MOVW R4, SPR(DC_CST) /* invalidate all */
110 ISYNC
111 MOVW $(4<<24), R4
112 MOVW R4, SPR(DC_CST) /* disable i-cache */
113 ISYNC
114
115 MOVW $7, R4
116ANDN R4, R4, R4
117 MOVW R4, SPR(158) /* cancel `show cycle' for normal instruction execution */
118
119/*
120 * set other system configuration values
121 */
122 MOVW SPR(IMMR), R5 /* save initial space pointer */
123 MOVW $INTMEM, R4
124 MOVW R4, SPR(IMMR) /* set internal memory base */
125 MOVW $0xFFFFFF88, R3
126 MOVW R3, 4(R4) /* disable watchdog in sypcr */
127 MOVW $0x01012440, R3
128 MOVW R3, 0(R4) /* siumcr */
129
130/*
131 * system initialisation (init and map DRAM)
132 */
133 MOVW $0, R0
134 MOVW $setSB(SB), R2
135 MOVW $(0xF000<<16), R3
136/*MOVW R0, R3*/
137 ANDCC R5, R3 /* initial space is high? */
138 BEQ notrom
139 MOVW $FLASHCODEBASE, R5 /* where $start(SB) actually is now */
140 MOVW $start(SB), R4 /* logical start address */
141 SUB R4, R5, R6 /* text relocation value */
142 MOVW $etext(SB), R7
143 SUB R4, R7
144 ADD R5, R7 /* data address in ROM */
145 MOVW $bdata(SB), R8
146 SUB R8, R2
147 ADD R7, R2 /* relocate SB: SB' = romdata+(SB-bdata) */
148 MOVW $sysinit0(SB), R4
149 ADD R6, R4 /* relocate sysinit0's address */
150 MOVW R4, CTR
151 MOVW $inmem(SB), R4
152 ADD R6, R4
153 MOVW R4, LR /* and the return address */
154 BR (CTR) /* call sysinit0 */
155 TEXT inmem(SB), $-4
156 MOVW $FLASHCODEBASE, R3
157 BR cpu0
158notrom:
159 MOVW $start(SB), R6
160 SUB R6, R2
161 ADD $LOADCODEBASE, R2
162 BL sysinit0(SB)
163 MOVW $LOADCODEBASE, R3
164
165/*
166 * cpu 0
167 * relocate bootstrap to our link addresses for text and data
168 * set new PC
169 */
170cpu0:
171 MOVW $setSB(SB), R2 /* set correct static base register */
172 MOVW $start(SB), R4
173 MOVW $etext(SB), R5
174 SUB R4, R5
175 CMP R4, R3 /* already there? */
176 BNE copytext
177 ADD R5, R3 /* start of data image */
178 BR copydata
179
180copytext:
181 ADD $3, R5
182 SRAW $2, R5
183 MOVW R5, CTR
184 SUB $4, R4
185 SUB $4, R3
186copyt: /* copy text */
187 MOVWU 4(R3), R5
188 MOVWU R5, 4(R4)
189 BDNZ copyt
190 ADD $4, R3
191
192copydata:
193 /* copy data */
194 MOVW $bdata(SB), R4
195 CMP R4, R3 /* already there? */
196 BEQ loadkpc
197 MOVW $edata(SB), R5
198 SUB R4, R5
199 ADD $3, R5
200 SRAW $2, R5
201 MOVW R5, CTR
202 SUB $4, R4
203 SUB $4, R3
204copyd:
205 MOVWU 4(R3), R5
206 MOVWU R5, 4(R4)
207 BDNZ copyd
208
209 /* load correct PC */
210loadkpc:
211 MOVW $start1(SB), R3
212 MOVW R3, LR
213 BR (LR)
214TEXT start1(SB), $-4
215 MOVW $edata(SB), R3
216 MOVW $end(SB), R4
217 SUBCC R3, R4
218 BLE skipz
219 SRAW $2, R4
220 MOVW R4, CTR
221 SUB $4, R3
222 MOVW $0, R0
223zero:
224 MOVWU R0, 4(R3)
225 BDNZ zero
226skipz:
227 MOVW $mach0(SB), R1
228 MOVW R1, m(SB)
229 ADD $(MACHSIZE-8), R1
230 MOVW $0, R0
231 BL main(SB)
232 BR 0(PC)
233
234TEXT getmsr(SB), $0
235 MOVW MSR, R3
236 RETURN
237
238TEXT putmsr(SB), $0
239 SYNC
240 MOVW R3, MSR
241 WAITMSR
242 RETURN
243
244TEXT eieio(SB), $0
245 EIEIO
246 RETURN
247
248TEXT idle(SB), $0
249 RETURN
250
251TEXT spllo(SB), $0
252 MOVW MSR, R3
253 OR $EE, R3, R4
254 SYNC
255 MOVW R4, MSR
256 WAITMSR
257 RETURN
258
259TEXT splhi(SB), $0
260 MOVW MSR, R3
261 RLWNM $0, R3, $~EE, R4
262 SYNC
263 MOVW R4, MSR
264 WAITMSR
265 RETURN
266
267TEXT splx(SB), $0
268 MOVW MSR, R4
269 RLWMI $0, R3, $EE, R4
270 SYNC
271 MOVW R4, MSR
272 WAITMSR
273 RETURN
274
275TEXT gettbl(SB), $0
276/* MOVW SPR(TBRL), R3 */
277 WORD $0x7c6c42e6 /* mftbl on 8xx series */
278 RETURN
279
280TEXT getpvr(SB), $0
281 MOVW SPR(PVR), R3
282 RETURN
283
284TEXT getimmr(SB), $0
285 MOVW SPR(IMMR), R3
286 RETURN
287
288TEXT getdec(SB), $0
289 MOVW SPR(DEC), R3
290 RETURN
291
292TEXT putdec(SB), $0
293 MOVW R3, SPR(DEC)
294 RETURN
295
296/*
297 * save state in Ureg on kernel stack.
298 * enter with R0 giving the PC from the call to `exception' from the vector.
299 * on return, SB (R2) has been set, and R3 has the Ureg*
300 */
301TEXT saveureg(SB), $-4
302 SUB $UREGSPACE, R1
303 MOVMW R2, 48(R1) /* r2:r31 */
304 MOVW $setSB(SB), R2
305 MOVW SPR(SAVER1), R4
306 MOVW R4, 44(R1)
307 MOVW SPR(SAVER0), R5
308 MOVW R5, 40(R1)
309 MOVW CTR, R6
310 MOVW R6, 36(R1)
311 MOVW XER, R4
312 MOVW R4, 32(R1)
313 MOVW SPR(SAVECR), R5 /* CR */
314 MOVW R5, 28(R1)
315 MOVW SPR(SAVELR), R6 /* LR */
316 MOVW R6, 24(R1)
317 /* pad at 20(R1) */
318 MOVW SPR(SRR0), R4
319 MOVW R4, 16(R1) /* old PC */
320 MOVW SPR(SRR1), R5
321 MOVW R5, 12(R1)
322 MOVW R0, 8(R1) /* cause/vector, encoded in LR from vector */
323 ADD $8, R1, R3 /* Ureg* */
324 STWCCC R3, (R1) /* break any pending reservations */
325 MOVW $0, R0 /* R0ISZERO */
326 BR (LR)
327
328/*
329 * restore state from Ureg
330 * SB (R2) is unusable on return
331 */
332TEXT restoreureg(SB), $-4
333 MOVMW 48(R1), R2 /* r2:r31 */
334 /* defer R1 */
335 MOVW 40(R1), R0
336 MOVW R0, SPR(SAVER0)
337 MOVW 36(R1), R0
338 MOVW R0, CTR
339 MOVW 32(R1), R0
340 MOVW R0, XER
341 MOVW 28(R1), R0
342 MOVW R0, CR /* CR */
343 MOVW 24(R1), R0
344 MOVW R0, SPR(SAVELR) /* LR */
345 /* pad, skip */
346 MOVW 16(R1), R0
347 MOVW R0, SPR(SRR0) /* old PC */
348 MOVW 12(R1), R0
349 MOVW R0, SPR(SRR1) /* old MSR */
350 /* cause, skip */
351 MOVW 44(R1), R1 /* old SP */
352 BR (LR)
353
354TEXT exception(SB), $-4
355 MOVW R1, SPR(SAVER1)
356 MOVW CR, R0
357 MOVW R0, SPR(SAVECR)
358 MOVW LR, R0
359 BL saveureg(SB)
360 MOVW $0, R0
361 BL trap(SB)
362 BL restoreureg(SB)
363 MOVW SPR(SAVELR), R0
364 MOVW R0, LR
365 MOVW SPR(SAVER0), R0
366 ISYNC
367 RFI
368
369GLOBL mach0+0(SB), $MACHSIZE
370GLOBL m(SB), $4
os/boot/mpc/lib.h+106−0
@@ -0,0 +1,106 @@
1/*
2 * functions (possibly) linked in, complete, from libc.
3 */
4
5/*
6 * mem routines
7 */
8extern void* memccpy(void*, void*, int, long);
9extern void* memset(void*, int, long);
10extern int memcmp(void*, void*, long);
11extern void* memmove(void*, void*, long);
12extern void* memchr(void*, int, long);
13
14/*
15 * string routines
16 */
17extern char* strcat(char*, char*);
18extern char* strchr(char*, char);
19extern int strcmp(char*, char*);
20extern char* strcpy(char*, char*);
21extern char* strncat(char*, char*, long);
22extern char* strncpy(char*, char*, long);
23extern int strncmp(char*, char*, long);
24extern long strlen(char*);
25extern char* strrchr(char*, char);
26extern char* strstr(char*, char*);
27
28/*
29 * print routines
30 * Fconv isn't used but is defined to satisfy prototypes in libg.h
31 * that are never called.
32 */
33typedef struct Fconv Fconv;
34
35extern char* donprint(char*, char*, char*, void*);
36extern int sprint(char*, char*, ...);
37extern int print(char*, ...);
38
39#define PRINTSIZE 256
40
41/*
42 * one-of-a-kind
43 */
44extern int atoi(char*);
45extern long strtol(char*, char**, int);
46extern ulong strtoul(char*, char**, int);
47extern long end;
48
49/*
50 * Syscall data structures
51 */
52
53#define MORDER 0x0003 /* mask for bits defining order of mounting */
54#define MREPL 0x0000 /* mount replaces object */
55#define MBEFORE 0x0001 /* mount goes before others in union directory */
56#define MAFTER 0x0002 /* mount goes after others in union directory */
57#define MCREATE 0x0004 /* permit creation in mounted directory */
58#define MMASK 0x0007 /* all bits on */
59
60#define OREAD 0 /* open for read */
61#define OWRITE 1 /* write */
62#define ORDWR 2 /* read and write */
63#define OEXEC 3 /* execute, == read but check execute permission */
64#define OTRUNC 16 /* or'ed in (except for exec), truncate file first */
65#define OCEXEC 32 /* or'ed in, close on exec */
66#define ORCLOSE 64 /* or'ed in, remove on close */
67
68#define NCONT 0 /* continue after note */
69#define NDFLT 1 /* terminate after note */
70
71typedef struct Qid Qid;
72typedef struct Dir Dir;
73typedef struct Waitmsg Waitmsg;
74
75#define ERRLEN 64
76#define DIRLEN 116
77#define NAMELEN 28
78
79struct Qid
80{
81 ulong path;
82 ulong vers;
83};
84
85struct Dir
86{
87 char name[NAMELEN];
88 char uid[NAMELEN];
89 char gid[NAMELEN];
90 Qid qid;
91 ulong mode;
92 long atime;
93 long mtime;
94 vlong length;
95 short type;
96 short dev;
97};
98
99struct Waitmsg
100{
101 int pid; /* of loved one */
102 int status; /* unused; a placeholder */
103 ulong time[3]; /* of loved one */
104 char msg[ERRLEN];
105};
106#define nelem(x) (sizeof(x)/sizeof((x)[0]))
os/boot/mpc/main.c+524−0
@@ -0,0 +1,524 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7
8#include "dosfs.h"
9
10typedef struct Type Type;
11typedef struct Medium Medium;
12typedef struct Mode Mode;
13
14enum {
15 Dany = -1,
16 Nmedia = 16,
17
18 /* DS1 switch options */
19 Sflashfs = 1<<0, /* take local fs from flash */
20 Snotflash = 1<<1, /* don't boot from flash */
21};
22
23enum { /* type */
24 Tflash,
25 Tuart,
26 Tether,
27 Thard,
28
29 Tany = -1,
30};
31
32enum { /* flag and name */
33 Fnone = 0x00,
34
35 Fdos = 0x01,
36 Ndos = 0x00,
37 Fboot = 0x02,
38 Nboot = 0x01,
39 Fbootp = 0x04,
40 Nbootp = 0x02,
41 Fflash = 0x08,
42 Fuart = 0x10,
43 NName = 0x03,
44
45 Fany = Fbootp|Fboot|Fdos|Fflash|Fuart,
46
47 Fini = 0x10,
48 Fprobe = 0x80,
49};
50
51enum { /* mode */
52 Mauto = 0x00,
53 Mlocal = 0x01,
54 Manual = 0x02,
55 NMode = 0x03,
56};
57
58typedef struct Type {
59 int type;
60 char *cname;
61 int flag;
62 int (*init)(void);
63 long (*read)(int, void*, long);
64 long (*seek)(int, long);
65 Partition* (*setpart)(int, char*);
66 char* name[NName];
67
68 int mask;
69 Medium* media;
70} Type;
71
72typedef struct Medium {
73 Type* type;
74 int flag;
75 Partition* partition;
76 Dos;
77
78 Medium* next;
79} Medium;
80
81typedef struct Mode {
82 char* name;
83 int mode;
84} Mode;
85
86static Type types[] = {
87 { Tflash, "flash",
88 Fflash,
89 flashinit, 0, 0, 0,
90 { 0, "F", 0, }
91 },
92/*
93 { Tuart, "uart",
94 Fuart|Fboot,
95 uartinit, uartread, uartseek, setuartpart,
96 { 0, "u", 0, }
97 },
98*/
99 { Tether, "ether",
100 Fbootp,
101 etherinit, 0, 0, 0,
102 { 0, 0, "e", },
103 },
104 { Thard, "ata",
105 Fini|Fboot|Fdos,
106 0, 0, 0, 0, /* not used now, will be later with PCMCIA */
107 { "hd", "h", 0, },
108 },
109 {-1},
110};
111
112static Medium media[Nmedia];
113static Medium *curmedium = media;
114
115static Mode modes[NMode+1] = {
116 [Mauto] { "auto", Mauto, },
117 [Mlocal] { "local", Mlocal, },
118 [Manual] { "manual", Manual, },
119};
120
121static char *inis[] = {
122 "inferno/inferno.ini",
123 "inferno.ini",
124 "plan9/plan9.ini",
125 "plan9.ini",
126 0,
127};
128char **ini;
129int predawn;
130
131static int
132parse(char *line, int *type, int *flag, int *dev, char *file)
133{
134 Type *tp;
135 char buf[2*NAMELEN], *v[4], *p;
136 int i;
137
138 strcpy(buf, line);
139 switch(getcfields(buf, v, 4, "!")){
140
141 case 3:
142 break;
143
144 case 2:
145 v[2] = "";
146 break;
147
148 default:
149 return 0;
150 }
151
152 *flag = 0;
153 for(tp = types; tp->cname; tp++){
154 for(i = 0; i < NName; i++){
155
156 if(tp->name[i] == 0 || strcmp(v[0], tp->name[i]))
157 continue;
158 *type = tp->type;
159 *flag |= 1<<i;
160
161 if((*dev = strtoul(v[1], &p, 0)) == 0 && p == v[1])
162 return 0;
163
164 strcpy(file, v[2]);
165
166 return 1;
167 }
168 }
169
170 return 0;
171
172}
173
174static int
175boot(Medium *mp, int flag, char *file)
176{
177 Dosfile df;
178 char ixdos[128], *p;
179 int r;
180
181 uartsetboot(0);
182 if(flag & Fbootp){
183 sprint(BOOTLINE, "%s!%d", mp->type->name[Nbootp], mp->dev);
184 return bootp(mp->dev, file);
185 }
186
187 if(flag & Fflash){
188 if(mp->flag & Fflash && flashbootable(0))
189 flashboot(mp->dev);
190 }
191
192 if(flag & Fboot){
193
194 if(mp->flag & Fini){
195 (*mp->type->setpart)(mp->dev, "disk");
196 plan9ini(mp, nil);
197 }
198 if(file == 0 || *file == 0)
199 file = mp->partition->name;
200 (*mp->type->setpart)(mp->dev, file);
201 sprint(BOOTLINE, "%s!%d!%s", mp->type->name[Nboot], mp->dev, file);
202 r = plan9boot(mp->dev, mp->seek, mp->read);
203 uartsetboot(0);
204 return r;
205 }
206
207 if(flag & Fdos){
208 if(mp->type->setpart)
209 (*mp->type->setpart)(mp->dev, "disk");
210 if(mp->flag & Fini)
211 plan9ini(mp, nil);
212 if(file == 0 || *file == 0){
213 strcpy(ixdos, *ini);
214 if(p = strrchr(ixdos, '/'))
215 p++;
216 else
217 p = ixdos;
218 strcpy(p, "impc");
219 if(dosstat(mp, ixdos, &df) <= 0)
220 return -1;
221 }
222 else
223 strcpy(ixdos, file);
224 sprint(BOOTLINE, "%s!%d!%s", mp->type->name[Ndos], mp->dev, ixdos);
225 return dosboot(mp, ixdos);
226 }
227
228 return -1;
229}
230
231static Medium*
232allocm(Type *tp)
233{
234 Medium **l;
235
236 if(curmedium >= &media[Nmedia])
237 return 0;
238
239 for(l = &tp->media; *l; l = &(*l)->next)
240 ;
241 *l = curmedium++;
242 return *l;
243}
244
245Medium*
246probe(int type, int flag, int dev)
247{
248 Type *tp;
249 int dombr, i, start;
250 Medium *mp;
251 Dosfile df;
252 Partition *pp;
253
254 for(tp = types; tp->cname; tp++){
255 if(type != Tany && type != tp->type || tp->init == 0)
256 continue;
257
258 if(flag != Fnone){
259 for(mp = tp->media; mp; mp = mp->next){
260 if((flag & mp->flag) && (dev == Dany || dev == mp->dev))
261 return mp;
262 }
263 }
264 if((tp->flag & Fprobe) == 0){
265 tp->flag |= Fprobe;
266 tp->mask = (*tp->init)();
267 }
268
269 for(i = 0; tp->mask; i++){
270 if((tp->mask & (1<<i)) == 0)
271 continue;
272 tp->mask &= ~(1<<i);
273
274 if((mp = allocm(tp)) == 0)
275 continue;
276
277 mp->dev = i;
278 mp->flag = tp->flag;
279 mp->seek = tp->seek;
280 mp->read = tp->read;
281 mp->type = tp;
282
283 if(mp->flag & Fboot){
284 if((mp->partition = (*tp->setpart)(i, "boot")) == 0)
285 mp->flag &= ~Fboot;
286 if((mp->flag & (Fflash|Fuart)) == 0)
287 (*tp->setpart)(i, "disk");
288 }
289
290 if(mp->flag & Fdos){
291 start = 0;
292 dombr = 1;
293 if(mp->type->setpart){
294 if(pp = (*mp->type->setpart)(i, "dos")){
295 if(start = pp->start)
296 dombr = 0;
297 }
298 (*tp->setpart)(i, "disk");
299 }
300 if(dosinit(mp, start, dombr) < 0)
301 mp->flag &= ~(Fini|Fdos);
302 else
303 print("dos init failed\n");
304 }
305
306 if(mp->flag & Fini){
307 mp->flag &= ~Fini;
308 for(ini = inis; *ini; ini++){
309 if(dosstat(mp, *ini, &df) <= 0)
310 continue;
311 mp->flag |= Fini;
312 break;
313 }
314 }
315
316 if((flag & mp->flag) && (dev == Dany || dev == i))
317 return mp;
318 }
319 }
320
321 return 0;
322}
323
324void
325main(void)
326{
327 Medium *mp;
328 int dev, flag, i, mode, tried, type, options;
329 char def[2*NAMELEN], file[2*NAMELEN], line[80], *p;
330 Type *tp;
331
332 machinit();
333 archinit();
334 meminit();
335 cpminit();
336 trapinit();
337 consinit(); /* screen and keyboard initially */
338 screeninit();
339 cpuidprint();
340 alarminit();
341 clockinit();
342 predawn = 0;
343 spllo();
344 options = archoptionsw();
345
346 mp = 0;
347 for(tp = types; tp->cname; tp++){
348 if(tp->type == Tether)
349 continue;
350 if((mp = probe(tp->type, Fini, Dany)) && (mp->flag & Fini)){
351 plan9ini(mp, nil);
352 break;
353 }
354 }
355
356 if(mp == 0 || (mp->flag & Fini) == 0)
357 plan9ini(nil, flashconfig(0));
358
359 //consinit(); /* establish new console location */
360
361 if((options & Snotflash) == 0 && flashbootable(0)){
362 print("Flash boot\n");
363 flashboot(0);
364 }
365
366 tried = 0;
367 mode = Mauto;
368 p = getconf("bootfile");
369 flag = 0;
370
371 if(p != 0) {
372 mode = Manual;
373 for(i = 0; i < NMode; i++){
374 if(strcmp(p, modes[i].name) == 0){
375 mode = modes[i].mode;
376 goto done;
377 }
378 }
379 if(parse(p, &type, &flag, &dev, file) == 0) {
380 print("Bad bootfile syntax: %s\n", p);
381 goto done;
382 }
383 mp = probe(type, flag, dev);
384 if(mp == 0) {
385 print("Cannot access device: %s\n", p);
386 goto done;
387 }
388 tried = boot(mp, flag, file);
389 }
390done:
391 if(tried == 0 && mode != Manual){
392 flag = Fany;
393 if(mode == Mlocal)
394 flag &= ~Fbootp;
395 if(options & Snotflash)
396 flag &= ~Fflash;
397 if((mp = probe(Tany, flag, Dany)) != 0)
398 boot(mp, flag & mp->flag, 0);
399 }
400
401 def[0] = 0;
402 probe(Tany, Fnone, Dany);
403
404 flag = 0;
405 for(tp = types; tp->cname; tp++){
406 for(mp = tp->media; mp; mp = mp->next){
407 if(flag == 0){
408 flag = 1;
409 print("Boot devices:");
410 }
411
412 if(mp->flag & Fbootp)
413 print(" %s!%d", mp->type->name[Nbootp], mp->dev);
414 if(mp->flag & Fdos)
415 print(" %s!%d", mp->type->name[Ndos], mp->dev);
416 if(mp->flag & (Fflash|Fuart) || mp->flag & Fboot)
417 print(" %s!%d", mp->type->name[Nboot], mp->dev);
418 }
419 }
420 if(flag)
421 print("\n");
422
423 for(;;){
424 if(getstr("boot from", line, sizeof(line), def) >= 0){
425 if(parse(line, &type, &flag, &dev, file)){
426 if(mp = probe(type, flag, dev))
427 boot(mp, flag, file);
428 }
429 }
430 def[0] = 0;
431 }
432}
433
434void
435machinit(void)
436{
437 memset(m, 0, sizeof(*m));
438 m->delayloop = 20000;
439 m->cpupvr = getpvr();
440 m->iomem = KADDR(INTMEM);
441}
442
443int
444getcfields(char* lp, char** fields, int n, char* sep)
445{
446 int i;
447
448 for(i = 0; lp && *lp && i < n; i++){
449 while(*lp && strchr(sep, *lp) != 0)
450 *lp++ = 0;
451 if(*lp == 0)
452 break;
453 fields[i] = lp;
454 while(*lp && strchr(sep, *lp) == 0){
455 if(*lp == '\\' && *(lp+1) == '\n')
456 *lp++ = ' ';
457 lp++;
458 }
459 }
460
461 return i;
462}
463
464static Map memv[512];
465static RMap rammap = {"physical memory"};
466
467void
468meminit(void)
469{
470 ulong e;
471
472 mapinit(&rammap, memv, sizeof(memv));
473 e = PADDR(&end);
474 mapfree(&rammap, e, 4*1024*1024-e); /* fixed 4Mbytes is plenty for bootstrap */
475}
476
477void*
478ialloc(ulong n, int align)
479{
480 ulong a;
481 int s;
482
483 if(align <= 0)
484 align = 4;
485 s = splhi();
486 a = mapalloc(&rammap, 0, n, align);
487 splx(s);
488 if(a == 0)
489 panic("ialloc");
490 return memset(KADDR(a), 0, n);
491}
492
493void*
494malloc(ulong n)
495{
496 ulong *p;
497
498 n = ((n+sizeof(int)-1)&~(sizeof(int)-1))+2*sizeof(int);
499 p = ialloc(n, sizeof(int));
500 *p++ = 0xcafebeef;
501 *p++ = n;
502 return p;
503}
504
505void
506free(void *ap)
507{
508 int s;
509 ulong *p;
510
511 p = ap;
512 if(p){
513 if(*(p -= 2) != 0xcafebeef)
514 panic("free");
515 s = splhi();
516 mapfree(&rammap, (ulong)p, p[1]);
517 splx(s);
518 }
519}
520
521void
522sched(void)
523{
524}
os/boot/mpc/mem.c+0−0

Empty file added.

os/boot/mpc/mem.h+95−0
@@ -0,0 +1,95 @@
1/*
2 * Memory and machine-specific definitions. Used in C and assembler.
3 */
4
5/*
6 * Sizes
7 */
8#define BI2BY 8 /* bits per byte */
9#define BI2WD 32 /* bits per word */
10#define BY2WD 4 /* bytes per word */
11#define BY2PG 4096 /* bytes per page */
12#define WD2PG (BY2PG/BY2WD) /* words per page */
13#define PGSHIFT 12 /* log(BY2PG) */
14#define PGROUND(s) (((s)+(BY2PG-1))&~(BY2PG-1))
15
16#define MAXMACH 1 /* max # cpus system can run */
17#define CACHELINELOG 4
18#define CACHELINESZ (1<<CACHELINELOG)
19
20/*
21 * Time
22 */
23#define HZ (50) /* clock frequency */
24#define MS2HZ (1000/HZ) /* millisec per clock tick */
25#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */
26#define TK2MS(t) ((((ulong)(t))*1000)/HZ) /* ticks to milliseconds */
27#define MS2TK(t) ((((ulong)(t))*HZ)/1000) /* milliseconds to ticks */
28#define MHz 1000000
29
30/*
31 * Fundamental values
32 */
33
34#define KZERO 0 /* bootstrap runs in real mode */
35#define MACHSIZE 4096
36
37/*
38 * physical MMU
39 */
40#define KSEG0 0x20000000
41#define KSEGM 0xE0000000 /* mask to check which seg */
42
43/*
44 * MSR bits
45 */
46
47#define POW 0x40000 /* enable power mgmt */
48#define TGPR 0x20000 /* GPR0-3 remapped; 603/603e specific */
49#define ILE 0x10000 /* interrupts little endian */
50#define EE 0x08000 /* enable external/decrementer interrupts */
51#define PR 0x04000 /* =1, user mode */
52#define FPE 0x02000 /* enable floating point */
53#define ME 0x01000 /* enable machine check exceptions */
54#define FE0 0x00800
55#define SE 0x00400 /* single-step trace */
56#define BE 0x00200 /* branch trace */
57#define FE1 0x00100
58#define IP 0x00040 /* =0, vector to nnnnn; =1, vector to FFFnnnnn */
59#define IR 0x00020 /* enable instruction address translation */
60#define DR 0x00010 /* enable data address translation */
61#define RI 0x00002 /* exception is recoverable */
62#define LE 0x00001 /* little endian mode */
63
64#define KMSR (ME|FE0|FE1|FPE)
65#define UMSR (KMSR|PR|EE|IR|DR)
66
67/*
68 * MPC82x addresses; mpc8bug is happy with these
69 */
70#define BCSRMEM 0x02100000
71#define INTMEM 0x02200000
72#define FLASHMEM 0x02800000
73#define SDRAMMEM 0x03000000
74
75#define DPRAM (INTMEM+0x2000)
76#define DPLEN1 0x400
77#define DPLEN2 0x200
78#define DPLEN3 0x100
79#define DPBASE (DPRAM+DPLEN1)
80
81#define SCC1P (INTMEM+0x3C00)
82#define I2CP (INTMEM+0x3C80)
83#define MISCP (INTMEM+0x3CB0)
84#define IDMA1P (INTMEM+0x3CC0)
85#define SCC2P (INTMEM+0x3D00)
86#define SCC3P (INTMEM+0x3E00)
87#define SCC4P (INTMEM+0x3F00)
88#define SPIP (INTMEM+0x3D80)
89#define TIMERP (INTMEM+0x3DB0)
90#define SMC1P (INTMEM+0x3E80)
91#define DSP1P (INTMEM+0x3EC0)
92#define SMC2P (INTMEM+0x3F80)
93#define DSP2P (INTMEM+0x3FC0)
94
95#define KEEP_ALIVE_KEY 0x55ccaa33 /* clock and rtc register key */
os/boot/mpc/mkfile+116−0
@@ -0,0 +1,116 @@
1objtype=power
2OBJTYPE=power # always
3<../../../mkconfig
4SYSTARG=$OSTARG # always
5<$ROOT/mkfiles/mkfile-$SYSTARG-$OBJTYPE
6INSTALLDIR=$ROOT/Inferno/$OBJTYPE/bin #path of directory where kernel is installed
7ARCH=fads # selects board dependent code
8TARG=qb$ARCH
9OFILES=\
10 l.$O\
11 arch$ARCH.$O\
12 devuart.$O\
13 uartboot.$O\
14 alarm.$O\
15 bootp.$O\
16 clock.$O\
17 conf.$O\
18 console.$O\
19 cpm.$O\
20 defont0.$O\
21 donprint.$O\
22 dosboot.$O\
23 devether.$O\
24 etherscc.$O\
25 fblt.$O\
26 gbitbltclip.$O\
27 flash.$O\
28 main.$O\
29 plan9boot.$O\
30 qio.$O\
31 rmap.$O\
32 screen.$O\
33 init$ARCH.$O\
34 trap.$O\
35 zqs.$O\
36
37HFILES=\
38 boot.h\
39 dat.h\
40 fns.h\
41 io.h\
42 lib.h\
43 mem.h\
44 squeeze.h\
45 gnot.h\
46 arch$ARCH.h\
47
48LIBS=\
49 kern\
50
51LIBDIRS=$LIBS
52LIBNAMES=${LIBS:%=lib%.a}
53LIBFILES=${LIBS:%=$ROOT/$TARGMODEL/$OBJTYPE/lib/lib%.a}
54
55#all:NV: $TARG k.mx f.mx
56all:NV: $TARG
57install:V: $INSTALLDIR/$TARG
58installall:V: $INSTALLDIR/$TARG
59
60$INSTALLDIR/%: %
61 rm -f $INSTALLDIR/$stem && cp $stem $INSTALLDIR/$stem
62
63$TARG: $OFILES $LIBNAMES
64 $LD -o $target -l -T0x140000 -R4 $OFILES $LIBFILES
65 ls -l $target
66
67qbrom$ARCH: $OFILES $LIBNAMES
68 $LD -o $target -l -T0x02800100 -R0 -D0x140000 $OFILES $LIBFILES
69
70k.mx: $TARG
71 ms2 -S 0x100 -a 0x100 -p 4 $TARG >k.mx
72
73f.mx: qbrom$ARCH
74 ms2 -S 0x100 -a 0x2800100 -p 4 $prereq >f.mx
75
76%.$O: %.s
77 $AS $stem.s
78
79%.$O: %.c
80 $CC $CFLAGS $stem.c
81
82%.$O: $HFILES
83
84lib%.a:V: $SHELLTYPE-lib%.a
85
86rc-lib%.a nt-lib%.a:VQ:
87 echo '@{builtin cd ' $ROOT/lib$stem ';mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE install}'
88 @{builtin cd $ROOT/lib$stem ;mk 'SHELLTYPE='$SHELLTYPE 'SYSTARG='$SYSTARG 'OBJTYPE='$OBJTYPE install}
89
90sh-lib%.a:VQ:
91 echo "(cd $ROOT/lib$stem ; mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE install)"
92 (cd $ROOT/lib$stem ; mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE install)
93
94clock.$O floppy.$O trap.$O: ureg.h
95conf.$O dosboot.$O main.$O: dosfs.h
96ether.$O etherscc.$O: etherif.h
97bootp.$O: ip.h
98
99clean:V:
100 rm -f *.[$OS] [$OS].out y.tab.? y.debug y.output $TARG qboot k.mx f.mx romboot
101
102nuke-sh:QV:
103 for i in $LIBDIRS
104 do
105 echo "(cd $ROOT/lib$i ; mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE nuke)"
106 (cd $ROOT/lib$i; mk 'SHELLTYPE='$SHELLTYPE 'SYSTARG='$SYSTARG 'OBJTYPE='$OBJTYPE nuke)
107 done
108
109nuke-rc nuke-nt:QV:
110 for (i in $LIBDIRS)
111 {
112 echo '@{cd $ROOT/lib$i ; mk SHELLTYPE=$SHELLTYPE SYSTARG=$SYSTARG OBJTYPE=$OBJTYPE nuke}'
113 @{cd $ROOT/lib$i; mk 'SHELLTYPE='$SHELLTYPE 'SYSTARG='$SYSTARG 'OBJTYPE='$OBJTYPE nuke}
114 }
115
116nuke:V: clean nuke-$SHELLTYPE
os/boot/mpc/ms2.c+179−0
@@ -0,0 +1,179 @@
1#include <u.h>
2#include <libc.h>
3#include <bio.h>
4#include <mach.h>
5
6void record(uchar*, int);
7void usage(void);
8void dosegment(long, int);
9void trailer(ulong);
10
11enum
12{
13 Recordsize = 32,
14};
15
16int dsegonly;
17int supressend;
18int binary;
19int addr4;
20ulong addr;
21ulong psize = 4096;
22ulong startaddr = 0x030000;
23Biobuf stdout;
24Biobuf bio;
25
26void
27main(int argc, char **argv)
28{
29 Dir dir;
30 Fhdr f;
31 int fd;
32
33 ARGBEGIN{
34 case 'd':
35 dsegonly++;
36 break;
37 case 's':
38 supressend++;
39 break;
40 case 'a':
41 addr = strtoul(ARGF(), 0, 0);
42 break;
43 case 'p':
44 psize = strtoul(ARGF(), 0, 0);
45 break;
46 case 'b':
47 binary++;
48 break;
49 case 'S':
50 startaddr = strtoul(ARGF(), 0, 0);
51 break;
52 case '4':
53 addr4++;
54 break;
55 default:
56 usage();
57 }ARGEND
58
59 if(argc != 1)
60 usage();
61
62 Binit(&stdout, 1, OWRITE);
63
64 fd = open(argv[0], OREAD);
65 if(fd < 0) {
66 fprint(2, "ms2: open %s: %r\n", argv[0]);
67 exits("open");
68 }
69
70 if(binary) {
71 if(dirfstat(fd, &dir) < 0) {
72 fprint(2, "ms2: stat failed %r");
73 exits("dirfstat");
74 }
75 Binit(&bio, fd, OREAD);
76 dosegment(0, dir.length);
77 if(supressend == 0)
78 trailer(startaddr);
79 Bterm(&stdout);
80 Bterm(&bio);
81 exits(0);
82 }
83
84 if(crackhdr(fd, &f) == 0){
85 fprint(2, "ms2: bad magic: %r\n");
86 exits("magic");
87 }
88 seek(fd, 0, 0);
89
90 Binit(&bio, fd, OREAD);
91
92 if(dsegonly)
93 dosegment(f.datoff, f.datsz);
94 else {
95 dosegment(f.txtoff, f.txtsz);
96 addr = (addr+(psize-1))&~(psize-1);
97 dosegment(f.datoff, f.datsz);
98 }
99
100 if(supressend == 0)
101 trailer(startaddr);
102
103 Bterm(&stdout);
104 Bterm(&bio);
105 exits(0);
106}
107
108void
109dosegment(long foff, int len)
110{
111 int l, n;
112 uchar buf[2*Recordsize];
113
114 Bseek(&bio, foff, 0);
115 for(;;) {
116 l = len;
117 if(l > Recordsize)
118 l = Recordsize;
119 n = Bread(&bio, buf, l);
120 if(n == 0)
121 break;
122 if(n < 0) {
123 fprint(2, "ms2: read error: %r\n");
124 exits("read");
125 }
126 record(buf, l);
127 len -= l;
128 }
129}
130
131void
132record(uchar *s, int l)
133{
134 int i;
135 ulong cksum;
136
137 if(addr4 || addr & (0xFF<<24)){
138 Bprint(&stdout, "S3%.2X%.8luX", l+5, addr);
139 cksum = l+5;
140 cksum += (addr>>24)&0xff;
141 }else{
142 Bprint(&stdout, "S2%.2X%.6X", l+4, addr);
143 cksum = l+4;
144 }
145 cksum += addr&0xff;
146 cksum += (addr>>8)&0xff;
147 cksum += (addr>>16)&0xff;
148
149 for(i = 0; i < l; i++) {
150 cksum += *s;
151 Bprint(&stdout, "%.2X", *s++);
152 }
153 Bprint(&stdout, "%.2X\n", (~cksum)&0xff);
154 addr += l;
155}
156
157void
158trailer(ulong a)
159{
160 ulong cksum;
161
162 cksum = 0;
163 if(addr4 || a & (0xFF<<24)){
164 Bprint(&stdout, "S7%.8luX", a);
165 cksum += (a>>24)&0xff;
166 }else
167 Bprint(&stdout, "S9%.6X", a);
168 cksum += a&0xff;
169 cksum += (a>>8)&0xff;
170 cksum += (a>>16)&0xff;
171 Bprint(&stdout, "%.2X\n", (~cksum)&0xff);
172}
173
174void
175usage(void)
176{
177 fprint(2, "usage: ms2 [-ds] [-a address] [-p pagesize] ?.out\n");
178 exits("usage");
179}
os/boot/mpc/plan9boot.c+96−0
@@ -0,0 +1,96 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6
7char *premature = "premature EOF\n";
8
9/*
10 * read in a segment
11 */
12static long
13readseg(int dev, long (*read)(int, void*, long), long len, long addr)
14{
15 char *a;
16 long n, sofar;
17
18 a = (char *)addr;
19 for(sofar = 0; sofar < len; sofar += n){
20 n = 8*1024;
21 if(len - sofar < n)
22 n = len - sofar;
23 n = (*read)(dev, a + sofar, n);
24 if(n <= 0)
25 break;
26 print(".");
27 }
28 return sofar;
29}
30
31/*
32 * boot
33 */
34int
35plan9boot(int dev, long (*seek)(int, long), long (*read)(int, void*, long))
36{
37 long n;
38 long addr;
39 void (*b)(void);
40 Exec *ep;
41
42 if((*seek)(dev, 0) < 0)
43 return -1;
44
45 /*
46 * read header
47 */
48 ep = (Exec *) ialloc(sizeof(Exec), 0);
49 n = sizeof(Exec);
50 if(readseg(dev, read, n, (long) ep) != n){
51 print(premature);
52 return -1;
53 }
54 if(GLLONG(ep->magic) != Q_MAGIC){
55 print("bad magic 0x%lux not a plan 9 executable!\n", GLLONG(ep->magic));
56 return -1;
57 }
58
59 /*
60 * read text
61 */
62 addr = PADDR(GLLONG(ep->entry));
63 n = GLLONG(ep->text);
64 print("%d", n);
65 if(readseg(dev, read, n, addr) != n){
66 print(premature);
67 return -1;
68 }
69
70 /*
71 * read data (starts at first page after kernel)
72 */
73 addr = PGROUND(addr+n);
74 n = GLLONG(ep->data);
75 print("+%d@%8.8lux", n, addr);
76 if(readseg(dev, read, n, addr) != n){
77 print(premature);
78 return -1;
79 }
80
81 /*
82 * bss and entry point
83 */
84 print("+%d\nstart at 0x%lux\n", GLLONG(ep->bss), GLLONG(ep->entry));
85 uartwait();
86 scc2stop();
87 splhi();
88
89 /*
90 * Go to new code. It's up to the program to get its PC relocated to
91 * the right place.
92 */
93 b = (void (*)(void))(PADDR(GLLONG(ep->entry)));
94 (*b)();
95 return 0;
96}
os/boot/mpc/qio.c+128−0
@@ -0,0 +1,128 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7
8struct Queue {
9 Block* first;
10 Block* last;
11 void (*kick)(void*);
12 void* arg;
13 long len;
14};
15
16Block *
17iallocb(int n)
18{
19 Block *b;
20
21 b = (Block*)malloc(sizeof(Block)+n);
22 b->data = (uchar*)b + sizeof(Block);
23 b->rp = b->wp = b->data;
24 b->lim = b->data + n;
25 b->next = 0;
26 b->magic = 0xcafebee0;
27 return b;
28}
29
30void
31freeb(Block *b)
32{
33 if(b){
34 if(b->magic != 0xcafebee0)
35 panic("freeb");
36 b->magic = 0;
37 b->next = (Block*)0xdeadbabe;
38 free(b);
39 }
40}
41
42Queue *
43qopen(int limit, int msg, void (*kick)(void*), void *arg)
44{
45 Queue *q;
46
47 USED(limit, msg);
48 q = (Queue*)malloc(sizeof(Queue));
49 q->first = q->last = 0;
50 q->kick = kick;
51 q->arg = arg;
52 q->len = 0;
53 return q;
54}
55
56Block *
57qget(Queue *q)
58{
59 int s;
60 Block *b;
61
62 s = splhi();
63 if((b = q->first) != 0){
64 q->first = b->next;
65 b->next = 0;
66 q->len -= BLEN(b);
67 if(q->len < 0)
68 panic("qget");
69 }
70 splx(s);
71 return b;
72}
73
74void
75qbwrite(Queue *q, Block *b)
76{
77 int s;
78
79 s = splhi();
80 b->next = 0;
81 if(q->first == 0)
82 q->first = b;
83 else
84 q->last->next = b;
85 q->last = b;
86 q->len += BLEN(b);
87 splx(s);
88 if(q->kick)
89 q->kick(q->arg);
90}
91
92long
93qlen(Queue *q)
94{
95 return q->len;
96}
97
98int
99qbgetc(Queue *q)
100{
101 Block *b;
102 int s, c;
103
104 c = -1;
105 s = splhi();
106 while(c < 0 && (b = q->first) != nil){
107 if(b->rp < b->wp){
108 c = *b->rp++;
109 q->len--;
110 }
111 if(b->rp >= b->wp){
112 q->first = b->next;
113 b->next = nil;
114 }
115 }
116 splx(s);
117 return c;
118}
119
120void
121qbputc(Queue *q, int c)
122{
123 Block *b;
124
125 b = iallocb(1);
126 *b->wp++ = c;
127 qbwrite(q, b);
128}
os/boot/mpc/rmap.c+104−0
@@ -0,0 +1,104 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6
7void
8mapinit(RMap *rmap, Map *map, int size)
9{
10 lock(rmap);
11 rmap->map = map;
12 rmap->mapend = map+(size/sizeof(Map));
13 unlock(rmap);
14}
15
16void
17mapfree(RMap* rmap, ulong addr, int size)
18{
19 Map *mp;
20 ulong t;
21
22 if(size <= 0)
23 return;
24
25 lock(rmap);
26 for(mp = rmap->map; mp->addr <= addr && mp->size; mp++)
27 ;
28
29 if(mp > rmap->map && (mp-1)->addr+(mp-1)->size == addr){
30 (mp-1)->size += size;
31 if(addr+size == mp->addr){
32 (mp-1)->size += mp->size;
33 while(mp->size){
34 mp++;
35 (mp-1)->addr = mp->addr;
36 (mp-1)->size = mp->size;
37 }
38 }
39 }
40 else{
41 if(addr+size == mp->addr && mp->size){
42 mp->addr -= size;
43 mp->size += size;
44 }
45 else do{
46 if(mp >= rmap->mapend){
47 print("mapfree: %s: losing 0x%uX, %d\n",
48 rmap->name, addr, size);
49 break;
50 }
51 t = mp->addr;
52 mp->addr = addr;
53 addr = t;
54 t = mp->size;
55 mp->size = size;
56 mp++;
57 }while(size = t);
58 }
59 unlock(rmap);
60}
61
62ulong
63mapalloc(RMap* rmap, ulong addr, int size, int align)
64{
65 Map *mp;
66 ulong maddr, oaddr;
67
68 lock(rmap);
69 for(mp = rmap->map; mp->size; mp++){
70 maddr = mp->addr;
71
72 if(addr){
73 if(maddr > addr)
74 continue;
75 if(addr+size > maddr+mp->size)
76 break;
77 maddr = addr;
78 }
79
80 if(align > 0)
81 maddr = ((maddr+align-1)/align)*align;
82 if(mp->addr+mp->size-maddr < size)
83 continue;
84
85 oaddr = mp->addr;
86 mp->addr = maddr+size;
87 mp->size -= maddr-oaddr+size;
88 if(mp->size == 0){
89 do{
90 mp++;
91 (mp-1)->addr = mp->addr;
92 }while((mp-1)->size = mp->size);
93 }
94
95 unlock(rmap);
96 if(oaddr != maddr)
97 mapfree(rmap, oaddr, maddr-oaddr);
98
99 return maddr;
100 }
101 unlock(rmap);
102
103 return 0;
104}
os/boot/mpc/screen.c+242−0
@@ -0,0 +1,242 @@
1#include "all.h"
2#include <libg.h>
3#include <gnot.h>
4
5enum {
6 Colldepth = 3,
7 Colmaxx = 640,
8 Colmaxxvis = 640,
9 Colmaxy = 480,
10};
11
12#define MINX 8
13
14extern GSubfont defont0;
15
16struct{
17 Point pos;
18 int bwid;
19}out;
20
21typedef struct Mode Mode;
22struct Mode {
23 int x;
24 int y;
25 int d;
26 char* aperture;
27 int apsize;
28};
29
30GBitmap gscreen;
31Point gchar(GBitmap*, Point, GFont*, int, Fcode);
32int setcolor(ulong, ulong, ulong, ulong);
33static void lcdinit(Mode*);
34
35void
36screeninit(void)
37{
38 Mode m;
39
40 m.x = Colmaxx;
41 m.y = Colmaxy;
42 m.d = Colldepth;
43 m.aperture = 0;
44 lcdinit(&m);
45 if(m.aperture == 0)
46 return;
47 gscreen.ldepth = 3;
48 gscreen.base = (ulong*)m.aperture;
49 gscreen.width = Colmaxx/BY2WD;
50 gscreen.r = Rect(0, 0, Colmaxxvis, Colmaxy);
51 gscreen.clipr = gscreen.r;
52 /*
53 * For now, just use a fixed colormap:
54 * 0 == white and 255 == black
55 */
56 setcolor(0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
57 setcolor(255, 0x00000000, 0x00000000, 0x00000000);
58
59 gbitblt(&gscreen, Pt(0, 0), &gscreen, gscreen.r, Zero);
60 out.pos.x = MINX;
61 out.pos.y = 0;
62 out.bwid = defont0.info[' '].width;
63}
64
65void
66screenputc(int c)
67{
68 Fontchar *i;
69 Point p;
70
71 if(gscreen.base == nil)
72 return;
73 switch(c){
74 case '\n':
75 out.pos.x = MINX;
76 out.pos.y += defont0.height;
77 if(out.pos.y > gscreen.r.max.y-defont0.height)
78 out.pos.y = gscreen.r.min.y;
79 gbitblt(&gscreen, Pt(0, out.pos.y), &gscreen,
80 Rect(0, out.pos.y, gscreen.r.max.x, out.pos.y+2*defont0.height),
81 Zero);
82 break;
83 case '\t':
84 out.pos.x += (8-((out.pos.x-MINX)/out.bwid&7))*out.bwid;
85 if(out.pos.x >= gscreen.r.max.x)
86 screenputc('\n');
87 break;
88 case '\b':
89 if(out.pos.x >= out.bwid+MINX){
90 out.pos.x -= out.bwid;
91 screenputc(' ');
92 out.pos.x -= out.bwid;
93 }
94 break;
95 default:
96 if(out.pos.x >= gscreen.r.max.x-out.bwid)
97 screenputc('\n');
98 c &= 0x7f;
99 if(c <= 0 || c >= defont0.n)
100 break;
101 i = defont0.info + c;
102 p = out.pos;
103 gbitblt(&gscreen, Pt(p.x+i->left, p.y), defont0.bits,
104 Rect(i[0].x, 0, i[1].x, defont0.height),
105 S);
106 out.pos.x = p.x + i->width;
107 break;
108 }
109}
110
111void
112screenputs(char *s, int n)
113{
114 while(n-- > 0)
115 screenputc(*s++);
116}
117
118/*
119 * See section 5.2.1 (page 5-6) of the MPC823 manual
120 */
121static uchar lcdclock[17] = { /* (a<<2)|b => divisor of (1<<a)*((b<<1)+1) */
122 0, 0, (1<<2), 1,
123 (2<<2), 2, (1<<2)|1, 3,
124 (3<<2), (1<<2)|2, (1<<2)|2, (2<<2)|1,
125 (2<<2)|1, (1<<2)|3, (1<<2)|3, (4<<2),
126 (4<<2)
127};
128
129/*
130 * support for the Sharp LQ64D341 TFT colour display
131 */
132
133enum {
134 COLS = 640,
135 ROWS = 480,
136 LDEPTH = 3, /* screen depth */
137 LCDFREQ = 25000000,
138
139 /* lccr */
140 ClockLow = 1<<11,
141 OELow = 1<<10,
142 HsyncLow = 1<<9,
143 VsyncLow = 1<<8,
144 DataLow = 1<<7,
145 Passive8 = 1<<4,
146 DualScan = 1<<3,
147 IsColour = 1<<2,
148 IsTFT = 1<<1,
149 Enable = 1<<0,
150
151 /* lchcr */
152 BigEndian = 1<<24,
153 AT7 = 7<<21, /* access type */
154
155 /* sdcr */
156 LAM = 1<<6, /* ``LCD aggressive mode'' */
157};
158
159/*
160 * TO DO: most of the data could come from a table
161 */
162static void
163lcdinit(Mode *mode)
164{
165 IMM *io;
166 int i, d;
167 long hz;
168
169 io = m->iomem;
170 mode->y = ROWS;
171 mode->x = COLS;
172 mode->d = LDEPTH;
173 mode->aperture = ialloc(mode->x*mode->y, 16);
174 mode->apsize = mode->x*mode->y;
175
176 io->sdcr &= ~LAM; /* MPC823 errata: turn off LAM before disabling controller */
177 io->lcfaa = PADDR(mode->aperture);
178 io->lccr = (((mode->x*mode->y*(1<<LDEPTH)+127)/128) << 17) | (LDEPTH << 5) | IsColour | IsTFT | OELow | VsyncLow | ClockLow;
179
180 switch(LDEPTH){
181 default:
182 case 0:
183 /* monochrome/greyscale identity map */
184 for(i=0; i<16; i++)
185 io->lcdmap[i] = i;
186 break;
187 case 2:
188 /* 4-bit grey scale map */
189 for(i=0; i<16; i++)
190 io->lcdmap[0] = (i<<8)|(i<<4)|i;
191 break;
192 case 3:
193 /* 8-bit linear map */
194 for(i=0; i<256; i++)
195 io->lcdmap[i] = (i<<8)|(i<<4)|i;
196 break;
197 }
198
199 io->lcvcr = (mode->y << 11) | (1<<28) | 33; /* 2 line vsync pulse, 34 line wait between frames */
200 io->lchcr = (mode->x<<10) | BigEndian | 228; /* clock cycles between lines */
201
202 hz = m->cpuhz;
203 d = hz/LCDFREQ;
204 if(hz/d > LCDFREQ)
205 d++;
206 if(d >= 16)
207 d = 16;
208
209 /*
210 * enable LCD outputs
211 */
212 io->pddat = 0;
213 io->pdpar = 0x1fff;
214io->pdpar &= ~SIBIT(6); /* 823 bug fix? */
215 io->pddir = 0x1fff;
216 io->pbpar |= IBIT(31) | IBIT(19) | IBIT(17);
217 io->pbdir |= IBIT(31) | IBIT(19) | IBIT(17);
218 io->pbodr &= ~(IBIT(31) | IBIT(19) | IBIT(17));
219
220 eieio();
221 io->sccrk = KEEP_ALIVE_KEY;
222 eieio();
223 io->sccr = (io->sccr & ~0x1F) | lcdclock[d];
224 eieio();
225 io->sccrk = ~KEEP_ALIVE_KEY;
226 eieio();
227 gscreen.width = gscreen.width; /* access external memory before enabling (mpc823 errata) */
228 io->lcsr = 7; /* clear status */
229 eieio();
230 io->lccr |= Enable;
231 archbacklight(1);
232}
233
234int
235setcolor(ulong p, ulong r, ulong g, ulong b)
236{
237 r >>= 28;
238 g >>= 28;
239 b >>= 28;
240 m->iomem->lcdmap[~p&0xFF] = (r<<8) | (g<<4) | b; /* TO DO: it's a function of the ldepth */
241 return 1;
242}
os/boot/mpc/sload.c+71−0
@@ -0,0 +1,71 @@
1/*
2 * send S records to rpcg
3 */
4
5#include <u.h>
6#include <libc.h>
7#include <bio.h>
8
9static int dbg;
10static char buf[2048];
11static int run=1;
12static void stuffbym(char*, int, int);
13static void getdot(void);
14
15void
16main(int argc, char **argv)
17{
18 int n;
19 char *l;
20 Biobuf *f;
21 static int p;
22
23 ARGBEGIN{
24 case 'd': dbg++; break;
25 case 'n': run=0; break;
26 }ARGEND
27
28 f = Bopen(*argv? *argv: "k.mx", OREAD);
29 if(f == 0) {
30 fprint(2, "sload: cannot open k.mx: %r\n");
31 exits("sload");
32 }
33 getdot();
34 while((l = Brdline(f, '\n')) != 0) {
35 l[Blinelen(f)-1] = '\r';
36 stuffbym(l, Blinelen(f), 16);
37 getdot();
38 if(++p % 25 == 0)
39 write(2, ".", 1);
40 }
41 exits(0);
42}
43
44static void
45stuffbym(char *l, int n, int m)
46{
47 int nr, ns;
48
49 while(n > 0) {
50 ns = n;
51 if(ns > m)
52 ns = m;
53 write(1, l, ns);
54 l += ns;
55 n -= ns;
56 }
57}
58
59static void
60getdot(void)
61{
62 char c;
63
64 for(;;){
65 if(read(0, &c, 1) != 1)
66 exits("bang");
67 write(2, &c, 1);
68 if(c == '.')
69 break;
70 }
71}
os/boot/mpc/squeeze.h+34−0
@@ -0,0 +1,34 @@
1
2/*
3 * squeezed file format:
4 * Sqhdr
5 * original Exec header
6 * two Squeeze tables
7 * squeezed segment
8 * unsqueezed segment, if any
9 */
10#define SQMAGIC (ulong)0xFEEF0F1E
11
12typedef struct Sqhdr Sqhdr;
13struct Sqhdr {
14 uchar magic[4]; /* SQMAGIC */
15 uchar text[4]; /* squeezed length of text (excluding tables) */
16 uchar data[4]; /* squeezed length of data (excluding tables) */
17 uchar asis[4]; /* length of unsqueezed segment */
18 uchar toptxt[4]; /* value for 0 encoding in text */
19 uchar topdat[4]; /* value for 0 encoding in data */
20 uchar sum[4]; /* simple checksum of unsqueezed data */
21 uchar flags[4];
22};
23#define SQHDRLEN (8*4)
24
25/*
26 * certain power instruction types are rearranged by sqz
27 * so as to move the variable part of the instruction word to the
28 * low order bits. note that the mapping is its own inverse.
29 */
30#define QREMAP(X)\
31 switch((X)>>26){\
32 case 19: case 31: case 59: case 63:\
33 (X) = (((X) & 0xFC00F801) | (((X)>>15)&0x7FE) | (((X)&0x7FE)<<15));\
34 }
os/boot/mpc/trap.c+233−0
@@ -0,0 +1,233 @@
1#include "boot.h"
2
3enum
4{
5 Maxhandler= 32+16, /* max number of interrupt handlers */
6};
7
8typedef struct Handler Handler;
9struct Handler
10{
11 void (*r)(Ureg*, void*);
12 void *arg;
13 Handler *next;
14 int edge;
15};
16
17struct
18{
19 Handler *ivec[128];
20 Handler h[Maxhandler];
21 int free;
22} halloc;
23
24char *excname[] = {
25 "reserved 0",
26 "system reset",
27 "machine check",
28 "data access",
29 "instruction access",
30 "external interrupt",
31 "alignment",
32 "program exception",
33 "floating-point unavailable",
34 "decrementer",
35 "reserved A",
36 "reserved B",
37 "system call",
38 "trace trap",
39 "floating point assist",
40 "reserved F",
41 "software emulation",
42 "ITLB miss",
43 "DTLB miss",
44 "ITLB error",
45 "DTLB error",
46};
47
48char *regname[]={
49 "CAUSE", "SRR1",
50 "PC", "GOK",
51 "LR", "CR",
52 "XER", "CTR",
53 "R0", "R1",
54 "R2", "R3",
55 "R4", "R5",
56 "R6", "R7",
57 "R8", "R9",
58 "R10", "R11",
59 "R12", "R13",
60 "R14", "R15",
61 "R16", "R17",
62 "R18", "R19",
63 "R20", "R21",
64 "R22", "R23",
65 "R24", "R25",
66 "R26", "R27",
67 "R28", "R29",
68 "R30", "R31",
69};
70
71static void intr(Ureg*);
72
73void
74sethvec(int v, void (*r)(void))
75{
76 ulong *vp, pa, o;
77
78 if((ulong)r & 3)
79 panic("sethvec");
80 vp = (ulong*)KADDR(v);
81 vp[0] = 0x7c1043a6; /* MOVW R0, SPR(SPRG0) */
82 vp[1] = 0x7c0802a6; /* MOVW LR, R0 */
83 vp[2] = 0x7c1243a6; /* MOVW R0, SPR(SPRG2) */
84 pa = PADDR(r);
85 o = pa >> 25;
86 if(o != 0 && o != 0x7F){
87 /* a branch too far: running from ROM */
88 vp[3] = (15<<26)|(pa>>16); /* MOVW $r&~0xFFFF, R0 */
89 vp[4] = (24<<26)|(pa&0xFFFF); /* OR $r&0xFFFF, R0 */
90 vp[5] = 0x7c0803a6; /* MOVW R0, LR */
91 vp[6] = 0x4e800021; /* BL (LR) */
92 }else
93 vp[3] = (18<<26)|(pa&0x3FFFFFC)|3; /* bla */
94}
95
96#define LEV(n) (((n)<<1)|1)
97#define IRQ(n) (((n)<<1)|0)
98
99void
100setvec(int v, void (*r)(Ureg*, void*), void *arg)
101{
102 Handler *h;
103 IMM *io;
104
105 if(halloc.free >= Maxhandler)
106 panic("out of interrupt handlers");
107 v -= VectorPIC;
108 h = &halloc.h[halloc.free++];
109 h->next = halloc.ivec[v];
110 h->r = r;
111 h->arg = arg;
112 halloc.ivec[v] = h;
113
114 /*
115 * enable corresponding interrupt in SIU/CPM
116 */
117
118 io = m->iomem;
119 if(v >= VectorCPIC){
120 v -= VectorCPIC;
121 io->cimr |= 1<<(v&0x1F);
122 }
123 else if(v >= VectorIRQ)
124 io->simask |= 1<<(31-IRQ(v&7));
125 else
126 io->simask |= 1<<(31-LEV(v));
127}
128
129void
130trapinit(void)
131{
132 int i;
133 IMM *io;
134
135 io = m->iomem;
136 io->sypcr &= ~(3<<2); /* disable watchdog (821/823) */
137 io->simask = 0; /* mask all */
138 io->siel = ~0; /* edge sensitive, wake on all */
139 io->cicr = 0; /* disable CPM interrupts */
140 io->cipr = ~0; /* clear all interrupts */
141 io->cimr = 0; /* mask all events */
142 io->cicr = (0xE1<<16)|(CPIClevel<<13)|(0x1F<<8);
143 io->cicr |= 1 << 7; /* enable */
144 io->tbscrk = KEEP_ALIVE_KEY;
145 io->tbscr = 1; /* TBE */
146 io->simask |= 1<<(31-LEV(CPIClevel)); /* CPM's level */
147 io->tbk = KEEP_ALIVE_KEY;
148 eieio();
149 putdec(~0);
150
151 /*
152 * set all exceptions to trap
153 */
154 for(i = 0x0; i < 0x3000; i += 0x100)
155 sethvec(i, exception);
156}
157
158void
159dumpregs(Ureg *ur)
160{
161 int i;
162 ulong *l;
163 l = &ur->cause;
164 for(i=0; i<sizeof regname/sizeof(char*); i+=2, l+=2)
165 print("%s\t%.8lux\t%s\t%.8lux\n", regname[i], l[0], regname[i+1], l[1]);
166}
167
168void
169trap(Ureg *ur)
170{
171 int c;
172
173 c = ur->cause >> 8;
174 switch(c){
175 default:
176 {extern int predawn; predawn = 1;}
177 if(c < 0 || c >= nelem(excname))
178 print("exception/interrupt #%x\n", c);
179 else
180 print("exception %s\n", excname[c]);
181 dumpregs(ur);
182 /* spllo(); */
183 print("^P to reset\n");
184 for(;;)
185 ;
186
187 case 0x09: /* decrementer */
188 clockintr(ur, 0);
189 return;
190
191 case 0x05: /* external interrupt */
192 intr(ur);
193 break;
194 }
195}
196
197static void
198intr(Ureg *ur)
199{
200 int b, v;
201 Handler *h;
202 IMM *io;
203
204 io = m->iomem;
205 b = io->sivec>>2;
206 v = b>>1;
207 if(b & 1) {
208 if(v == CPIClevel){
209 io->civr = 1;
210 eieio();
211 v = VectorCPIC+(io->civr>>11);
212 }
213 }else
214 v += VectorIRQ;
215 h = halloc.ivec[v];
216 if(h == nil){
217 for(;;)
218 ;
219 //print("unknown interrupt %d pc=0x%lux\n", v, ur->pc);
220 return;
221 }
222 if(h->edge)
223 io->sipend |= 1<<(31-b);
224 /*
225 * call the interrupt handlers
226 */
227 do {
228 (*h->r)(ur, h->arg);
229 h = h->next;
230 } while(h != nil);
231 if(v >= VectorCPIC)
232 io->cisr |= 1<<(v-VectorCPIC);
233}
os/boot/mpc/uartboot.c+189−0
@@ -0,0 +1,189 @@
1#include "boot.h"
2
3/*
4 * this doesn't yet use the crc
5 */
6
7typedef struct Uboot Uboot;
8struct Uboot {
9 Queue* iq;
10 Block* partial;
11 ulong csum;
12 long bno;
13 uchar buf[64];
14 int nleft;
15 int ntimeout;
16};
17
18static Uboot uboot;
19ulong crc32(void *buf, int n, ulong crc);
20
21static void
22uartbrecv(uchar *p, int n)
23{
24 Uboot *ub;
25 Block *b;
26
27 ub = &uboot;
28 if(n > 0 && ub->iq != nil){
29 b = iallocb(n);
30 memmove(b->wp, p, n);
31 b->wp += n;
32 qbwrite(ub->iq, b);
33 }
34}
35
36int
37uartinit(void)
38{
39 return 1<<0;
40}
41
42Partition*
43setuartpart(int, char *s)
44{
45 static Partition pp[1];
46
47 if(strcmp(s, "boot") != 0 && strcmp(s, "disk") != 0)
48 return 0;
49 pp[0].start = 0;
50 pp[0].end = 2*1024*1024;
51 strcpy(pp[0].name, "boot");
52 return pp;
53}
54
55long
56uartseek(int, long)
57{
58 /* start the boot */
59 if(uboot.iq == nil)
60 uboot.iq = qopen(64*1024, 0, 0, 0);
61 if(uboot.partial){
62 freeb(uboot.partial);
63 uboot.partial = 0;
64 }
65 print("uart: start transmission\n");
66 uartsetboot(uartbrecv);
67 uboot.csum = ~0;
68 uboot.bno = 0;
69 uboot.nleft = 0;
70 uboot.ntimeout = 0;
71 return 0;
72}
73
74static long
75uartreadn(void *buf, int nb)
76{
77 ulong start;
78 Uboot *ub;
79 int l;
80 Block *b;
81 uchar *p;
82
83 p = buf;
84 ub = &uboot;
85 start = m->ticks;
86 while(nb > 0){
87 b = ub->partial;
88 ub->partial = nil;
89 if(b == nil){
90 ub->ntimeout = 0;
91 while((b = qget(ub->iq)) == 0){
92 if(TK2MS(m->ticks - start) >= 15*1000){
93 if(++ub->ntimeout >= 3){
94 print("uart: timeout\n");
95 return 0;
96 }
97 uartputs("n", 1);
98 }
99 }
100 }
101 l = BLEN(b);
102 if(l > nb)
103 l = nb;
104 memmove(p, b->rp, l);
105 b->rp += l;
106 if(b->rp >= b->wp)
107 freeb(b);
108 else
109 ub->partial = b;
110 nb -= l;
111 p += l;
112 }
113 return p-(uchar*)buf;
114}
115
116long
117uartread(int, void *buf, long n)
118{
119 uchar *p;
120 int l;
121 static uchar lbuf[64];
122
123 p = buf;
124 if((l = uboot.nleft) > 0){
125 if(l > n)
126 l = n;
127 uboot.nleft -= l;
128 memmove(p, uboot.buf, l);
129 p += l;
130 n -= l;
131 }
132 while(n > 0){
133 l = uartreadn(lbuf, sizeof(lbuf));
134 if(l < sizeof(lbuf))
135 return 0;
136 if(l > n){
137 uboot.nleft = l-n;
138 memmove(uboot.buf, lbuf+n, uboot.nleft);
139 l = n;
140 }
141 memmove(p, lbuf, l);
142 n -= l;
143 p += l;
144 uboot.bno++;
145 uartputs("y", 1);
146 }
147 return p-(uchar*)buf;
148}
149
150/*
151 * from Rob Warnock
152 */
153static ulong crc32tab[256]; /* initialised on first call to crc32 */
154
155enum {
156 CRC32POLY = 0x04c11db7 /* AUTODIN II, Ethernet, & FDDI */
157};
158
159/*
160 * Build auxiliary table for parallel byte-at-a-time CRC-32.
161 */
162static void
163initcrc32(void)
164{
165 int i, j;
166 ulong c;
167
168 for(i = 0; i < 256; i++) {
169 for(c = i << 24, j = 8; j > 0; j--)
170 if(c & (1<<31))
171 c = (c<<1) ^ CRC32POLY;
172 else
173 c <<= 1;
174 crc32tab[i] = c;
175 }
176}
177
178ulong
179crc32(void *buf, int n, ulong crc)
180{
181 uchar *p;
182
183 if(crc32tab[1] == 0)
184 initcrc32();
185 crc = ~crc;
186 for(p = buf; --n >= 0;)
187 crc = (crc << 8) ^ crc32tab[(crc >> 24) ^ *p++];
188 return ~crc;
189}
os/boot/mpc/ureg.h+43−0
@@ -0,0 +1,43 @@
1struct Ureg
2{
3 ulong cause;
4 union { ulong srr1; ulong status;};
5 ulong pc; /* SRR0 */
6 ulong pad;
7 ulong lr;
8 ulong cr;
9 ulong xer;
10 ulong ctr;
11 ulong r0;
12 union{ ulong r1; ulong sp; ulong usp; };
13 ulong r2;
14 ulong r3;
15 ulong r4;
16 ulong r5;
17 ulong r6;
18 ulong r7;
19 ulong r8;
20 ulong r9;
21 ulong r10;
22 ulong r11;
23 ulong r12;
24 ulong r13;
25 ulong r14;
26 ulong r15;
27 ulong r16;
28 ulong r17;
29 ulong r18;
30 ulong r19;
31 ulong r20;
32 ulong r21;
33 ulong r22;
34 ulong r23;
35 ulong r24;
36 ulong r25;
37 ulong r26;
38 ulong r27;
39 ulong r28;
40 ulong r29;
41 ulong r30;
42 ulong r31;
43};
os/boot/mpc/zqs.c+234−0
@@ -0,0 +1,234 @@
1#include "boot.h"
2#include "squeeze.h"
3
4/*
5 * for details of `unsqueeze' see:
6 *
7 * %A Mark Taunton
8 * %T Compressed Executables: An Exercise in Thinking Small
9 * %P 385-404
10 * %I USENIX
11 * %B USENIX Conference Proceedings
12 * %D Summer 1991
13 * %C Nashville, TN
14 *
15 * several of the unimplemented improvements described in the paper
16 * have been implemented here
17 *
18 * there is a further transformation on the powerpc (QFLAG!=0) to shuffle bits
19 * in certain instructions so as to push the fixed bits to the top of the word.
20 */
21
22#define EXECHDRLEN (8*4)
23
24typedef struct Squeeze Squeeze;
25struct Squeeze {
26 int n;
27 ulong tab[7*256];
28};
29
30#define GET4(p) (((((((p)[0]<<8)|(p)[1])<<8)|(p)[2])<<8)|(p)[3])
31
32/*
33 * for speed of unsqueezing from Flash, certain checks are
34 * not done inside the loop (as they would be in the unsqueeze program zqs),
35 * but instead the checksum is expected to catch corrupted files.
36 * in fact the Squeeze array bounds can't be exceeded in practice
37 * because the tables are always full for a squeezed kernel.
38 */
39enum {
40 QFLAG = 1, /* invert powerpc-specific code transformation */
41 CHECK = 0, /* check precise bounds in Squeeze array (otherwise checksum detects error) */
42};
43
44static ulong chksum;
45static int rdtab(Block*, Squeeze*, int);
46static ulong* unsqueeze(ulong*, uchar*, uchar*, Squeeze*, Squeeze*, ulong);
47static uchar* unsqzseg(uchar*, Block*, long, long, char*);
48static Alarm* unsqzal;
49
50int
51issqueezed(uchar *b)
52{
53 return GET4(b) == SQMAGIC? GET4(b+SQHDRLEN): 0;
54}
55
56static void
57unsqzdot(Alarm*)
58{
59 unsqzal = alarm(500, unsqzdot, nil);
60 print(".");
61}
62
63long
64unsqueezef(Block *b, ulong *entryp)
65{
66 uchar *loada, *wp;
67 ulong toptxt, topdat, oldsum;
68 long asis, nst, nsd;
69 Sqhdr *sqh;
70 Exec *ex;
71
72 if(BLEN(b) < SQHDRLEN+EXECHDRLEN)
73 return -1;
74 sqh = (Sqhdr*)b->rp;
75 if(GET4(sqh->magic) != SQMAGIC)
76 return -1;
77 chksum = 0;
78 toptxt = GET4(sqh->toptxt);
79 topdat = GET4(sqh->topdat);
80 oldsum = GET4(sqh->sum);
81 asis = GET4(sqh->asis);
82 nst = GET4(sqh->text);
83 nsd = GET4(sqh->data);
84 b->rp += SQHDRLEN;
85 ex = (Exec*)b->rp;
86 if(GET4(ex->magic) != Q_MAGIC){
87 print("zqs: not powerPC executable\n");
88 return -1;
89 }
90 *entryp = GET4(ex->entry);
91 b->rp += EXECHDRLEN;
92 loada = KADDR(PADDR(*entryp));
93 wp = unsqzseg(loada, b, nst, toptxt, "text");
94 if(wp == nil){
95 print("zqs: format error\n");
96 return -1;
97 }
98 if(nsd){
99 wp = (uchar*)PGROUND((ulong)wp);
100 wp = unsqzseg(wp, b, nsd, topdat, "data");
101 if(wp == nil){
102 print("zqs: format error\n");
103 return -1;
104 }
105 }
106 if(asis){
107 memmove(wp, b->rp, asis);
108 wp += asis;
109 b->rp += asis;
110 }
111 if(chksum != oldsum){
112 print("\nsqueezed kernel: checksum error: %8.8lux need %8.8lux\n", chksum, oldsum);
113 return -1;
114 }
115 return wp-loada;
116}
117
118static uchar *
119unsqzseg(uchar *wp, Block *b, long ns, long top, char *what)
120{
121 static Squeeze sq3, sq4;
122
123 print("unpack %s %8.8lux %lud:", what, wp, ns);
124 if(ns == 0)
125 return wp;
126 if(rdtab(b, &sq3, 0) < 0)
127 return nil;
128 if(rdtab(b, &sq4, 8) < 0)
129 return nil;
130 if(BLEN(b) < ns){
131 print(" **size error\n");
132 return nil;
133 }
134 unsqzal = alarm(500, unsqzdot, nil);
135 wp = (uchar*)unsqueeze((ulong*)wp, b->rp, b->rp+ns, &sq3, &sq4, top);
136 cancel(unsqzal);
137 unsqzal = nil;
138 print("\n");
139 if(wp == nil){
140 print("zqs: corrupt squeezed data stream\n");
141 return nil;
142 }
143 b->rp += ns;
144 return wp;
145}
146
147static ulong*
148unsqueeze(ulong *wp, uchar *rp, uchar *ep, Squeeze *sq3, Squeeze *sq4, ulong top)
149{
150 ulong nx, csum;
151 int code, n;
152
153 if(QFLAG){
154 QREMAP(top); /* adjust top just once, outside the loop */
155 }
156 csum = chksum;
157 while(rp < ep){
158 /* no function calls within this loop for speed */
159 code = *rp;
160 rp++;
161 n = 0;
162 nx = code>>4;
163 do{
164 if(nx == 0){
165 nx = top;
166 }else{
167 if(nx==1){
168 nx = (((((rp[3]<<8)|rp[2])<<8)|rp[1])<<8)|rp[0];
169 rp += 4;
170 }else if(nx <= 8){ /* 2 to 8 */
171 nx = ((nx-2)<<8) | rp[0];
172 if(CHECK && nx >= sq4->n)
173 return nil; /* corrupted file */
174 nx = sq4->tab[nx] | rp[1];
175 rp += 2;
176 }else{ /* 9 to 15 */
177 nx = ((nx-9)<<8) | rp[0];
178 if(CHECK && nx >= sq3->n)
179 return nil; /* corrupted file */
180 nx = sq3->tab[nx];
181 rp++;
182 }
183 if(rp > ep)
184 return nil; /* corrupted file */
185 if(QFLAG){
186 QREMAP(nx);
187 }
188 }
189 *wp = nx;
190 wp++;
191 csum += nx;
192 nx = code & 0xF;
193 }while(++n == 1);
194 }
195 chksum = csum;
196 return wp;
197}
198
199static int
200rdtab(Block *b, Squeeze *sq, int shift)
201{
202 uchar *p, *ep;
203 ulong v, w;
204 int i;
205
206 if(BLEN(b) < 2)
207 return -1;
208 i = (b->rp[0]<<8) | b->rp[1];
209 if(1)
210 print(" T%d", i);
211 b->rp += 2;
212 if((i -= 2) > 0){
213 if(BLEN(b) < i)
214 return -1;
215 }
216 sq->n = 0;
217 p = b->rp;
218 ep = b->rp+i;
219 b->rp += i;
220 v = 0;
221 while(p < ep){
222 w = 0;
223 do{
224 if(p >= ep)
225 return -1;
226 w = (w<<7) | (*p & 0x7F);
227 }while(*p++ & 0x80);
228 v += w;
229 if(0)
230 print("%d %8.8lux %8.8lux\n", sq->n, v, w);
231 sq->tab[sq->n++] = v<<shift;
232 }
233 return 0;
234}
os/boot/pc/8250.c+308−0
@@ -0,0 +1,308 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7
8/*
9 * INS8250 uart
10 */
11enum
12{
13 /*
14 * register numbers
15 */
16 Data= 0, /* xmit/rcv buffer */
17 Iena= 1, /* interrupt enable */
18 Ircv= (1<<0), /* for char rcv'd */
19 Ixmt= (1<<1), /* for xmit buffer empty */
20 Irstat=(1<<2), /* for change in rcv'er status */
21 Imstat=(1<<3), /* for change in modem status */
22 Istat= 2, /* interrupt flag (read) */
23 Tctl= 2, /* test control (write) */
24 Format= 3, /* byte format */
25 Bits8= (3<<0), /* 8 bits/byte */
26 Stop2= (1<<2), /* 2 stop bits */
27 Pena= (1<<3), /* generate parity */
28 Peven= (1<<4), /* even parity */
29 Pforce=(1<<5), /* force parity */
30 Break= (1<<6), /* generate a break */
31 Dra= (1<<7), /* address the divisor */
32 Mctl= 4, /* modem control */
33 Dtr= (1<<0), /* data terminal ready */
34 Rts= (1<<1), /* request to send */
35 Ri= (1<<2), /* ring */
36 Inton= (1<<3), /* turn on interrupts */
37 Loop= (1<<4), /* loop back */
38 Lstat= 5, /* line status */
39 Inready=(1<<0), /* receive buffer full */
40 Oerror=(1<<1), /* receiver overrun */
41 Perror=(1<<2), /* receiver parity error */
42 Ferror=(1<<3), /* rcv framing error */
43 Outready=(1<<5), /* output buffer empty */
44 Mstat= 6, /* modem status */
45 Ctsc= (1<<0), /* clear to send changed */
46 Dsrc= (1<<1), /* data set ready changed */
47 Rire= (1<<2), /* rising edge of ring indicator */
48 Dcdc= (1<<3), /* data carrier detect changed */
49 Cts= (1<<4), /* complement of clear to send line */
50 Dsr= (1<<5), /* complement of data set ready line */
51 Ring= (1<<6), /* complement of ring indicator line */
52 Dcd= (1<<7), /* complement of data carrier detect line */
53 Scratch=7, /* scratchpad */
54 Dlsb= 0, /* divisor lsb */
55 Dmsb= 1, /* divisor msb */
56
57 Serial= 0,
58 Modem= 1,
59};
60
61typedef struct Uart Uart;
62struct Uart
63{
64 int port;
65 uchar sticky[8]; /* sticky write register values */
66 uchar txbusy;
67
68 void (*rx)(int); /* routine to take a received character */
69 int (*tx)(void); /* routine to get a character to transmit */
70
71 ulong frame;
72 ulong overrun;
73};
74
75static Uart com[2];
76static Uart* uart;
77
78#define UartFREQ 1843200
79
80#define uartwrreg(u,r,v) outb((u)->port + r, (u)->sticky[r] | (v))
81#define uartrdreg(u,r) inb((u)->port + r)
82
83/*
84 * set the baud rate by calculating and setting the baudrate
85 * generator constant. This will work with fairly non-standard
86 * baud rates.
87 */
88static void
89uartsetbaud(Uart *up, int rate)
90{
91 ulong brconst;
92
93 brconst = (UartFREQ+8*rate-1)/(16*rate);
94
95 uartwrreg(up, Format, Dra);
96 outb(up->port+Dmsb, (brconst>>8) & 0xff);
97 outb(up->port+Dlsb, brconst & 0xff);
98 uartwrreg(up, Format, 0);
99}
100
101/*
102 * toggle DTR
103 */
104static void
105uartdtr(Uart *up, int n)
106{
107 if(n)
108 up->sticky[Mctl] |= Dtr;
109 else
110 up->sticky[Mctl] &= ~Dtr;
111 uartwrreg(up, Mctl, 0);
112}
113
114/*
115 * toggle RTS
116 */
117static void
118uartrts(Uart *up, int n)
119{
120 if(n)
121 up->sticky[Mctl] |= Rts;
122 else
123 up->sticky[Mctl] &= ~Rts;
124 uartwrreg(up, Mctl, 0);
125}
126
127static void
128uartintr(Ureg*, void *arg)
129{
130 Uart *up;
131 int ch;
132 int s, l, loops;
133
134 up = arg;
135 for(loops = 0; loops < 1024; loops++){
136 s = uartrdreg(up, Istat);
137 switch(s & 0x3F){
138 case 6: /* receiver line status */
139 l = uartrdreg(up, Lstat);
140 if(l & Ferror)
141 up->frame++;
142 if(l & Oerror)
143 up->overrun++;
144 break;
145
146 case 4: /* received data available */
147 case 12:
148 ch = inb(up->port+Data);
149 if(up->rx)
150 (*up->rx)(ch);
151 break;
152
153 case 2: /* transmitter empty */
154 ch = -1;
155 if(up->tx)
156 ch = (*up->tx)();
157 if(ch != -1)
158 outb(up->port+Data, ch);
159 else
160 up->txbusy = 0;
161 break;
162
163 case 0: /* modem status */
164 uartrdreg(up, Mstat);
165 break;
166
167 default:
168 if(s&1)
169 return;
170 print("weird modem interrupt #%2.2ux\n", s);
171 break;
172 }
173 }
174 panic("uartintr: 0x%2.2ux\n", uartrdreg(up, Istat));
175}
176
177/*
178 * turn on a port's interrupts. set DTR and RTS
179 */
180static void
181uartenable(Uart *up)
182{
183 /*
184 * turn on interrupts
185 */
186 up->sticky[Iena] = 0;
187 if(up->tx)
188 up->sticky[Iena] |= Ixmt;
189 if(up->rx)
190 up->sticky[Iena] |= Ircv|Irstat;
191 uartwrreg(up, Iena, 0);
192
193 /*
194 * turn on DTR and RTS
195 */
196 uartdtr(up, 1);
197 uartrts(up, 1);
198}
199
200static void
201uartdisable(Uart* up)
202{
203 /*
204 * Disable interrupts.
205 */
206 up->sticky[Iena] = 0;
207 uartwrreg(up, Iena, 0);
208 uartdtr(up, 0);
209 uartrts(up, 0);
210}
211
212void
213uartspecial(int port, void (*rx)(int), int (*tx)(void), int baud)
214{
215 Uart *up;
216 int vector;
217
218 switch(port){
219 case 0:
220 port = 0x3F8;
221 vector = VectorUART0;
222 up = &com[0];
223 break;
224 case 1:
225 port = 0x2F8;
226 vector = VectorUART1;
227 up = &com[1];
228 break;
229 default:
230 return;
231 }
232
233 if(uart != nil && uart != up)
234 uartdisable(uart);
235 uart = up;
236
237 if(up->port == 0){
238 up->port = port;
239 setvec(vector, uartintr, up);
240 }
241
242 /*
243 * set rate to 9600 baud.
244 * 8 bits/character.
245 * 1 stop bit.
246 * interrupts enabled.
247 */
248 uartsetbaud(up, 9600);
249 up->sticky[Format] = Bits8;
250 uartwrreg(up, Format, 0);
251 up->sticky[Mctl] |= Inton;
252 uartwrreg(up, Mctl, 0x0);
253
254 up->rx = rx;
255 up->tx = tx;
256 uartenable(up);
257 if(baud)
258 uartsetbaud(up, baud);
259}
260
261void
262uartputc(int c)
263{
264 int i;
265 Uart *up;
266
267 if((up = uart) == nil)
268 return;
269 for(i = 0; i < 100; i++){
270 if(uartrdreg(up, Lstat) & Outready)
271 break;
272 delay(1);
273 }
274 outb(up->port+Data, c);
275}
276
277void
278uartputs(IOQ *q, char *s, int n)
279{
280 Uart *up;
281 int c, x;
282
283 if((up = uart) == nil)
284 return;
285 while(n--){
286 if(*s == '\n')
287 q->putc(q, '\r');
288 q->putc(q, *s++);
289 }
290 x = splhi();
291 if(up->txbusy == 0 && (c = q->getc(q)) != -1){
292 uartputc(c & 0xFF);
293 up->txbusy = 1;
294 }
295 splx(x);
296}
297
298void
299uartdrain(void)
300{
301 Uart *up;
302 int timeo;
303
304 if((up = uart) == nil)
305 return;
306 for(timeo = 0; timeo < 10000 && up->txbusy; timeo++)
307 delay(1);
308}
os/boot/pc/LICENCE+237−0
@@ -0,0 +1,237 @@
1Lucent Public License Version 1.02
2
3THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS PUBLIC
4LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE
5PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
6
71. DEFINITIONS
8
9"Contribution" means:
10
11 a. in the case of Lucent Technologies Inc. ("LUCENT"), the Original
12 Program, and
13 b. in the case of each Contributor,
14
15 i. changes to the Program, and
16 ii. additions to the Program;
17
18 where such changes and/or additions to the Program were added to the
19 Program by such Contributor itself or anyone acting on such
20 Contributor's behalf, and the Contributor explicitly consents, in
21 accordance with Section 3C, to characterization of the changes and/or
22 additions as Contributions.
23
24"Contributor" means LUCENT and any other entity that has Contributed a
25Contribution to the Program.
26
27"Distributor" means a Recipient that distributes the Program,
28modifications to the Program, or any part thereof.
29
30"Licensed Patents" mean patent claims licensable by a Contributor
31which are necessarily infringed by the use or sale of its Contribution
32alone or when combined with the Program.
33
34"Original Program" means the original version of the software
35accompanying this Agreement as released by LUCENT, including source
36code, object code and documentation, if any.
37
38"Program" means the Original Program and Contributions or any part
39thereof
40
41"Recipient" means anyone who receives the Program under this
42Agreement, including all Contributors.
43
442. GRANT OF RIGHTS
45
46 a. Subject to the terms of this Agreement, each Contributor hereby
47 grants Recipient a non-exclusive, worldwide, royalty-free copyright
48 license to reproduce, prepare derivative works of, publicly display,
49 publicly perform, distribute and sublicense the Contribution of such
50 Contributor, if any, and such derivative works, in source code and
51 object code form.
52
53 b. Subject to the terms of this Agreement, each Contributor hereby
54 grants Recipient a non-exclusive, worldwide, royalty-free patent
55 license under Licensed Patents to make, use, sell, offer to sell,
56 import and otherwise transfer the Contribution of such Contributor, if
57 any, in source code and object code form. The patent license granted
58 by a Contributor shall also apply to the combination of the
59 Contribution of that Contributor and the Program if, at the time the
60 Contribution is added by the Contributor, such addition of the
61 Contribution causes such combination to be covered by the Licensed
62 Patents. The patent license granted by a Contributor shall not apply
63 to (i) any other combinations which include the Contribution, nor to
64 (ii) Contributions of other Contributors. No hardware per se is
65 licensed hereunder.
66
67 c. Recipient understands that although each Contributor grants the
68 licenses to its Contributions set forth herein, no assurances are
69 provided by any Contributor that the Program does not infringe the
70 patent or other intellectual property rights of any other entity. Each
71 Contributor disclaims any liability to Recipient for claims brought by
72 any other entity based on infringement of intellectual property rights
73 or otherwise. As a condition to exercising the rights and licenses
74 granted hereunder, each Recipient hereby assumes sole responsibility
75 to secure any other intellectual property rights needed, if any. For
76 example, if a third party patent license is required to allow
77 Recipient to distribute the Program, it is Recipient's responsibility
78 to acquire that license before distributing the Program.
79
80 d. Each Contributor represents that to its knowledge it has sufficient
81 copyright rights in its Contribution, if any, to grant the copyright
82 license set forth in this Agreement.
83
843. REQUIREMENTS
85
86A. Distributor may choose to distribute the Program in any form under
87this Agreement or under its own license agreement, provided that:
88
89 a. it complies with the terms and conditions of this Agreement;
90
91 b. if the Program is distributed in source code or other tangible
92 form, a copy of this Agreement or Distributor's own license agreement
93 is included with each copy of the Program; and
94
95 c. if distributed under Distributor's own license agreement, such
96 license agreement:
97
98 i. effectively disclaims on behalf of all Contributors all warranties
99 and conditions, express and implied, including warranties or
100 conditions of title and non-infringement, and implied warranties or
101 conditions of merchantability and fitness for a particular purpose;
102 ii. effectively excludes on behalf of all Contributors all liability
103 for damages, including direct, indirect, special, incidental and
104 consequential damages, such as lost profits; and
105 iii. states that any provisions which differ from this Agreement are
106 offered by that Contributor alone and not by any other party.
107
108B. Each Distributor must include the following in a conspicuous
109 location in the Program:
110
111 Copyright (C) 2003, Lucent Technologies Inc. and others. All Rights
112 Reserved.
113
114C. In addition, each Contributor must identify itself as the
115originator of its Contribution in a manner that reasonably allows
116subsequent Recipients to identify the originator of the Contribution.
117Also, each Contributor must agree that the additions and/or changes
118are intended to be a Contribution. Once a Contribution is contributed,
119it may not thereafter be revoked.
120
1214. COMMERCIAL DISTRIBUTION
122
123Commercial distributors of software may accept certain
124responsibilities with respect to end users, business partners and the
125like. While this license is intended to facilitate the commercial use
126of the Program, the Distributor who includes the Program in a
127commercial product offering should do so in a manner which does not
128create potential liability for Contributors. Therefore, if a
129Distributor includes the Program in a commercial product offering,
130such Distributor ("Commercial Distributor") hereby agrees to defend
131and indemnify every Contributor ("Indemnified Contributor") against
132any losses, damages and costs (collectively"Losses") arising from
133claims, lawsuits and other legal actions brought by a third party
134against the Indemnified Contributor to the extent caused by the acts
135or omissions of such Commercial Distributor in connection with its
136distribution of the Program in a commercial product offering. The
137obligations in this section do not apply to any claims or Losses
138relating to any actual or alleged intellectual property infringement.
139In order to qualify, an Indemnified Contributor must: a) promptly
140notify the Commercial Distributor in writing of such claim, and b)
141allow the Commercial Distributor to control, and cooperate with the
142Commercial Distributor in, the defense and any related settlement
143negotiations. The Indemnified Contributor may participate in any such
144claim at its own expense.
145
146For example, a Distributor might include the Program in a commercial
147product offering, Product X. That Distributor is then a Commercial
148Distributor. If that Commercial Distributor then makes performance
149claims, or offers warranties related to Product X, those performance
150claims and warranties are such Commercial Distributor's responsibility
151alone. Under this section, the Commercial Distributor would have to
152defend claims against the Contributors related to those performance
153claims and warranties, and if a court requires any Contributor to pay
154any damages as a result, the Commercial Distributor must pay those
155damages.
156
1575. NO WARRANTY
158
159EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
160PROVIDED ON AN"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
161KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
162WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
163OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
164responsible for determining the appropriateness of using and
165distributing the Program and assumes all risks associated with its
166exercise of rights under this Agreement, including but not limited to
167the risks and costs of program errors, compliance with applicable
168laws, damage to or loss of data, programs or equipment, and
169unavailability or interruption of operations.
170
1716. DISCLAIMER OF LIABILITY
172
173EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
174ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
175INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
176WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
177LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
178NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
179DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
180HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
181
1827. EXPORT CONTROL
183
184Recipient agrees that Recipient alone is responsible for compliance
185with the United States export administration regulations (and the
186export control laws and regulation of any other countries).
187
1888. GENERAL
189
190If any provision of this Agreement is invalid or unenforceable under
191applicable law, it shall not affect the validity or enforceability of
192the remainder of the terms of this Agreement, and without further
193action by the parties hereto, such provision shall be reformed to the
194minimum extent necessary to make such provision valid and enforceable.
195
196If Recipient institutes patent litigation against a Contributor with
197respect to a patent applicable to software (including a cross-claim or
198counterclaim in a lawsuit), then any patent licenses granted by that
199Contributor to such Recipient under this Agreement shall terminate as
200of the date such litigation is filed. In addition, if Recipient
201institutes patent litigation against any entity (including a
202cross-claim or counterclaim in a lawsuit) alleging that the Program
203itself (excluding combinations of the Program with other software or
204hardware) infringes such Recipient's patent(s), then such Recipient's
205rights granted under Section 2(b) shall terminate as of the date such
206litigation is filed.
207
208All Recipient's rights under this Agreement shall terminate if it
209fails to comply with any of the material terms or conditions of this
210Agreement and does not cure such failure in a reasonable period of
211time after becoming aware of such noncompliance. If all Recipient's
212rights under this Agreement terminate, Recipient agrees to cease use
213and distribution of the Program as soon as reasonably practicable.
214However, Recipient's obligations under this Agreement and any licenses
215granted by Recipient relating to the Program shall continue and
216survive.
217
218LUCENT may publish new versions (including revisions) of this
219Agreement from time to time. Each new version of the Agreement will be
220given a distinguishing version number. The Program (including
221Contributions) may always be distributed subject to the version of the
222Agreement under which it was received. In addition, after a new
223version of the Agreement is published, Contributor may elect to
224distribute the Program (including its Contributions) under the new
225version. No one other than LUCENT has the right to modify this
226Agreement. Except as expressly stated in Sections 2(a) and 2(b) above,
227Recipient receives no rights or licenses to the intellectual property
228of any Contributor under this Agreement, whether expressly, by
229implication, estoppel or otherwise. All rights in the Program not
230expressly granted under this Agreement are reserved.
231
232This Agreement is governed by the laws of the State of New York and
233the intellectual property laws of the United States of America. No
234party to this Agreement will bring a legal action under this Agreement
235more than one year after the cause of action arose. Each party waives
236its rights to a jury trial in any resulting litigation.
237
os/boot/pc/NOTICE+4−0
@@ -0,0 +1,4 @@
1Copyright © 1995-2006 Lucent Technologies Inc. and others. All rights reserved.
2Revisions for use with Inferno © 2003-2006 Vita Nuova Holdings Limited.
3
4This software is provided under the terms of the Lucent Public License, Version 1.02.
os/boot/pc/alarm.c+123−0
@@ -0,0 +1,123 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7#define MAXALARM 10
8
9Alarm alarmtab[MAXALARM];
10
11/*
12 * Insert new into list after where
13 */
14void
15insert(List **head, List *where, List *new)
16{
17 if(where == 0){
18 new->next = *head;
19 *head = new;
20 }else{
21 new->next = where->next;
22 where->next = new;
23 }
24
25}
26
27/*
28 * Delete old from list. where->next is known to be old.
29 */
30void
31delete(List **head, List *where, List *old)
32{
33 if(where == 0){
34 *head = old->next;
35 return;
36 }
37 where->next = old->next;
38}
39
40Alarm*
41newalarm(void)
42{
43 int i;
44 Alarm *a;
45
46 for(i=0,a=alarmtab; i < nelem(alarmtab); i++,a++)
47 if(a->busy==0 && a->f==0){
48 a->f = 0;
49 a->arg = 0;
50 a->busy = 1;
51 return a;
52 }
53 panic("newalarm");
54 return 0; /* not reached */
55}
56
57Alarm*
58alarm(int ms, void (*f)(Alarm*), void *arg)
59{
60 Alarm *a, *w, *pw;
61 ulong s;
62
63 if(ms < 0)
64 ms = 0;
65 s = splhi();
66 a = newalarm();
67 a->dt = MS2TK(ms);
68 a->f = f;
69 a->arg = arg;
70 pw = 0;
71 for(w=m->alarm; w; pw=w, w=w->next){
72 if(w->dt <= a->dt){
73 a->dt -= w->dt;
74 continue;
75 }
76 w->dt -= a->dt;
77 break;
78 }
79 insert(&m->alarm, pw, a);
80 splx(s);
81 return a;
82}
83
84void
85cancel(Alarm *a)
86{
87 a->f = 0;
88}
89
90void
91alarminit(void)
92{
93}
94
95#define NA 10 /* alarms per clock tick */
96void
97checkalarms(void)
98{
99 int i, n, s;
100 Alarm *a;
101 void (*f)(Alarm*);
102 Alarm *alist[NA];
103
104 s = splhi();
105 a = m->alarm;
106 if(a){
107 for(n=0; a && a->dt<=0 && n<NA; n++){
108 alist[n] = a;
109 delete(&m->alarm, 0, a);
110 a = m->alarm;
111 }
112 if(a)
113 a->dt--;
114
115 for(i = 0; i < n; i++){
116 f = alist[i]->f; /* avoid race with cancel */
117 if(f)
118 (*f)(alist[i]);
119 alist[i]->busy = 0;
120 }
121 }
122 splx(s);
123}
os/boot/pc/apm.c+16−0
@@ -0,0 +1,16 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7
8Apminfo apm;
9
10void
11apminit(void)
12{
13 if(getconf("apm0") && apm.haveinfo)
14 changeconf("apm0=ax=%x ebx=%x cx=%x dx=%x di=%x esi=%x\n",
15 apm.ax, apm.ebx, apm.cx, apm.dx, apm.di, apm.esi);
16}
os/boot/pc/bcom.c+460−0
@@ -0,0 +1,460 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7
8#include "fs.h"
9
10Type types[] = {
11 { Tfloppy,
12 Fini|Ffs,
13 floppyinit, floppyinitdev,
14 floppygetfspart, 0, floppyboot,
15 },
16 { Tsd,
17 Fini|Ffs,
18 sdinit, sdinitdev,
19 sdgetfspart, sdaddconf, sdboot,
20 },
21 { Tnil,
22 0,
23 0, 0,
24 0, 0, 0,
25 },
26};
27
28#include "sd.h"
29
30extern SDifc sdataifc;
31extern SDifc sdmylexifc;
32extern SDifc sd53c8xxifc;
33SDifc* sdifc[] = {
34 &sdataifc,
35// &sdmylexifc,
36// &sd53c8xxifc,
37 nil,
38};
39
40typedef struct Mode Mode;
41
42enum {
43 Maxdev = 7,
44 Dany = -1,
45 Nmedia = 16,
46 Nini = 10,
47};
48
49enum { /* mode */
50 Mauto = 0x00,
51 Mlocal = 0x01,
52 Manual = 0x02,
53 NMode = 0x03,
54};
55
56typedef struct Medium Medium;
57struct Medium {
58 Type* type;
59 int flag;
60 int dev;
61 char name[NAMELEN];
62 Fs* inifs;
63
64 Medium* next;
65};
66
67typedef struct Mode {
68 char* name;
69 int mode;
70} Mode;
71
72static Medium media[Nmedia];
73static Medium *curmedium = media;
74
75static Mode modes[NMode+1] = {
76 [Mauto] { "auto", Mauto, },
77 [Mlocal] { "local", Mlocal, },
78 [Manual] { "manual", Manual, },
79};
80
81char *defaultpartition = "new";
82
83static Medium*
84parse(char *line, char **file)
85{
86 char *p;
87 Type *tp;
88 Medium *mp;
89
90 if(p = strchr(line, '!')) {
91 *p++ = 0;
92 *file = p;
93 } else
94 *file = "";
95
96 for(tp = types; tp->type != Tnil; tp++)
97 for(mp = tp->media; mp; mp = mp->next)
98 if(strcmp(mp->name, line) == 0)
99 return mp;
100 return nil;
101}
102
103static int
104boot(Medium *mp, char *file)
105{
106 static Boot b;
107
108 memset(&b, 0, sizeof b);
109 b.state = INIT9LOAD;
110
111// sprint(BOOTLINE, "%s!%s", mp->name, file);
112 return (*mp->type->boot)(mp->dev, file, &b);
113}
114
115static Medium*
116allocm(Type *tp)
117{
118 Medium **l;
119
120 if(curmedium >= &media[Nmedia])
121 return 0;
122
123 for(l = &tp->media; *l; l = &(*l)->next)
124 ;
125 *l = curmedium++;
126 return *l;
127}
128
129char *parts[] = { "dos", "9fat", "fs", 0 };
130
131Medium*
132probe(int type, int flag, int dev)
133{
134 Type *tp;
135 int i;
136 Medium *mp;
137
138 for(tp = types; tp->type != Tnil; tp++){
139 if(type != Tany && type != tp->type)
140 continue;
141
142 if(flag != Fnone){
143 for(mp = tp->media; mp; mp = mp->next){
144 if((flag & mp->flag) && (dev == Dany || dev == mp->dev))
145 return mp;
146 }
147 }
148
149 if((tp->flag & Fprobe) == 0){
150 tp->flag |= Fprobe;
151 tp->mask = (*tp->init)();
152 }
153
154 for(i = 0; tp->mask; i++){
155 if((tp->mask & (1<<i)) == 0)
156 continue;
157 tp->mask &= ~(1<<i);
158
159 if((mp = allocm(tp)) == 0)
160 continue;
161
162 mp->dev = i;
163 mp->flag = tp->flag;
164 mp->type = tp;
165 (*tp->initdev)(i, mp->name);
166
167 if((flag & mp->flag) && (dev == Dany || dev == i))
168 return mp;
169 }
170 }
171
172 return 0;
173}
174
175extern int loopconst;
176void
177main(void)
178{
179 Medium *mp;
180 int flag;
181 char def[2*NAMELEN], line[80], *p, *file;
182 Type *tp;
183
184 i8042a20();
185 memset(m, 0, sizeof(Mach));
186 trapinit();
187 clockinit();
188 alarminit();
189 spllo();
190
191 kbdinit();
192
193 if((ulong)&end > (KZERO|(640*1024)))
194 panic("i'm too big");
195
196 /*
197 * If there were any arguments, MS-DOS leaves a character
198 * count followed by the arguments in the runtime header.
199 * Step over the leading space.
200 */
201 p = (char*)0x80080080;
202 if(p[0]){
203 p[p[0]+1] = 0;
204 p += 2;
205 }
206 else
207 p = 0;
208
209 /*
210 * Advance command line to first option, if any
211 */
212 if(p) {
213 while(*p==' ' || *p=='\t')
214 p++;
215 if(*p == 0)
216 p = nil;
217 }
218
219 /*
220 * Probe everything, to collect device names.
221 */
222 probe(Tany, Fnone, Dany);
223
224 if(p != 0) {
225 if((mp = parse(p, &file)) == nil) {
226 print("bad loadfile syntax: %s\n", p);
227 goto done;
228 }
229 boot(mp, file);
230 }
231
232done:
233 flag = 0;
234 for(tp = types; tp->type != Tnil; tp++){
235 for(mp = tp->media; mp; mp = mp->next){
236 if(flag == 0){
237 flag = 1;
238 print("Load devices:");
239 }
240 print(" %s", mp->name);
241 }
242 }
243 if(flag)
244 print("\n");
245
246 for(;;){
247 if(getstr("load from", line, sizeof(line), nil, 0) >= 0)
248 if(mp = parse(line, &file))
249 boot(mp, file);
250 def[0] = 0;
251 }
252}
253
254int
255getfields(char *lp, char **fields, int n, char sep)
256{
257 int i;
258
259 for(i = 0; lp && *lp && i < n; i++){
260 while(*lp == sep)
261 *lp++ = 0;
262 if(*lp == 0)
263 break;
264 fields[i] = lp;
265 while(*lp && *lp != sep){
266 if(*lp == '\\' && *(lp+1) == '\n')
267 *lp++ = ' ';
268 lp++;
269 }
270 }
271 return i;
272}
273
274int
275cistrcmp(char *a, char *b)
276{
277 int ac, bc;
278
279 for(;;){
280 ac = *a++;
281 bc = *b++;
282
283 if(ac >= 'A' && ac <= 'Z')
284 ac = 'a' + (ac - 'A');
285 if(bc >= 'A' && bc <= 'Z')
286 bc = 'a' + (bc - 'A');
287 ac -= bc;
288 if(ac)
289 return ac;
290 if(bc == 0)
291 break;
292 }
293 return 0;
294}
295
296int
297cistrncmp(char *a, char *b, int n)
298{
299 unsigned ac, bc;
300
301 while(n > 0){
302 ac = *a++;
303 bc = *b++;
304 n--;
305
306 if(ac >= 'A' && ac <= 'Z')
307 ac = 'a' + (ac - 'A');
308 if(bc >= 'A' && bc <= 'Z')
309 bc = 'a' + (bc - 'A');
310
311 ac -= bc;
312 if(ac)
313 return ac;
314 if(bc == 0)
315 break;
316 }
317
318 return 0;
319}
320
321void*
322ialloc(ulong n, int align)
323{
324
325 static ulong palloc;
326 ulong p;
327 int a;
328
329 if(palloc == 0)
330 palloc = 3*1024*1024;
331
332 p = palloc;
333 if(align <= 0)
334 align = 4;
335 if(a = n % align)
336 n += align - a;
337 if(a = p % align)
338 p += align - a;
339
340 palloc = p+n;
341
342 return memset((void*)(p|KZERO), 0, n);
343}
344
345void*
346xspanalloc(ulong size, int align, ulong span)
347{
348 ulong a, v;
349
350 a = (ulong)ialloc(size+align+span, 0);
351
352 if(span > 2)
353 v = (a + span) & ~(span-1);
354 else
355 v = a;
356
357 if(align > 1)
358 v = (v + align) & ~(align-1);
359
360 return (void*)v;
361}
362
363static Block *allocbp;
364
365Block*
366allocb(int size)
367{
368 Block *bp, **lbp;
369 ulong addr;
370
371 lbp = &allocbp;
372 for(bp = *lbp; bp; bp = bp->next){
373 if((bp->lim - bp->base) >= size){
374 *lbp = bp->next;
375 break;
376 }
377 lbp = &bp->next;
378 }
379 if(bp == 0){
380 bp = ialloc(sizeof(Block)+size+64, 0);
381 addr = (ulong)bp;
382 addr = ROUNDUP(addr + sizeof(Block), 8);
383 bp->base = (uchar*)addr;
384 bp->lim = ((uchar*)bp) + sizeof(Block)+size+64;
385 }
386
387 if(bp->flag)
388 panic("allocb reuse\n");
389
390 bp->rp = bp->base;
391 bp->wp = bp->rp;
392 bp->next = 0;
393 bp->flag = 1;
394
395 return bp;
396}
397
398void
399freeb(Block* bp)
400{
401 bp->next = allocbp;
402 allocbp = bp;
403
404 bp->flag = 0;
405}
406
407enum {
408 Paddr= 0x70, /* address port */
409 Pdata= 0x71, /* data port */
410};
411
412uchar
413nvramread(int offset)
414{
415 outb(Paddr, offset);
416 return inb(Pdata);
417}
418
419void (*etherdetach)(void);
420void (*floppydetach)(void);
421void (*sddetach)(void);
422
423void
424warp9(ulong entry)
425{
426 if(etherdetach)
427 etherdetach();
428 consdrain();
429 (*(void(*)(void))(PADDR(entry)))();
430}
431
432char*
433getconf(char*)
434{
435 return nil;
436}
437
438void
439addconf(char*, ...)
440{
441}
442
443void
444uartspecial(int, void(*)(int), int(*)(void), int)
445{
446}
447
448void
449uartputs(IOQ*, char*, int)
450{
451}
452
453void
454uartputc(int)
455{}
456
457void
458uartdrain(void)
459{
460}
os/boot/pc/boot.c+451−0
@@ -0,0 +1,451 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7
8#include "../../../utils/libmach/elf.h"
9
10static uchar elfident[7] = {
11 '\177', 'E', 'L', 'F', '\1', '\1', '\1'
12};
13static Ehdr ehdr, rehdr;
14static Phdr *phdr;
15static int curphdr;
16static ulong curoff;
17static ulong elftotal;
18static long (*swal)(long);
19static ushort (*swab)(ushort);
20
21/*
22 * big-endian short
23 */
24ushort
25beswab(ushort s)
26{
27 uchar *p;
28
29 p = (uchar*)&s;
30 return (p[0]<<8) | p[1];
31}
32
33/*
34 * big-endian long
35 */
36long
37beswal(long l)
38{
39 uchar *p;
40
41 p = (uchar*)&l;
42 return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
43}
44
45/*
46 * little-endian short
47 */
48ushort
49leswab(ushort s)
50{
51 uchar *p;
52
53 p = (uchar*)&s;
54 return (p[1]<<8) | p[0];
55}
56
57/*
58 * little-endian long
59 */
60long
61leswal(long l)
62{
63 uchar *p;
64
65 p = (uchar*)&l;
66 return (p[3]<<24) | (p[2]<<16) | (p[1]<<8) | p[0];
67}
68
69/*
70 * Convert header to canonical form
71 */
72static void
73hswal(long *lp, int n, long (*swap) (long))
74{
75 while (n--) {
76 *lp = (*swap) (*lp);
77 lp++;
78 }
79}
80
81static int
82readehdr(Boot *b)
83{
84 int i;
85
86 /* bitswap the header according to the DATA format */
87 if(ehdr.ident[CLASS] != ELFCLASS32) {
88 print("bad ELF class - not 32 bit\n");
89 return 0;
90 }
91 if(ehdr.ident[DATA] == ELFDATA2LSB) {
92 swab = leswab;
93 swal = leswal;
94 } else if(ehdr.ident[DATA] == ELFDATA2MSB) {
95 swab = beswab;
96 swal = beswal;
97 } else {
98 print("bad ELF encoding - not big or little endian\n");
99 return 0;
100 }
101 memmove(&rehdr, &ehdr, sizeof(Ehdr));
102
103 ehdr.type = swab(ehdr.type);
104 ehdr.machine = swab(ehdr.machine);
105 ehdr.version = swal(ehdr.version);
106 ehdr.elfentry = swal(ehdr.elfentry);
107 ehdr.phoff = swal(ehdr.phoff);
108 ehdr.shoff = swal(ehdr.shoff);
109 ehdr.flags = swal(ehdr.flags);
110 ehdr.ehsize = swab(ehdr.ehsize);
111 ehdr.phentsize = swab(ehdr.phentsize);
112 ehdr.phnum = swab(ehdr.phnum);
113 ehdr.shentsize = swab(ehdr.shentsize);
114 ehdr.shnum = swab(ehdr.shnum);
115 ehdr.shstrndx = swab(ehdr.shstrndx);
116 if(ehdr.type != EXEC || ehdr.version != CURRENT)
117 return 0;
118 if(ehdr.phentsize != sizeof(Phdr))
119 return 0;
120
121 if(debug)
122 print("readehdr OK entry 0x%lux\n", ehdr.elfentry);
123
124 curoff = sizeof(Ehdr);
125 i = ehdr.phoff+ehdr.phentsize*ehdr.phnum - curoff;
126 b->state = READPHDR;
127 b->bp = (char*)malloc(i);
128 b->wp = b->bp;
129 b->ep = b->wp + i;
130 phdr = (Phdr*)(b->bp + ehdr.phoff-sizeof(Ehdr));
131 if(debug)
132 print("phdr...");
133
134 return 1;
135}
136
137static int
138nextphdr(Boot *b)
139{
140 Phdr *php;
141 ulong entry, offset;
142 char *paddr;
143
144 if(debug)
145 print("readedata %d\n", curphdr);
146
147 for(; curphdr < ehdr.phnum; curphdr++){
148 php = phdr+curphdr;
149 if(php->type != LOAD)
150 continue;
151 offset = php->offset;
152 paddr = (char*)PADDR(php->paddr);
153 if(offset < curoff){
154 /*
155 * Can't (be bothered to) rewind the
156 * input, it might be from tftp. If we
157 * did then we could boot FreeBSD kernels
158 * too maybe.
159 */
160 return 0;
161 }
162 if(php->offset > curoff){
163 b->state = READEPAD;
164 b->bp = (char*)malloc(offset - curoff);
165 b->wp = b->bp;
166 b->ep = b->wp + offset - curoff;
167 if(debug)
168 print("nextphdr %lud...\n", offset - curoff);
169 return 1;
170 }
171 b->state = READEDATA;
172 b->bp = paddr;
173 b->wp = b->bp;
174 b->ep = b->wp+php->filesz;
175 print("%ud+", php->filesz);
176 elftotal += php->filesz;
177 if(debug)
178 print("nextphdr %ud@0x%p\n", php->filesz, paddr);
179
180 return 1;
181 }
182
183 if(curphdr != 0){
184 print("=%lud\n", elftotal);
185 b->state = TRYBOOT;
186 entry = ehdr.elfentry & ~0xF0000000;
187 PLLONG(b->exec.entry, entry);
188 return 1;
189 }
190
191 return 0;
192}
193
194static int
195readepad(Boot *b)
196{
197 Phdr *php;
198
199 php = phdr+curphdr;
200 if(debug)
201 print("readepad %d\n", curphdr);
202 curoff = php->offset;
203
204 return nextphdr(b);
205}
206
207static int
208readedata(Boot *b)
209{
210 Phdr *php;
211
212 php = phdr+curphdr;
213 if(debug)
214 print("readedata %d\n", curphdr);
215 if(php->filesz < php->memsz){
216 print("%lud", php->memsz-php->filesz);
217 elftotal += php->memsz-php->filesz;
218 memset((char*)(PADDR(php->paddr)+php->filesz), 0, php->memsz-php->filesz);
219 }
220 curoff = php->offset+php->filesz;
221 curphdr++;
222
223 return nextphdr(b);
224}
225
226static int
227readphdr(Boot *b)
228{
229 Phdr *php;
230
231 php = phdr;
232 hswal((long*)php, ehdr.phentsize*ehdr.phnum/sizeof(long), swal);
233 if(debug)
234 print("phdr curoff %lud vaddr 0x%lux paddr 0x%lux\n",
235 curoff, php->vaddr, php->paddr);
236
237 curoff = ehdr.phoff+ehdr.phentsize*ehdr.phnum;
238 curphdr = 0;
239
240 return nextphdr(b);
241}
242
243static int
244addbytes(char **dbuf, char *edbuf, char **sbuf, char *esbuf)
245{
246 int n;
247
248 n = edbuf - *dbuf;
249 if(n <= 0)
250 return 0;
251 if(n > esbuf - *sbuf)
252 n = esbuf - *sbuf;
253 if(n <= 0)
254 return -1;
255
256 memmove(*dbuf, *sbuf, n);
257 *sbuf += n;
258 *dbuf += n;
259 return edbuf - *dbuf;
260}
261
262int
263bootpass(Boot *b, void *vbuf, int nbuf)
264{
265 char *buf, *ebuf;
266 Exec *ep;
267 ulong entry, data, text, bss;
268
269 if(b->state == FAILED)
270 return FAIL;
271
272 if(nbuf == 0)
273 goto Endofinput;
274
275 buf = vbuf;
276 ebuf = buf+nbuf;
277 while(addbytes(&b->wp, b->ep, &buf, ebuf) == 0) {
278 switch(b->state) {
279 case INITKERNEL:
280 b->state = READEXEC;
281 b->bp = (char*)&b->exec;
282 b->wp = b->bp;
283 b->ep = b->bp+sizeof(Exec);
284 break;
285 case READEXEC:
286 ep = &b->exec;
287 if(GLLONG(ep->magic) == I_MAGIC) {
288 b->state = READ9TEXT;
289 b->bp = (char*)PADDR(GLLONG(ep->entry));
290 b->wp = b->bp;
291 b->ep = b->wp+GLLONG(ep->text);
292 print("%lud", GLLONG(ep->text));
293 break;
294 }
295
296 /* check for gzipped kernel */
297 if(b->bp[0] == 0x1F && (uchar)b->bp[1] == 0x8B && b->bp[2] == 0x08) {
298 b->state = READGZIP;
299 b->bp = (char*)malloc(1440*1024);
300 b->wp = b->bp;
301 b->ep = b->wp + 1440*1024;
302 memmove(b->bp, &b->exec, sizeof(Exec));
303 b->wp += sizeof(Exec);
304 print("gz...");
305 break;
306 }
307
308 /*
309 * Check for ELF.
310 */
311 if(memcmp(b->bp, elfident, 4) == 0){
312 b->state = READEHDR;
313 b->bp = (char*)&ehdr;
314 b->wp = b->bp;
315 b->ep = b->wp + sizeof(Ehdr);
316 memmove(b->bp, &b->exec, sizeof(Exec));
317 b->wp += sizeof(Exec);
318 print("elf...");
319 break;
320 }
321
322 print("bad kernel format\n");
323 b->state = FAILED;
324 return FAIL;
325
326 case READ9TEXT:
327 ep = &b->exec;
328 b->state = READ9DATA;
329 b->bp = (char*)PGROUND(PADDR(GLLONG(ep->entry))+GLLONG(ep->text));
330 b->wp = b->bp;
331 b->ep = b->wp + GLLONG(ep->data);
332 print("+%ld", GLLONG(ep->data));
333 break;
334
335 case READ9DATA:
336 ep = &b->exec;
337 bss = GLLONG(ep->bss);
338 print("+%ld=%ld\n",
339 bss, GLLONG(ep->text)+GLLONG(ep->data)+bss);
340 b->state = TRYBOOT;
341 return ENOUGH;
342
343 case READEHDR:
344 if(!readehdr(b)){
345 print("readehdr failed\n");
346 b->state = FAILED;
347 return FAIL;
348 }
349 break;
350
351 case READPHDR:
352 if(!readphdr(b)){
353 b->state = FAILED;
354 return FAIL;
355 }
356 break;
357
358 case READEPAD:
359 if(!readepad(b)){
360 b->state = FAILED;
361 return FAIL;
362 }
363 break;
364
365 case READEDATA:
366 if(!readedata(b)){
367 b->state = FAILED;
368 return FAIL;
369 }
370 if(b->state == TRYBOOT)
371 return ENOUGH;
372 break;
373
374 case TRYBOOT:
375 case READGZIP:
376 return ENOUGH;
377
378 case READ9LOAD:
379 case INIT9LOAD:
380 panic("9load");
381
382 default:
383 panic("bootstate");
384 }
385 }
386 return MORE;
387
388
389Endofinput:
390 /* end of input */
391 switch(b->state) {
392 case INITKERNEL:
393 case READEXEC:
394 case READ9TEXT:
395 case READ9DATA:
396 case READEHDR:
397 case READPHDR:
398 case READEPAD:
399 case READEDATA:
400 print("premature EOF\n");
401 b->state = FAILED;
402 return FAIL;
403
404 case TRYBOOT:
405 entry = GLLONG(b->exec.entry);
406 print("entry: 0x%lux\n", entry);
407 warp9(PADDR(entry));
408 b->state = FAILED;
409 return FAIL;
410
411 case READGZIP:
412 ep = &b->exec;
413 if(b->bp[0] != 0x1F || (uchar)b->bp[1] != 0x8B || b->bp[2] != 0x08)
414 print("lost magic\n");
415
416 print("%ld => ", b->wp - b->bp);
417 if(gunzip((uchar*)ep, sizeof(*ep), (uchar*)b->bp, b->wp - b->bp) < sizeof(*ep)) {
418 print("badly compressed kernel\n");
419 return FAIL;
420 }
421
422 entry = GLLONG(ep->entry);
423 text = GLLONG(ep->text);
424 data = GLLONG(ep->data);
425 bss = GLLONG(ep->bss);
426 print("%lud+%lud+%lud=%lud\n", text, data, bss, text+data+bss);
427
428 if(gunzip((uchar*)PADDR(entry)-sizeof(Exec), sizeof(Exec)+text+data,
429 (uchar*)b->bp, b->wp-b->bp) < sizeof(Exec)+text+data) {
430 print("error uncompressing kernel\n");
431 return FAIL;
432 }
433
434 /* relocate data to start at page boundary */
435 memmove((void*)PGROUND(PADDR(entry+text)), (void*)(PADDR(entry+text)), data);
436
437 print("entry: %lux\n", entry);
438 warp9(PADDR(entry));
439 b->state = FAILED;
440 return FAIL;
441
442 case INIT9LOAD:
443 case READ9LOAD:
444 panic("end 9load");
445
446 default:
447 panic("bootdone");
448 }
449 b->state = FAILED;
450 return FAIL;
451}
os/boot/pc/bootld.c+108−0
@@ -0,0 +1,108 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7
8static int
9addbytes(char **dbuf, char *edbuf, char **sbuf, char *esbuf)
10{
11 int n;
12
13 n = edbuf - *dbuf;
14 if(n <= 0)
15 return 0;
16 if(n > esbuf - *sbuf)
17 n = esbuf - *sbuf;
18 if(n <= 0)
19 return -1;
20
21 memmove(*dbuf, *sbuf, n);
22 *sbuf += n;
23 *dbuf += n;
24 return edbuf - *dbuf;
25}
26
27extern void origin(void);
28
29int
30bootpass(Boot *b, void *vbuf, int nbuf)
31{
32 char *buf, *ebuf, *p, *q;
33 ulong size;
34
35 if(b->state == FAILED)
36 return FAIL;
37
38 if(nbuf == 0)
39 goto Endofinput;
40
41 buf = vbuf;
42 ebuf = buf+nbuf;
43 while(addbytes(&b->wp, b->ep, &buf, ebuf) == 0) {
44 switch(b->state) {
45 case INIT9LOAD:
46 b->state = READ9LOAD;
47 b->bp = (char*)0x10000;
48 b->wp = b->bp;
49 b->ep = b->bp + 256*1024;
50 break;
51
52 case READ9LOAD:
53 return ENOUGH;
54
55 default:
56 panic("bootstate");
57 }
58 }
59 return MORE;
60
61
62Endofinput:
63 /* end of input */
64 print("\n");
65 switch(b->state) {
66 case INIT9LOAD:
67 print("premature EOF\n");
68 b->state = FAILED;
69 return FAIL;
70
71 case READ9LOAD:
72 size = b->wp - b->bp;
73 if(memcmp(b->bp, origin, 16) != 0) {
74 print("beginning of file does not look right\n");
75 b->state = FAILED;
76 return FAIL;
77 }
78 if(size < 32*1024 || size > 256*1024) {
79 print("got %lud byte loader; not likely\n", size);
80 b->state = FAILED;
81 return FAIL;
82 }
83
84 p = b->bp;
85 q = b->wp;
86 if(q - p > 10000) /* don't search much past l.s */
87 q = p+10000;
88
89 /*
90 * The string `JUMP' appears right before
91 * tokzero, which is where we want to jump.
92 */
93 for(; p<q; p++) {
94 if(strncmp(p, "JUMP", 4) == 0) {
95 p += 4;
96 warp9((ulong)p);
97 }
98 }
99 print("could not find jump destination\n");
100 b->state = FAILED;
101 return FAIL;
102
103 default:
104 panic("bootdone");
105 }
106 b->state = FAILED;
107 return FAIL;
108}
os/boot/pc/bootp.c+652−0
@@ -0,0 +1,652 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7
8#include "ip.h"
9
10uchar broadcast[Eaddrlen] = {
11 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
12};
13
14static ushort tftpport = 5000;
15static int Id = 1;
16static Netaddr myaddr;
17static Netaddr server;
18
19typedef struct {
20 uchar header[4];
21 uchar data[Segsize];
22} Tftp;
23static Tftp tftpb;
24
25static void
26hnputs(uchar *ptr, ushort val)
27{
28 ptr[0] = val>>8;
29 ptr[1] = val;
30}
31
32static void
33hnputl(uchar *ptr, ulong val)
34{
35 ptr[0] = val>>24;
36 ptr[1] = val>>16;
37 ptr[2] = val>>8;
38 ptr[3] = val;
39}
40
41static ulong
42nhgetl(uchar *ptr)
43{
44 return ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]);
45}
46
47static ushort
48nhgets(uchar *ptr)
49{
50 return ((ptr[0]<<8) | ptr[1]);
51}
52
53static short endian = 1;
54static char* aendian = (char*)&endian;
55#define LITTLE *aendian
56
57static ushort
58ptcl_csum(void *a, int len)
59{
60 uchar *addr;
61 ulong t1, t2;
62 ulong losum, hisum, mdsum, x;
63
64 addr = a;
65 losum = 0;
66 hisum = 0;
67 mdsum = 0;
68
69 x = 0;
70 if((ulong)addr & 1) {
71 if(len) {
72 hisum += addr[0];
73 len--;
74 addr++;
75 }
76 x = 1;
77 }
78 while(len >= 16) {
79 t1 = *(ushort*)(addr+0);
80 t2 = *(ushort*)(addr+2); mdsum += t1;
81 t1 = *(ushort*)(addr+4); mdsum += t2;
82 t2 = *(ushort*)(addr+6); mdsum += t1;
83 t1 = *(ushort*)(addr+8); mdsum += t2;
84 t2 = *(ushort*)(addr+10); mdsum += t1;
85 t1 = *(ushort*)(addr+12); mdsum += t2;
86 t2 = *(ushort*)(addr+14); mdsum += t1;
87 mdsum += t2;
88 len -= 16;
89 addr += 16;
90 }
91 while(len >= 2) {
92 mdsum += *(ushort*)addr;
93 len -= 2;
94 addr += 2;
95 }
96 if(x) {
97 if(len)
98 losum += addr[0];
99 if(LITTLE)
100 losum += mdsum;
101 else
102 hisum += mdsum;
103 } else {
104 if(len)
105 hisum += addr[0];
106 if(LITTLE)
107 hisum += mdsum;
108 else
109 losum += mdsum;
110 }
111
112 losum += hisum >> 8;
113 losum += (hisum & 0xff) << 8;
114 while(hisum = losum>>16)
115 losum = hisum + (losum & 0xffff);
116
117 return ~losum;
118}
119
120static ushort
121ip_csum(uchar *addr)
122{
123 int len;
124 ulong sum = 0;
125
126 len = (addr[0]&0xf)<<2;
127
128 while(len > 0) {
129 sum += addr[0]<<8 | addr[1] ;
130 len -= 2;
131 addr += 2;
132 }
133
134 sum = (sum & 0xffff) + (sum >> 16);
135 sum = (sum & 0xffff) + (sum >> 16);
136 return (sum^0xffff);
137}
138
139enum {
140 /* this is only true of IPv4, but we're not doing v6 yet */
141 Min_udp_payload = ETHERMINTU - ETHERHDRSIZE - UDP_HDRSIZE,
142};
143
144static void
145udpsend(int ctlrno, Netaddr *a, void *data, int dlen)
146{
147 char payload[ETHERMAXTU];
148 Udphdr *uh;
149 Etherhdr *ip;
150 Etherpkt pkt;
151 int len, ptcllen;
152
153 /*
154 * if packet is too short, make it longer rather than relying
155 * on ethernet interface or lower layers to pad it.
156 */
157 if (dlen < Min_udp_payload) {
158 memmove(payload, data, dlen);
159 data = payload;
160 dlen = Min_udp_payload;
161 }
162
163 uh = (Udphdr*)&pkt;
164
165 memset(uh, 0, sizeof(Etherpkt));
166 memmove(uh->udpcksum+sizeof(uh->udpcksum), data, dlen);
167
168 /*
169 * UDP portion
170 */
171 ptcllen = dlen + (UDP_HDRSIZE-UDP_PHDRSIZE);
172 uh->ttl = 0;
173 uh->udpproto = IP_UDPPROTO;
174 uh->frag[0] = 0;
175 uh->frag[1] = 0;
176 hnputs(uh->udpplen, ptcllen);
177 hnputl(uh->udpsrc, myaddr.ip);
178 hnputs(uh->udpsport, myaddr.port);
179 hnputl(uh->udpdst, a->ip);
180 hnputs(uh->udpdport, a->port);
181 hnputs(uh->udplen, ptcllen);
182 uh->udpcksum[0] = 0;
183 uh->udpcksum[1] = 0;
184 dlen = (dlen+1)&~1;
185 hnputs(uh->udpcksum, ptcl_csum(&uh->ttl, dlen+UDP_HDRSIZE));
186
187 /*
188 * IP portion
189 */
190 ip = (Etherhdr*)&pkt;
191 len = UDP_EHSIZE+UDP_HDRSIZE+dlen; /* non-descriptive names */
192 ip->vihl = IP_VER|IP_HLEN;
193 ip->tos = 0;
194 ip->ttl = 255;
195 hnputs(ip->length, len-ETHER_HDR);
196 hnputs(ip->id, Id++);
197 ip->frag[0] = 0;
198 ip->frag[1] = 0;
199 ip->cksum[0] = 0;
200 ip->cksum[1] = 0;
201 hnputs(ip->cksum, ip_csum(&ip->vihl));
202
203 /*
204 * Ethernet MAC portion
205 */
206 hnputs(ip->type, ET_IP);
207 memmove(ip->d, a->ea, sizeof(ip->d));
208
209if(debug) {
210 print("udpsend ");
211}
212 ethertxpkt(ctlrno, &pkt, len, Timeout);
213}
214
215static void
216nak(int ctlrno, Netaddr *a, int code, char *msg, int report)
217{
218 int n;
219 char buf[128];
220
221 buf[0] = 0;
222 buf[1] = Tftp_ERROR;
223 buf[2] = 0;
224 buf[3] = code;
225 strcpy(buf+4, msg);
226 n = strlen(msg) + 4 + 1;
227 udpsend(ctlrno, a, buf, n);
228 if(report)
229 print("\ntftp: error(%d): %s\n", code, msg);
230}
231
232static int
233udprecv(int ctlrno, Netaddr *a, void *data, int dlen)
234{
235 int n, len;
236 ushort csm;
237 Udphdr *h;
238 ulong addr, timo;
239 Etherpkt pkt;
240 static int rxactive;
241
242 if(rxactive == 0)
243 timo = 1000;
244 else
245 timo = Timeout;
246 timo += TK2MS(m->ticks);
247 while(timo > TK2MS(m->ticks)){
248 n = etherrxpkt(ctlrno, &pkt, timo-TK2MS(m->ticks));
249 if(n <= 0)
250 continue;
251
252 h = (Udphdr*)&pkt;
253 if(debug)
254 print("udprecv %E to %E...\n", h->s, h->d);
255
256 if(nhgets(h->type) != ET_IP) {
257 if(debug)
258 print("not ip...");
259 continue;
260 }
261
262 if(ip_csum(&h->vihl)) {
263 print("ip chksum error\n");
264 continue;
265 }
266 if(h->vihl != (IP_VER|IP_HLEN)) {
267 print("ip bad vers/hlen\n");
268 continue;
269 }
270
271 if(h->udpproto != IP_UDPPROTO) {
272 if(debug)
273 print("not udp (%d)...", h->udpproto);
274 continue;
275 }
276
277 if(debug)
278 print("okay udp...");
279
280 h->ttl = 0;
281 len = nhgets(h->udplen);
282 hnputs(h->udpplen, len);
283
284 if(nhgets(h->udpcksum)) {
285 csm = ptcl_csum(&h->ttl, len+UDP_PHDRSIZE);
286 if(csm != 0) {
287 print("udp chksum error csum #%4ux len %d\n",
288 csm, n);
289 break;
290 }
291 }
292
293 if(a->port != 0 && nhgets(h->udpsport) != a->port) {
294 if(debug)
295 print("udpport %ux %ux\n",
296 nhgets(h->udpsport), a->port);
297 continue;
298 }
299
300 addr = nhgetl(h->udpsrc);
301 if(a->ip != Bcastip && addr != a->ip) {
302 if(debug)
303 print("bad ip\n");
304 continue;
305 }
306
307 len -= UDP_HDRSIZE-UDP_PHDRSIZE;
308 if(len > dlen) {
309 print("udp: packet too big: %d > %d; from addr %E\n",
310 len, dlen, h->udpsrc);
311 continue;
312 }
313
314 memmove(data, h->udpcksum+sizeof(h->udpcksum), len);
315 a->ip = addr;
316 a->port = nhgets(h->udpsport);
317 memmove(a->ea, pkt.s, sizeof(a->ea));
318
319 rxactive = 1;
320 return len;
321 }
322
323 return 0;
324}
325
326static int tftpblockno;
327
328/*
329 * format of a request packet, from the RFC:
330 *
331 2 bytes string 1 byte string 1 byte
332 ------------------------------------------------
333 | Opcode | Filename | 0 | Mode | 0 |
334 ------------------------------------------------
335 */
336static int
337tftpopen(int ctlrno, Netaddr *a, char *name, Tftp *tftp)
338{
339 int i, len, rlen, oport;
340 char buf[Segsize+2];
341
342 buf[0] = 0;
343 buf[1] = Tftp_READ;
344 len = 2 + sprint(buf+2, "%s", name) + 1;
345 len += sprint(buf+len, "octet") + 1;
346
347 oport = a->port;
348 for(i = 0; i < 5; i++){
349 a->port = oport;
350 udpsend(ctlrno, a, buf, len);
351 a->port = 0;
352 if((rlen = udprecv(ctlrno, a, tftp, sizeof(Tftp))) < sizeof(tftp->header))
353 continue;
354
355 switch((tftp->header[0]<<8)|tftp->header[1]){
356
357 case Tftp_ERROR:
358 print("tftpopen: error (%d): %s\n",
359 (tftp->header[2]<<8)|tftp->header[3], (char*)tftp->data);
360 return -1;
361
362 case Tftp_DATA:
363 tftpblockno = 1;
364 len = (tftp->header[2]<<8)|tftp->header[3];
365 if(len != tftpblockno){
366 print("tftpopen: block error: %d\n", len);
367 nak(ctlrno, a, 1, "block error", 0);
368 return -1;
369 }
370 rlen -= sizeof(tftp->header);
371 if(rlen < Segsize){
372 /* ACK now, in case we don't later */
373 buf[0] = 0;
374 buf[1] = Tftp_ACK;
375 buf[2] = tftpblockno>>8;
376 buf[3] = tftpblockno;
377 udpsend(ctlrno, a, buf, sizeof(tftp->header));
378 }
379 return rlen;
380 }
381 }
382
383 print("tftpopen: failed to connect to server\n");
384 return -1;
385}
386
387static int
388tftpread(int ctlrno, Netaddr *a, Tftp *tftp, int dlen)
389{
390 uchar buf[4];
391 int try, blockno, len;
392
393 dlen += sizeof(tftp->header);
394
395 for(try = 0; try < 10; try++) {
396 buf[0] = 0;
397 buf[1] = Tftp_ACK;
398 buf[2] = tftpblockno>>8;
399 buf[3] = tftpblockno;
400
401 udpsend(ctlrno, a, buf, sizeof(buf));
402 len = udprecv(ctlrno, a, tftp, dlen);
403 if(len <= sizeof(tftp->header)){
404 if(debug)
405 print("tftpread: too short %d <= %d\n",
406 len, sizeof(tftp->header));
407 continue;
408 }
409 blockno = (tftp->header[2]<<8)|tftp->header[3];
410 if(blockno <= tftpblockno){
411 if(debug)
412 print("tftpread: blkno %d <= %d\n",
413 blockno, tftpblockno);
414 continue;
415 }
416
417 if(blockno == tftpblockno+1) {
418 tftpblockno++;
419 if(len < dlen) { /* last packet; send final ack */
420 tftpblockno++;
421 buf[0] = 0;
422 buf[1] = Tftp_ACK;
423 buf[2] = tftpblockno>>8;
424 buf[3] = tftpblockno;
425 udpsend(ctlrno, a, buf, sizeof(buf));
426 }
427 return len-sizeof(tftp->header);
428 }
429 print("tftpread: block error: %d, expected %d\n",
430 blockno, tftpblockno+1);
431 }
432
433 return -1;
434}
435
436static int
437bootpopen(int ctlrno, char *file, Bootp *rep, int dotftpopen)
438{
439 Bootp req;
440 int i, n;
441 uchar *ea;
442 char name[128], *filename, *sysname;
443
444 if((ea = etheraddr(ctlrno)) == 0){
445 print("invalid ctlrno %d\n", ctlrno);
446 return -1;
447 }
448
449 filename = 0;
450 sysname = 0;
451 if(file && *file){
452 strcpy(name, file);
453 if(filename = strchr(name, '!')){
454 sysname = name;
455 *filename++ = 0;
456 }
457 else
458 filename = name;
459 }
460
461 memset(&req, 0, sizeof(req));
462 req.op = Bootrequest;
463 req.htype = 1; /* ethernet */
464 req.hlen = Eaddrlen; /* ethernet */
465 memmove(req.chaddr, ea, Eaddrlen);
466 if(filename != nil)
467 strncpy(req.file, filename, sizeof(req.file));
468 if(sysname != nil)
469 strncpy(req.sname, sysname, sizeof(req.sname));
470
471 myaddr.ip = 0;
472 myaddr.port = BPportsrc;
473 memmove(myaddr.ea, ea, Eaddrlen);
474
475 etherrxflush(ctlrno);
476 for(i = 0; i < 10; i++) {
477 server.ip = Bcastip;
478 server.port = BPportdst;
479 memmove(server.ea, broadcast, sizeof(server.ea));
480 udpsend(ctlrno, &server, &req, sizeof(req));
481 if(udprecv(ctlrno, &server, rep, sizeof(*rep)) <= 0)
482 continue;
483 if(memcmp(req.chaddr, rep->chaddr, Eaddrlen))
484 continue;
485 if(rep->htype != 1 || rep->hlen != Eaddrlen)
486 continue;
487 if(sysname == 0 || strcmp(sysname, rep->sname) == 0)
488 break;
489 }
490 if(i >= 10) {
491 print("bootp timed out\n");
492 return -1;
493 }
494
495 if(!dotftpopen)
496 return 0;
497
498 if(filename == 0 || *filename == 0){
499 if(strcmp(rep->file, "/386/9pxeload") == 0)
500 return -1;
501 filename = rep->file;
502 }
503
504 if(rep->sname[0] != '\0')
505 print("%s ", rep->sname);
506 print("(%d.%d.%d.%d!%d): %s\n",
507 rep->siaddr[0],
508 rep->siaddr[1],
509 rep->siaddr[2],
510 rep->siaddr[3],
511 server.port,
512 filename);
513
514 myaddr.ip = nhgetl(rep->yiaddr);
515 myaddr.port = tftpport++;
516 server.ip = nhgetl(rep->siaddr);
517 server.port = TFTPport;
518
519 if((n = tftpopen(ctlrno, &server, filename, &tftpb)) < 0)
520 return -1;
521
522 return n;
523}
524
525int
526bootpboot(int ctlrno, char *file, Boot *b)
527{
528 int n;
529 Bootp rep;
530
531 if((n = bootpopen(ctlrno, file, &rep, 1)) < 0)
532 return -1;
533
534 while(bootpass(b, tftpb.data, n) == MORE){
535 n = tftpread(ctlrno, &server, &tftpb, sizeof(tftpb.data));
536 if(n < sizeof(tftpb.data))
537 break;
538 }
539
540 if(0 < n && n < sizeof(tftpb.data)) /* got to end of file */
541 bootpass(b, tftpb.data, n);
542 else
543 nak(ctlrno, &server, 3, "ok", 0); /* tftpclose to abort transfer */
544 bootpass(b, nil, 0); /* boot if possible */
545 return -1;
546}
547
548#include "fs.h"
549
550#define INIPATHLEN 64
551
552static struct {
553 Fs fs;
554 char ini[INIPATHLEN];
555} pxether[MaxEther];
556
557static vlong
558pxediskseek(Fs*, vlong)
559{
560 return -1LL;
561}
562
563static long
564pxediskread(Fs*, void*, long)
565{
566 return -1;
567}
568
569static long
570pxeread(File* f, void* va, long len)
571{
572 int n;
573 Bootp rep;
574 char *p, *v;
575
576 if((n = bootpopen(f->fs->dev, pxether[f->fs->dev].ini, &rep, 1)) < 0)
577 return -1;
578
579 p = v = va;
580 while(n > 0) {
581 if((p-v)+n > len)
582 n = len - (p-v);
583 memmove(p, tftpb.data, n);
584 p += n;
585 if(n != Segsize)
586 break;
587 if((n = tftpread(f->fs->dev, &server, &tftpb, sizeof(tftpb.data))) < 0)
588 return -1;
589 }
590 return p-v;
591}
592
593static int
594pxewalk(File* f, char* name)
595{
596 Bootp rep;
597 char *ini;
598
599 switch(f->walked){
600 default:
601 return -1;
602 case 0:
603 if(strcmp(name, "cfg") == 0){
604 f->walked = 1;
605 return 1;
606 }
607 break;
608 case 1:
609 if(strcmp(name, "pxe") == 0){
610 f->walked = 2;
611 return 1;
612 }
613 break;
614 case 2:
615 if(strcmp(name, "%E") != 0)
616 break;
617 f->walked = 3;
618
619 if(bootpopen(f->fs->dev, nil, &rep, 0) < 0)
620 return 0;
621
622 ini = pxether[f->fs->dev].ini;
623 snprint(ini, INIPATHLEN, "/cfg/pxe/%E", rep.chaddr);
624 f->path = ini;
625
626 return 1;
627 }
628 return 0;
629}
630
631void*
632pxegetfspart(int ctlrno, char* part, int)
633{
634 if(!pxe)
635 return nil;
636 if(strcmp(part, "*") != 0)
637 return nil;
638 if(ctlrno >= MaxEther)
639 return nil;
640
641 pxether[ctlrno].fs.dev = ctlrno;
642 pxether[ctlrno].fs.diskread = pxediskread;
643 pxether[ctlrno].fs.diskseek = pxediskseek;
644
645 pxether[ctlrno].fs.read = pxeread;
646 pxether[ctlrno].fs.walk = pxewalk;
647
648 pxether[ctlrno].fs.root.fs = &pxether[ctlrno].fs;
649 pxether[ctlrno].fs.root.walked = 0;
650
651 return &pxether[ctlrno].fs;
652}
os/boot/pc/cga.c+91−0
@@ -0,0 +1,91 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6
7enum {
8 Width = 160,
9 Height = 25,
10
11 Attr = 7, /* white on black */
12};
13
14#define CGASCREENBASE ((uchar*)KADDR(0xB8000))
15
16static int pos;
17static int screeninitdone;
18
19static uchar
20cgaregr(int index)
21{
22 outb(0x3D4, index);
23 return inb(0x3D4+1) & 0xFF;
24}
25
26static void
27cgaregw(int index, int data)
28{
29 outb(0x3D4, index);
30 outb(0x3D4+1, data);
31}
32
33static void
34movecursor(void)
35{
36 cgaregw(0x0E, (pos/2>>8) & 0xFF);
37 cgaregw(0x0F, pos/2 & 0xFF);
38 CGASCREENBASE[pos+1] = Attr;
39}
40
41static void
42cgascreenputc(int c)
43{
44 int i;
45
46 if(c == '\n'){
47 pos = pos/Width;
48 pos = (pos+1)*Width;
49 }
50 else if(c == '\t'){
51 i = 8 - ((pos/2)&7);
52 while(i-->0)
53 cgascreenputc(' ');
54 }
55 else if(c == '\b'){
56 if(pos >= 2)
57 pos -= 2;
58 cgascreenputc(' ');
59 pos -= 2;
60 }
61 else{
62 CGASCREENBASE[pos++] = c;
63 CGASCREENBASE[pos++] = Attr;
64 }
65 if(pos >= Width*Height){
66 memmove(CGASCREENBASE, &CGASCREENBASE[Width], Width*(Height-1));
67 memset(&CGASCREENBASE[Width*(Height-1)], 0, Width);
68 pos = Width*(Height-1);
69 }
70 movecursor();
71}
72
73static void
74screeninit(void)
75{
76 if(screeninitdone == 0){
77 pos = cgaregr(0x0E)<<8;
78 pos |= cgaregr(0x0F);
79 pos *= 2;
80 screeninitdone = 1;
81 }
82}
83
84void
85cgascreenputs(char* s, int n)
86{
87 if(screeninitdone == 0)
88 screeninit();
89 while(n-- > 0)
90 cgascreenputc(*s++);
91}
os/boot/pc/clock.c+305−0
@@ -0,0 +1,305 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7#include "ureg.h"
8
9/*
10 * 8253 timer
11 */
12enum
13{
14 T0cntr= 0x40, /* counter ports */
15 T1cntr= 0x41, /* ... */
16 T2cntr= 0x42, /* ... */
17 Tmode= 0x43, /* mode port */
18
19 /* commands */
20 Latch0= 0x00, /* latch counter 0's value */
21 Load0= 0x30, /* load counter 0 with 2 bytes */
22
23 /* modes */
24 Square= 0x36, /* perioic square wave */
25
26 Freq= 1193182, /* Real clock frequency */
27};
28
29static uvlong cpuhz = 66000000;
30static int cpumhz = 66;
31static int loopconst = 100;
32int cpuidax, cpuiddx;
33int havetsc;
34
35extern void _cycles(uvlong*); /* in l.s */
36extern void wrmsr(int, vlong);
37
38static void
39clockintr(Ureg*, void*)
40{
41 m->ticks++;
42 checkalarms();
43}
44
45#define STEPPING(x) ((x)&0xf)
46#define X86MODEL(x) (((x)>>4)&0xf)
47#define X86FAMILY(x) (((x)>>8)&0xf)
48
49enum
50{
51 /* flags */
52 CpuidFPU = 0x001, /* on-chip floating point unit */
53 CpuidMCE = 0x080, /* machine check exception */
54 CpuidCX8 = 0x100, /* CMPXCHG8B instruction */
55};
56
57typedef struct
58{
59 int family;
60 int model;
61 int aalcycles;
62 char *name;
63} X86type;
64
65X86type x86intel[] =
66{
67 { 4, 0, 22, "486DX", }, /* known chips */
68 { 4, 1, 22, "486DX50", },
69 { 4, 2, 22, "486SX", },
70 { 4, 3, 22, "486DX2", },
71 { 4, 4, 22, "486SL", },
72 { 4, 5, 22, "486SX2", },
73 { 4, 7, 22, "DX2WB", }, /* P24D */
74 { 4, 8, 22, "DX4", }, /* P24C */
75 { 4, 9, 22, "DX4WB", }, /* P24CT */
76 { 5, 0, 23, "P5", },
77 { 5, 1, 23, "P5", },
78 { 5, 2, 23, "P54C", },
79 { 5, 3, 23, "P24T", },
80 { 5, 4, 23, "P55C MMX", },
81 { 5, 7, 23, "P54C VRT", },
82 { 6, 1, 16, "PentiumPro", },/* trial and error */
83 { 6, 3, 16, "PentiumII", },
84 { 6, 5, 16, "PentiumII/Xeon", },
85 { 6, 6, 16, "Celeron", },
86 { 6, 7, 16, "PentiumIII/Xeon", },
87 { 6, 8, 16, "PentiumIII/Xeon", },
88 { 6, 0xB, 16, "PentiumIII/Xeon", },
89 { 0xF, 1, 16, "P4", }, /* P4 */
90 { 0xF, 2, 16, "PentiumIV/Xeon", },
91
92 { 3, -1, 32, "386", }, /* family defaults */
93 { 4, -1, 22, "486", },
94 { 5, -1, 23, "P5", },
95 { 6, -1, 16, "P6", },
96 { 0xF, -1, 16, "P4", }, /* P4 */
97
98 { -1, -1, 16, "unknown", }, /* total default */
99};
100
101
102/*
103 * The AMD processors all implement the CPUID instruction.
104 * The later ones also return the processor name via functions
105 * 0x80000002, 0x80000003 and 0x80000004 in registers AX, BX, CX
106 * and DX:
107 * K5 "AMD-K5(tm) Processor"
108 * K6 "AMD-K6tm w/ multimedia extensions"
109 * K6 3D "AMD-K6(tm) 3D processor"
110 * K6 3D+ ?
111 */
112static X86type x86amd[] =
113{
114 { 5, 0, 23, "AMD-K5", }, /* guesswork */
115 { 5, 1, 23, "AMD-K5", }, /* guesswork */
116 { 5, 2, 23, "AMD-K5", }, /* guesswork */
117 { 5, 3, 23, "AMD-K5", }, /* guesswork */
118 { 5, 6, 11, "AMD-K6", }, /* trial and error */
119 { 5, 7, 11, "AMD-K6", }, /* trial and error */
120 { 5, 8, 11, "AMD-K6-2", }, /* trial and error */
121 { 5, 9, 11, "AMD-K6-III", },/* trial and error */
122
123 { 6, 1, 11, "AMD-Athlon", },/* trial and error */
124 { 6, 2, 11, "AMD-Athlon", },/* trial and error */
125
126 { 4, -1, 22, "Am486", }, /* guesswork */
127 { 5, -1, 23, "AMD-K5/K6", }, /* guesswork */
128 { 6, -1, 11, "AMD-Athlon", },/* guesswork */
129 { 0xF, -1, 11, "AMD64", }, /* guesswork */
130
131 { -1, -1, 11, "unknown", }, /* total default */
132};
133
134static X86type *cputype;
135
136
137void
138delay(int millisecs)
139{
140 millisecs *= loopconst;
141 if(millisecs <= 0)
142 millisecs = 1;
143 aamloop(millisecs);
144}
145
146void
147microdelay(int microsecs)
148{
149 microsecs *= loopconst;
150 microsecs /= 1000;
151 if(microsecs <= 0)
152 microsecs = 1;
153 aamloop(microsecs);
154}
155
156extern void cpuid(char*, int*, int*);
157
158X86type*
159cpuidentify(void)
160{
161 int family, model;
162 X86type *t;
163 char cpuidid[16];
164 int cpuidax, cpuiddx;
165
166 cpuid(cpuidid, &cpuidax, &cpuiddx);
167 if(strncmp(cpuidid, "AuthenticAMD", 12) == 0)
168 t = x86amd;
169 else
170 t = x86intel;
171 family = X86FAMILY(cpuidax);
172 model = X86MODEL(cpuidax);
173 if (0)
174 print("cpuidentify: cpuidax 0x%ux cpuiddx 0x%ux\n",
175 cpuidax, cpuiddx);
176 while(t->name){
177 if((t->family == family && t->model == model)
178 || (t->family == family && t->model == -1)
179 || (t->family == -1))
180 break;
181 t++;
182 }
183 if(t->name == nil)
184 panic("cpuidentify");
185
186 if(cpuiddx & 0x10){
187 havetsc = 1;
188 if(cpuiddx & 0x20)
189 wrmsr(0x10, 0);
190 }
191
192 return t;
193}
194
195void
196clockinit(void)
197{
198 uvlong a, b, cpufreq;
199 int loops, incr, x, y;
200 X86type *t;
201
202 /*
203 * set vector for clock interrupts
204 */
205 setvec(VectorCLOCK, clockintr, 0);
206
207 t = cpuidentify();
208
209 /*
210 * set clock for 1/HZ seconds
211 */
212 outb(Tmode, Load0|Square);
213 outb(T0cntr, (Freq/HZ)); /* low byte */
214 outb(T0cntr, (Freq/HZ)>>8); /* high byte */
215
216 /*
217 * Introduce a little delay to make sure the count is
218 * latched and the timer is counting down; with a fast
219 * enough processor this may not be the case.
220 * The i8254 (which this probably is) has a read-back
221 * command which can be used to make sure the counting
222 * register has been written into the counting element.
223 */
224 x = (Freq/HZ);
225 for(loops = 0; loops < 100000 && x >= (Freq/HZ); loops++){
226 outb(Tmode, Latch0);
227 x = inb(T0cntr);
228 x |= inb(T0cntr)<<8;
229 }
230
231 /* find biggest loop that doesn't wrap */
232 incr = 16000000/(t->aalcycles*HZ*2);
233 x = 2000;
234 for(loops = incr; loops < 64*1024; loops += incr) {
235
236 /*
237 * measure time for the loop
238 *
239 * MOVL loops,CX
240 * aaml1: AAM
241 * LOOP aaml1
242 *
243 * the time for the loop should be independent of external
244 * cache and memory system since it fits in the execution
245 * prefetch buffer.
246 *
247 */
248 outb(Tmode, Latch0);
249 if(havetsc)
250 _cycles(&a);
251 x = inb(T0cntr);
252 x |= inb(T0cntr)<<8;
253 aamloop(loops);
254 outb(Tmode, Latch0);
255 if(havetsc)
256 _cycles(&b);
257 y = inb(T0cntr);
258 y |= inb(T0cntr)<<8;
259 x -= y;
260
261 if(x < 0)
262 x += Freq/HZ;
263
264 if(x > Freq/(3*HZ))
265 break;
266 }
267
268 /*
269 * figure out clock frequency and a loop multiplier for delay().
270 * counter goes at twice the frequency, once per transition,
271 * i.e., twice per square wave
272 */
273 cpufreq = (vlong)loops*((t->aalcycles*2*Freq)/x);
274 loopconst = (cpufreq/1000)/t->aalcycles; /* AAM+LOOP's for 1 ms */
275
276 if(havetsc){
277 /* counter goes up by 2*Freq */
278 b = (b-a)<<1;
279 b *= Freq;
280 b /= x;
281
282 /*
283 * round to the nearest megahz
284 */
285 cpumhz = (b+500000)/1000000L;
286 cpuhz = b;
287 }
288 else{
289 /*
290 * add in possible .5% error and convert to MHz
291 */
292 cpumhz = (cpufreq + cpufreq/200)/1000000;
293 cpuhz = cpufreq;
294 }
295
296 if(debug){
297 int timeo;
298
299 print("%dMHz %s loop %d\n", cpumhz, t->name, loopconst);
300 print("tick...");
301 for(timeo = 0; timeo < 10; timeo++)
302 delay(1000);
303 print("tock...\n");
304 }
305}
os/boot/pc/conf.c+537−0
@@ -0,0 +1,537 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7
8#include "fs.h"
9
10/*
11 * Where configuration info is left for the loaded programme.
12 * This will turn into a structure as more is done by the boot loader
13 * (e.g. why parse the .ini file twice?).
14 * There are 3584 bytes available at CONFADDR.
15 *
16 * The low-level boot routines in l.s leave data for us at CONFADDR,
17 * which we pick up before reading the plan9.ini file.
18 */
19#define BOOTLINELEN 64
20#define BOOTARGS ((char*)(CONFADDR+BOOTLINELEN))
21#define BOOTARGSLEN (3584-0x200-BOOTLINELEN)
22#define MAXCONF 100
23
24static char *confname[MAXCONF];
25static char *confval[MAXCONF];
26static int nconf;
27
28extern char **ini;
29
30typedef struct {
31 char* name;
32 int start;
33 int end;
34} Mblock;
35
36typedef struct {
37 char* tag;
38 Mblock* mb;
39} Mitem;
40
41static Mblock mblock[MAXCONF];
42static int nmblock;
43static Mitem mitem[MAXCONF];
44static int nmitem;
45static char* mdefault;
46static char mdefaultbuf[10];
47static int mtimeout;
48
49static char*
50comma(char* line, char** residue)
51{
52 char *q, *r;
53
54 if((q = strchr(line, ',')) != nil){
55 *q++ = 0;
56 if(*q == ' ')
57 q++;
58 }
59 *residue = q;
60
61 if((r = strchr(line, ' ')) != nil)
62 *r = 0;
63
64 if(*line == ' ')
65 line++;
66 return line;
67}
68
69static Mblock*
70findblock(char* name, char** residue)
71{
72 int i;
73 char *p;
74
75 p = comma(name, residue);
76 for(i = 0; i < nmblock; i++){
77 if(strcmp(p, mblock[i].name) == 0)
78 return &mblock[i];
79 }
80 return nil;
81}
82
83static Mitem*
84finditem(char* name, char** residue)
85{
86 int i;
87 char *p;
88
89 p = comma(name, residue);
90 for(i = 0; i < nmitem; i++){
91 if(strcmp(p, mitem[i].mb->name) == 0)
92 return &mitem[i];
93 }
94 return nil;
95}
96
97static void
98parsemenu(char* str, char* scratch, int len)
99{
100 Mitem *mi;
101 Mblock *mb, *menu;
102 char buf[20], *p, *q, *line[MAXCONF];
103 int i, inblock, n, show;
104
105 inblock = 0;
106 menu = nil;
107 memmove(scratch, str, len);
108 n = getfields(scratch, line, MAXCONF, '\n');
109 if(n >= MAXCONF)
110 print("warning: possibly too many lines in plan9.ini\n");
111 for(i = 0; i < n; i++){
112 p = line[i];
113 if(inblock && *p == '['){
114 mblock[nmblock].end = i;
115 if(strcmp(mblock[nmblock].name, "menu") == 0)
116 menu = &mblock[nmblock];
117 nmblock++;
118 inblock = 0;
119 }
120 if(*p == '['){
121 if(nmblock == 0 && i != 0){
122 mblock[nmblock].name = "common";
123 mblock[nmblock].start = 0;
124 mblock[nmblock].end = i;
125 nmblock++;
126 }
127 q = strchr(p+1, ']');
128 if(q == nil || *(q+1) != 0){
129 print("malformed menu block header - %s\n", p);
130 return;
131 }
132 *q = 0;
133 mblock[nmblock].name = p+1;
134 mblock[nmblock].start = i+1;
135 inblock = 1;
136 }
137 }
138
139 if(inblock){
140 mblock[nmblock].end = i;
141 nmblock++;
142 }
143 if(menu == nil)
144 return;
145 if(nmblock < 2){
146 print("incomplete menu specification\n");
147 return;
148 }
149
150 for(i = menu->start; i < menu->end; i++){
151 p = line[i];
152 if(cistrncmp(p, "menuitem=", 9) == 0){
153 p += 9;
154 if((mb = findblock(p, &q)) == nil){
155 print("no block for menuitem %s\n", p);
156 return;
157 }
158 if(q != nil)
159 mitem[nmitem].tag = q;
160 else
161 mitem[nmitem].tag = mb->name;
162 mitem[nmitem].mb = mb;
163 nmitem++;
164 }
165 else if(cistrncmp(p, "menudefault=", 12) == 0){
166 p += 12;
167 if((mi = finditem(p, &q)) == nil){
168 print("no item for menudefault %s\n", p);
169 return;
170 }
171 if(q != nil)
172 mtimeout = strtol(q, 0, 0);
173 sprint(mdefaultbuf, "%ld", mi-mitem+1);
174 mdefault = mdefaultbuf;
175 }
176 else if(cistrncmp(p, "menuconsole=", 12) == 0){
177 p += 12;
178 p = comma(p, &q);
179 consinit(p, q);
180 }
181 else{
182 print("invalid line in [menu] block - %s\n", p);
183 return;
184 }
185 }
186
187again:
188 print("\nPlan 9 Startup Menu:\n====================\n");
189 for(i = 0; i < nmitem; i++)
190 print(" %d. %s\n", i+1, mitem[i].tag);
191 for(;;){
192 getstr("Selection", buf, sizeof(buf), mdefault, mtimeout);
193 mtimeout = 0;
194 i = strtol(buf, &p, 0)-1;
195 if(i < 0 || i >= nmitem)
196 goto again;
197 switch(*p){
198 case 'p':
199 case 'P':
200 show = 1;
201 print("\n");
202 break;
203 case 0:
204 show = 0;
205 break;
206 default:
207 continue;
208
209 }
210 mi = &mitem[i];
211
212 p = str;
213 p += sprint(p, "menuitem=%s\n", mi->mb->name);
214 for(i = 0; i < nmblock; i++){
215 mb = &mblock[i];
216 if(mi->mb != mb && cistrcmp(mb->name, "common") != 0)
217 continue;
218 for(n = mb->start; n < mb->end; n++)
219 p += sprint(p, "%s\n", line[n]);
220 }
221
222 if(show){
223 for(q = str; q < p; q += i){
224 if((i = print(q)) <= 0)
225 break;
226 }
227 goto again;
228 }
229 break;
230 }
231 print("\n");
232}
233
234/*
235static void
236msleep(int msec)
237{
238 ulong start;
239
240 for(start = m->ticks; TK2MS(m->ticks - start) < msec; )
241 ;
242}
243*/
244
245void
246readlsconf(void)
247{
248 uchar *p;
249
250 p = (uchar*)CONFADDR;
251 for(;;) {
252 if(strcmp((char*)p, "APM") == 0){
253 apm.haveinfo = 1;
254 apm.ax = *(ushort*)(p+4);
255 apm.cx = *(ushort*)(p+6);
256 apm.dx = *(ushort*)(p+8);
257 apm.di = *(ushort*)(p+10);
258 apm.ebx = *(ulong*)(p+12);
259 apm.esi = *(ulong*)(p+16);
260 print("apm ax=%x cx=%x dx=%x di=%x ebx=%x esi=%x\n",
261 apm.ax, apm.cx, apm.dx, apm.di, apm.ebx, apm.esi);
262 p += 20;
263 continue;
264 }
265 break;
266 }
267}
268
269char*
270getconf(char *name)
271{
272 int i, n, nmatch;
273 char buf[20];
274
275 nmatch = 0;
276 for(i = 0; i < nconf; i++)
277 if(cistrcmp(confname[i], name) == 0)
278 nmatch++;
279
280 switch(nmatch) {
281 default:
282 print("\n");
283 nmatch = 0;
284 for(i = 0; i < nconf; i++)
285 if(cistrcmp(confname[i], name) == 0)
286 print("%d. %s\n", ++nmatch, confval[i]);
287 print("%d. none of the above\n", ++nmatch);
288 do {
289 getstr(name, buf, sizeof(buf), nil, 0);
290 n = atoi(buf);
291 } while(n < 1 || n > nmatch);
292
293 for(i = 0; i < nconf; i++)
294 if(cistrcmp(confname[i], name) == 0)
295 if(--n == 0)
296 return confval[i];
297 break;
298
299 case 1:
300 for(i = 0; i < nconf; i++)
301 if(cistrcmp(confname[i], name) == 0)
302 return confval[i];
303 break;
304
305 case 0:
306 break;
307 }
308 return nil;
309}
310
311void
312addconf(char *fmt, ...)
313{
314 va_list arg;
315
316 va_start(arg, fmt);
317 vseprint(BOOTARGS+strlen(BOOTARGS), BOOTARGS+BOOTARGSLEN, fmt, arg);
318 va_end(arg);
319}
320
321void
322changeconf(char *fmt, ...)
323{
324 va_list arg;
325 char *p, *q, pref[20], buf[128];
326
327 va_start(arg, fmt);
328 vseprint(buf, buf+sizeof buf, fmt, arg);
329 va_end(arg);
330 strncpy(pref+1, buf, 19);
331 pref[19] = '\0';
332 if(p = strchr(pref, '='))
333 *(p+1) = '\0';
334 else
335 print("warning: did not change %s in plan9.ini\n", buf);
336
337 /* find old line by looking for \nwhat= */
338 pref[0] = '\n';
339 if(strncmp(BOOTARGS, pref+1, strlen(pref+1)) == 0)
340 p = BOOTARGS;
341 else if(p = strstr(BOOTARGS, pref))
342 p++;
343 else
344 p = nil;
345
346 /* move rest of args up, deleting what= line. */
347 if(p != nil && (q = strchr(p, '\n')) != nil)
348 memmove(p, q+1, strlen(q+1)+1);
349
350 /* add replacement to end */
351 addconf("%s", buf);
352}
353
354/*
355 * read configuration file
356 */
357static char inibuf[BOOTARGSLEN];
358static char id[8] = "ZORT 0\r\n";
359
360int
361dotini(Fs *fs)
362{
363 File rc;
364 int blankline, i, incomment, inspace, n;
365 char *cp, *p, *q, *line[MAXCONF];
366
367 if(fswalk(fs, *ini, &rc) <= 0)
368 return -1;
369
370 cp = inibuf;
371 *cp = 0;
372 n = fsread(&rc, cp, BOOTARGSLEN-1);
373 if(n <= 0)
374 return -1;
375
376 cp[n] = 0;
377
378 /*
379 * Strip out '\r', change '\t' -> ' '.
380 * Change runs of spaces into single spaces.
381 * Strip out trailing spaces, blank lines.
382 *
383 * We do this before we make the copy so that if we
384 * need to change the copy, it is already fairly clean.
385 * The main need is in the case when plan9.ini has been
386 * padded with lots of trailing spaces, as is the case
387 * for those created during a distribution install.
388 */
389 p = cp;
390 blankline = 1;
391 incomment = inspace = 0;
392 for(q = cp; *q; q++){
393 if(*q == '\r')
394 continue;
395 if(*q == '\t')
396 *q = ' ';
397 if(*q == ' '){
398 inspace = 1;
399 continue;
400 }
401 if(*q == '\n'){
402 if(!blankline){
403 if(!incomment)
404 *p++ = '\n';
405 blankline = 1;
406 }
407 incomment = inspace = 0;
408 continue;
409 }
410 if(inspace){
411 if(!blankline && !incomment)
412 *p++ = ' ';
413 inspace = 0;
414 }
415 if(blankline && *q == '#')
416 incomment = 1;
417 blankline = 0;
418 if(!incomment)
419 *p++ = *q;
420 }
421 if(p > cp && p[-1] != '\n')
422 *p++ = '\n';
423 *p++ = 0;
424 n = p-cp;
425
426 parsemenu(cp, BOOTARGS, n);
427
428 /*
429 * Keep a copy.
430 * We could change this to pass the parsed strings
431 * to the booted programme instead of the raw
432 * string, then it only gets done once.
433 */
434 if(strncmp(cp, id, sizeof(id))){
435 memmove(BOOTARGS, id, sizeof(id));
436 if(n+1+sizeof(id) >= BOOTARGSLEN)
437 n -= sizeof(id);
438 memmove(BOOTARGS+sizeof(id), cp, n+1);
439 }
440 else
441 memmove(BOOTARGS, cp, n+1);
442
443 n = getfields(cp, line, MAXCONF, '\n');
444 for(i = 0; i < n; i++){
445 cp = strchr(line[i], '=');
446 if(cp == 0)
447 continue;
448 *cp++ = 0;
449 if(cp - line[i] >= NAMELEN+1)
450 *(line[i]+NAMELEN-1) = 0;
451 confname[nconf] = line[i];
452 confval[nconf] = cp;
453 nconf++;
454 }
455 return 0;
456}
457
458static int
459parseether(uchar *to, char *from)
460{
461 char nip[4];
462 char *p;
463 int i;
464
465 p = from;
466 while(*p == ' ')
467 ++p;
468 for(i = 0; i < 6; i++){
469 if(*p == 0)
470 return -1;
471 nip[0] = *p++;
472 if(*p == 0)
473 return -1;
474 nip[1] = *p++;
475 nip[2] = 0;
476 to[i] = strtoul(nip, 0, 16);
477 if(*p == ':')
478 p++;
479 }
480 return 0;
481}
482
483int
484isaconfig(char *class, int ctlrno, ISAConf *isa)
485{
486 char cc[NAMELEN], *p, *q, *r;
487 int n;
488
489 sprint(cc, "%s%d", class, ctlrno);
490 for(n = 0; n < nconf; n++){
491 if(cistrncmp(confname[n], cc, NAMELEN))
492 continue;
493 isa->nopt = 0;
494 p = confval[n];
495 while(*p){
496 while(*p == ' ' || *p == '\t')
497 p++;
498 if(*p == '\0')
499 break;
500 if(cistrncmp(p, "type=", 5) == 0){
501 p += 5;
502 for(q = isa->type; q < &isa->type[NAMELEN-1]; q++){
503 if(*p == '\0' || *p == ' ' || *p == '\t')
504 break;
505 *q = *p++;
506 }
507 *q = '\0';
508 }
509 else if(cistrncmp(p, "port=", 5) == 0)
510 isa->port = strtoul(p+5, &p, 0);
511 else if(cistrncmp(p, "irq=", 4) == 0)
512 isa->irq = strtoul(p+4, &p, 0);
513 else if(cistrncmp(p, "mem=", 4) == 0)
514 isa->mem = strtoul(p+4, &p, 0);
515 else if(cistrncmp(p, "size=", 5) == 0)
516 isa->size = strtoul(p+5, &p, 0);
517 else if(cistrncmp(p, "ea=", 3) == 0){
518 if(parseether(isa->ea, p+3) == -1)
519 memset(isa->ea, 0, 6);
520 }
521 else if(isa->nopt < NISAOPT){
522 r = isa->opt[isa->nopt];
523 while(*p && *p != ' ' && *p != '\t'){
524 *r++ = *p++;
525 if(r-isa->opt[isa->nopt] >= ISAOPTLEN-1)
526 break;
527 }
528 *r = '\0';
529 isa->nopt++;
530 }
531 while(*p && *p != ' ' && *p != '\t')
532 p++;
533 }
534 return 1;
535 }
536 return 0;
537}
os/boot/pc/console.c+236−0
@@ -0,0 +1,236 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "io.h"
7
8IOQ consiq;
9IOQ consoq;
10
11static int useuart;
12
13int debug = 0;
14
15void
16kbdchar(int c)
17{
18 c &= 0x7F;
19 if(c == 0x10)
20 warp86("\n^P\n", 0);
21 if(c == 0x12)
22 debug = !debug;
23 consiq.putc(&consiq, c);
24}
25
26static int
27consputc(void)
28{
29 return consoq.getc(&consoq);
30}
31
32void
33kbdinit(void)
34{
35 i8042init();
36 qinit(&consiq);
37}
38
39void
40consinit(char* name, char* speed)
41{
42 int baud, port;
43
44 if(name == nil || cistrcmp(name, "cga") == 0)
45 return;
46 port = strtoul(name, 0, 0);
47 if(port < 0 || port > 1)
48 return;
49 if(speed == nil || (baud = strtoul(speed, 0, 0)) == 0)
50 baud = 9600;
51
52 qinit(&consoq);
53
54 uartspecial(port, kbdchar, consputc, baud);
55 useuart = 1;
56 uartputs(&consoq, "\n", 1);
57}
58
59void
60consdrain(void)
61{
62 if(useuart)
63 uartdrain();
64}
65
66void
67consputs(char* s, int n)
68{
69 cgascreenputs(s, n);
70 if(useuart)
71 uartputs(&consoq, s, n);
72}
73
74void
75warp86(char* s, ulong)
76{
77 if(s != nil)
78 print(s);
79 spllo();
80 consdrain();
81
82 i8042reset();
83 print("Takes a licking and keeps on ticking...\n");
84 for(;;)
85 idle();
86}
87
88static int
89getline(char *buf, int size, int timeout)
90{
91 int c, i=0;
92 ulong start;
93 char echo;
94
95 for (;;) {
96 start = m->ticks;
97 do{
98 /* timeout seconds to first char */
99 if(timeout && ((m->ticks - start) > timeout*HZ))
100 return -2;
101 c = consiq.getc(&consiq);
102 }while(c == -1);
103 timeout = 0;
104
105 if(c == '\r')
106 c = '\n'; /* turn carriage return into newline */
107 if(c == '\177')
108 c = '\010'; /* turn delete into backspace */
109 if(c == '\025')
110 echo = '\n'; /* echo ^U as a newline */
111 else
112 echo = c;
113 consputs(&echo, 1);
114
115 if(c == '\010'){
116 if(i > 0)
117 i--; /* bs deletes last character */
118 continue;
119 }
120 /* a newline ends a line */
121 if (c == '\n')
122 break;
123 /* ^U wipes out the line */
124 if (c =='\025')
125 return -1;
126 if(i == size)
127 return size;
128 buf[i++] = c;
129 }
130 buf[i] = 0;
131 return i;
132}
133
134int
135getstr(char *prompt, char *buf, int size, char *def, int timeout)
136{
137 int len, isdefault;
138 char pbuf[PRINTSIZE];
139
140 buf[0] = 0;
141 isdefault = (def && *def);
142 if(isdefault == 0){
143 timeout = 0;
144 sprint(pbuf, "%s: ", prompt);
145 }
146 else if(timeout)
147 sprint(pbuf, "%s[default==%s (%ds timeout)]: ", prompt, def, timeout);
148 else
149 sprint(pbuf, "%s[default==%s]: ", prompt, def);
150 for (;;) {
151 print(pbuf);
152 len = getline(buf, size, timeout);
153 switch(len){
154 case 0:
155 /* RETURN */
156 if(isdefault)
157 break;
158 continue;
159 case -1:
160 /* ^U typed */
161 continue;
162 case -2:
163 /* timeout, use default */
164 consputs("\n", 1);
165 len = 0;
166 break;
167 default:
168 break;
169 }
170 if(len >= size){
171 print("line too long\n");
172 continue;
173 }
174 break;
175 }
176 if(len == 0 && isdefault)
177 strcpy(buf, def);
178 return 0;
179}
180
181int
182print(char *fmt, ...)
183{
184 int n;
185 va_list arg;
186 char buf[PRINTSIZE];
187
188 va_start(arg, fmt);
189 n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
190 va_end(arg);
191 consputs(buf, n);
192
193 return n;
194}
195
196int
197sprint(char *s, char *fmt, ...)
198{
199 int n;
200 va_list arg;
201
202 va_start(arg, fmt);
203 n = vseprint(s, s+PRINTSIZE, fmt, arg) - s;
204 va_end(arg);
205
206 return n;
207}
208
209void
210panic(char *fmt, ...)
211{
212 int n;
213 va_list arg;
214 char buf[PRINTSIZE];
215
216 strcpy(buf, "panic: ");
217 va_start(arg, fmt);
218 n = vseprint(buf+7, buf+sizeof(buf), fmt, arg) - buf;
219 va_end(arg);
220 buf[n] = '\n';
221 consputs(buf, n+1);
222
223//floppymemwrite();
224//splhi(); for(;;);
225 if(etherdetach)
226 etherdetach();
227 if(sddetach)
228 sddetach();
229
230 consputs("\nPress almost any key to reset...", 32);
231 spllo();
232 while(consiq.getc(&consiq) == -1)
233 ;
234
235 warp86(nil, 0);
236}
os/boot/pc/dat.h+212−0
@@ -0,0 +1,212 @@
1typedef struct List {
2 void *next;
3} List;
4
5typedef struct Alarm Alarm;
6typedef struct Alarm {
7 List;
8 int busy;
9 long dt;
10 void (*f)(Alarm*);
11 void *arg;
12} Alarm;
13
14typedef struct Apminfo {
15 int haveinfo;
16 int ax;
17 int cx;
18 int dx;
19 int di;
20 int ebx;
21 int esi;
22} Apminfo;
23
24typedef struct Block Block;
25struct Block {
26 Block* next;
27 uchar* rp; /* first unconsumed byte */
28 uchar* wp; /* first empty byte */
29 uchar* lim; /* 1 past the end of the buffer */
30 uchar* base; /* start of the buffer */
31 ulong flag;
32};
33#define BLEN(s) ((s)->wp - (s)->rp)
34
35typedef struct IOQ IOQ;
36typedef struct IOQ {
37 uchar buf[4096];
38 uchar *in;
39 uchar *out;
40 int state;
41 int (*getc)(IOQ*);
42 int (*putc)(IOQ*, int);
43 void *ptr;
44};
45
46enum {
47 Eaddrlen = 6,
48 /* next two exclude 4-byte ether CRC */
49 ETHERMINTU = 60, /* minimum transmit size */
50 ETHERMAXTU = 1514, /* maximum transmit size */
51 ETHERHDRSIZE = 14, /* size of an ethernet header */
52
53 MaxEther = 6,
54};
55
56typedef struct {
57 uchar d[Eaddrlen];
58 uchar s[Eaddrlen];
59 uchar type[2];
60 uchar data[1500];
61 uchar crc[4];
62} Etherpkt;
63
64extern uchar broadcast[Eaddrlen];
65
66typedef struct Ureg Ureg;
67
68typedef struct Segdesc {
69 ulong d0;
70 ulong d1;
71} Segdesc;
72
73typedef struct Mach {
74 ulong ticks; /* of the clock since boot time */
75 void *alarm; /* alarms bound to this clock */
76} Mach;
77
78extern Mach *m;
79
80#define I_MAGIC ((((4*11)+0)*11)+7)
81
82typedef struct Exec Exec;
83struct Exec
84{
85 uchar magic[4]; /* magic number */
86 uchar text[4]; /* size of text segment */
87 uchar data[4]; /* size of initialized data */
88 uchar bss[4]; /* size of uninitialized data */
89 uchar syms[4]; /* size of symbol table */
90 uchar entry[4]; /* entry point */
91 uchar spsz[4]; /* size of sp/pc offset table */
92 uchar pcsz[4]; /* size of pc/line number table */
93};
94
95/*
96 * a parsed .ini line
97 */
98#define ISAOPTLEN 32
99#define NISAOPT 8
100
101typedef struct ISAConf {
102 char type[NAMELEN];
103 ulong port;
104 ulong irq;
105 ulong mem;
106 ulong size;
107 uchar ea[6];
108
109 int nopt;
110 char opt[NISAOPT][ISAOPTLEN];
111} ISAConf;
112
113typedef struct Pcidev Pcidev;
114typedef struct PCMmap PCMmap;
115
116#define BOOTLINE ((char*)CONFADDR)
117
118enum {
119 MB = (1024*1024),
120};
121#define ROUND(s, sz) (((s)+((sz)-1))&~((sz)-1))
122
123
124typedef struct Type Type;
125typedef struct Medium Medium;
126typedef struct Boot Boot;
127
128enum { /* type */
129 Tnil = 0x00,
130
131 Tfloppy = 0x01,
132 Tsd = 0x02,
133 Tether = 0x03,
134 Tcd = 0x04,
135
136 Tany = -1,
137};
138
139enum { /* name and flag */
140 Fnone = 0x00,
141
142 Nfs = 0x00,
143 Ffs = (1<<Nfs),
144 Nboot = 0x01,
145 Fboot = (1<<Nboot),
146 Nbootp = 0x02,
147 Fbootp = (1<<Nbootp),
148 NName = 3,
149
150 Fany = Fbootp|Fboot|Ffs,
151
152 Fini = 0x10,
153 Fprobe = 0x80,
154};
155
156typedef struct Type {
157 int type;
158 int flag;
159 int (*init)(void);
160 void (*initdev)(int, char*);
161 void* (*getfspart)(int, char*, int); /* actually returns Dos* */
162 void (*addconf)(int);
163 int (*boot)(int, char*, Boot*);
164 void (*printdevs)(int);
165 char** parts;
166 char** inis;
167 int mask;
168 Medium* media;
169} Type;
170
171extern void (*etherdetach)(void);
172extern void (*floppydetach)(void);
173extern void (*sddetach)(void);
174
175typedef struct Lock { /* for ilock, iunlock */
176 int locked;
177 int spl;
178} Lock;
179
180enum { /* returned by bootpass */
181 MORE, ENOUGH, FAIL
182};
183enum {
184 INITKERNEL,
185 READEXEC,
186 READ9TEXT,
187 READ9DATA,
188 READGZIP,
189 READEHDR,
190 READPHDR,
191 READEPAD,
192 READEDATA,
193 TRYBOOT,
194 INIT9LOAD,
195 READ9LOAD,
196 FAILED
197};
198
199struct Boot {
200 int state;
201
202 Exec exec;
203 char *bp; /* base ptr */
204 char *wp; /* write ptr */
205 char *ep; /* end ptr */
206};
207
208extern int debug;
209extern Apminfo apm;
210extern char *defaultpartition;
211extern int iniread;
212extern int pxe;
os/boot/pc/devfloppy.c+853−0
@@ -0,0 +1,853 @@
1#include <u.h>
2
3#include "lib.h"
4#include "mem.h"
5#include "dat.h"
6#include "fns.h"
7#include "io.h"
8#include "ureg.h"
9
10#include "fs.h"
11#include "devfloppy.h"
12
13
14/* Intel 82077A (8272A compatible) floppy controller */
15
16/* This module expects the following functions to be defined
17 * elsewhere:
18 *
19 * inb()
20 * outb()
21 * floppyexec()
22 * floppyeject()
23 * floppysetup0()
24 * floppysetup1()
25 * dmainit()
26 * dmasetup()
27 * dmaend()
28 *
29 * On DMA systems, floppyexec() should be an empty function;
30 * on non-DMA systems, dmaend() should be an empty function;
31 * dmasetup() may enforce maximum transfer sizes.
32 */
33
34enum {
35 /* file types */
36 Qdir= 0,
37 Qdata= (1<<2),
38 Qctl= (2<<2),
39 Qmask= (3<<2),
40
41 DMAchan= 2, /* floppy dma channel */
42};
43
44#define DPRINT if(0)print
45
46FType floppytype[] =
47{
48 { "3½HD", T1440kb, 512, 18, 2, 1, 80, 0x1B, 0x54, 0, },
49 { "3½DD", T1440kb, 512, 9, 2, 1, 80, 0x1B, 0x54, 2, },
50 { "3½DD", T720kb, 512, 9, 2, 1, 80, 0x1B, 0x54, 2, },
51 { "5¼HD", T1200kb, 512, 15, 2, 1, 80, 0x2A, 0x50, 0, },
52 { "5¼DD", T1200kb, 512, 9, 2, 2, 40, 0x2A, 0x50, 1, },
53 { "ATT3B1", T1200kb, 512, 8, 2, 2, 48, 0x2A, 0x50, 1, },
54 { "5¼DD", T360kb, 512, 9, 2, 1, 40, 0x2A, 0x50, 2, },
55};
56
57/*
58 * bytes per sector encoding for the controller.
59 * - index for b2c is is (bytes per sector/128).
60 * - index for c2b is code from b2c
61 */
62static int b2c[] =
63{
64[1] 0,
65[2] 1,
66[4] 2,
67[8] 3,
68};
69static int c2b[] =
70{
71 128,
72 256,
73 512,
74 1024,
75};
76
77FController fl;
78
79#define MOTORBIT(i) (1<<((i)+4))
80
81/*
82 * predeclared
83 */
84static int cmddone(void*);
85static void floppyformat(FDrive*, char*);
86static void floppykproc(void*);
87static void floppypos(FDrive*,long);
88static int floppyrecal(FDrive*);
89static int floppyresult(void);
90static void floppyrevive(void);
91static vlong pcfloppyseek(FDrive*, vlong);
92static int floppysense(void);
93static void floppywait(int);
94static long floppyxfer(FDrive*, int, void*, long, long);
95
96static void
97fldump(void)
98{
99 DPRINT("sra %ux srb %ux dor %ux msr %ux dir %ux\n", inb(Psra), inb(Psrb),
100 inb(Pdor), inb(Pmsr), inb(Pdir));
101}
102
103static void
104floppyalarm(Alarm* a)
105{
106 FDrive *dp;
107
108 for(dp = fl.d; dp < &fl.d[fl.ndrive]; dp++){
109 if((fl.motor&MOTORBIT(dp->dev)) && TK2SEC(m->ticks - dp->lasttouched) > 5)
110 floppyoff(dp);
111 }
112
113 alarm(5*1000, floppyalarm, 0);
114 cancel(a);
115}
116
117/*
118 * set floppy drive to its default type
119 */
120static void
121floppysetdef(FDrive *dp)
122{
123 FType *t;
124
125 for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++)
126 if(dp->dt == t->dt){
127 dp->t = t;
128 break;
129 }
130}
131
132static void
133_floppydetach(void)
134{
135 /*
136 * stop the motors
137 */
138 fl.motor = 0;
139 delay(10);
140 outb(Pdor, fl.motor | Fintena | Fena);
141 delay(10);
142}
143
144int
145floppyinit(void)
146{
147 FDrive *dp;
148 FType *t;
149 ulong maxtsize;
150 int mask;
151
152 dmainit(DMAchan);
153
154 floppysetup0(&fl);
155
156 /*
157 * init dependent parameters
158 */
159 maxtsize = 0;
160 for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++){
161 t->cap = t->bytes * t->heads * t->sectors * t->tracks;
162 t->bcode = b2c[t->bytes/128];
163 t->tsize = t->bytes * t->sectors;
164 if(maxtsize < t->tsize)
165 maxtsize = t->tsize;
166 }
167
168 fl.selected = fl.d;
169
170 floppydetach = _floppydetach;
171 floppydetach();
172
173 /*
174 * init drives
175 */
176 mask = 0;
177 for(dp = fl.d; dp < &fl.d[fl.ndrive]; dp++){
178 dp->dev = dp - fl.d;
179 if(dp->dt == Tnone)
180 continue;
181 mask |= 1<<dp->dev;
182 floppysetdef(dp);
183 dp->cyl = -1; /* because we don't know */
184 dp->cache = (uchar*)xspanalloc(maxtsize, BY2PG, 64*1024);
185 dp->ccyl = -1;
186 dp->vers = 0;
187 dp->maxtries = 5;
188 }
189
190 /*
191 * first operation will recalibrate
192 */
193 fl.confused = 1;
194
195 floppysetup1(&fl);
196
197 /* to turn the motor off when inactive */
198 alarm(5*1000, floppyalarm, 0);
199
200 return mask;
201}
202
203void
204floppyinitdev(int i, char *name)
205{
206 if(i >= fl.ndrive)
207 panic("floppyinitdev");
208 sprint(name, "fd%d", i);
209}
210
211void
212floppyprintdevs(int i)
213{
214 if(i >= fl.ndrive)
215 panic("floppyprintdevs");
216 print(" fd%d", i);
217}
218
219int
220floppyboot(int dev, char *file, Boot *b)
221{
222 Fs *fs;
223
224 if(strncmp(file, "dos!", 4) == 0)
225 file += 4;
226 else if(strchr(file, '!') || strcmp(file, "")==0) {
227 print("syntax is fd0!file\n");
228 return -1;
229 }
230
231 fs = floppygetfspart(dev, "dos", 1);
232 if(fs == nil)
233 return -1;
234
235 return fsboot(fs, file, b);
236}
237
238void
239floppyprintbootdevs(int dev)
240{
241 print(" fd%d", dev);
242}
243
244/*
245 * check if the floppy has been replaced under foot. cause
246 * an error if it has.
247 *
248 * a seek and a read clears the condition. this was determined
249 * experimentally, there has to be a better way.
250 *
251 * if the read fails, cycle through the possible floppy
252 * density till one works or we've cycled through all
253 * possibilities for this drive.
254 */
255static int
256changed(FDrive *dp)
257{
258 FType *start;
259
260 /*
261 * if floppy has changed or first time through
262 */
263 if((inb(Pdir)&Fchange) || dp->vers == 0){
264 DPRINT("changed\n");
265 fldump();
266 dp->vers++;
267 floppysetdef(dp);
268 dp->maxtries = 3;
269 start = dp->t;
270
271 /* flopppyon fails if there's no drive */
272 dp->confused = 1; /* make floppyon recal */
273 if(floppyon(dp) < 0)
274 return -1;
275
276 pcfloppyseek(dp, dp->t->heads*dp->t->tsize);
277
278 while(floppyxfer(dp, Fread, dp->cache, 0, dp->t->tsize) <= 0){
279
280 /*
281 * if the xfer attempt doesn't clear the changed bit,
282 * there's no floppy in the drive
283 */
284 if(inb(Pdir)&Fchange)
285 return -1;
286
287 while(++dp->t){
288 if(dp->t == &floppytype[nelem(floppytype)])
289 dp->t = floppytype;
290 if(dp->dt == dp->t->dt)
291 break;
292 }
293
294 /* flopppyon fails if there's no drive */
295 if(floppyon(dp) < 0)
296 return -1;
297
298 DPRINT("changed: trying %s\n", dp->t->name);
299 fldump();
300 if(dp->t == start)
301 return -1;
302 }
303 }
304
305 return 0;
306}
307
308static int
309readtrack(FDrive *dp, int cyl, int head)
310{
311 int i, nn, sofar;
312 ulong pos;
313
314 nn = dp->t->tsize;
315 if(dp->ccyl==cyl && dp->chead==head)
316 return nn;
317 pos = (cyl*dp->t->heads+head) * nn;
318 for(sofar = 0; sofar < nn; sofar += i){
319 dp->ccyl = -1;
320 i = floppyxfer(dp, Fread, dp->cache + sofar, pos + sofar, nn - sofar);
321 if(i <= 0)
322 return -1;
323 }
324 dp->ccyl = cyl;
325 dp->chead = head;
326 return nn;
327}
328
329long
330floppyread(Fs *fs, void *a, long n)
331{
332 FDrive *dp;
333 long rv, offset;
334 int sec, head, cyl;
335 long len;
336 uchar *aa;
337
338 aa = a;
339 dp = &fl.d[fs->dev];
340
341 offset = dp->offset;
342 floppyon(dp);
343 if(changed(dp))
344 return -1;
345
346 for(rv = 0; rv < n; rv += len){
347 /*
348 * all xfers come out of the track cache
349 */
350 dp->len = n - rv;
351 floppypos(dp, offset+rv);
352 cyl = dp->tcyl;
353 head = dp->thead;
354 len = dp->len;
355 sec = dp->tsec;
356 if(readtrack(dp, cyl, head) < 0)
357 break;
358 memmove(aa+rv, dp->cache + (sec-1)*dp->t->bytes, len);
359 }
360 dp->offset = offset+rv;
361
362 return rv;
363}
364
365void*
366floppygetfspart(int i, char *name, int chatty)
367{
368 static Fs fs;
369
370 if(strcmp(name, "dos") != 0){
371 if(chatty)
372 print("unknown partition fd%d!%s (use fd%d!dos)\n", i, name, i);
373 return nil;
374 }
375
376 fs.dev = i;
377 fs.diskread = floppyread;
378 fs.diskseek = floppyseek;
379
380 /* sometimes we get spurious errors and doing it again works */
381 if(dosinit(&fs) < 0 && dosinit(&fs) < 0){
382 if(chatty)
383 print("fd%d!%s does not contain a FAT file system\n", i, name);
384 return nil;
385 }
386 return &fs;
387}
388
389static int
390return0(void*)
391{
392 return 0;
393}
394
395static void
396timedsleep(int (*f)(void*), void* arg, int ms)
397{
398 int s;
399 ulong end;
400
401 end = m->ticks + 1 + MS2TK(ms);
402 while(m->ticks < end && !(*f)(arg)){
403 s = spllo();
404 delay(10);
405 splx(s);
406 }
407}
408
409/*
410 * start a floppy drive's motor.
411 */
412static int
413floppyon(FDrive *dp)
414{
415 int alreadyon;
416 int tries;
417
418 if(fl.confused)
419 floppyrevive();
420
421 /* start motor and select drive */
422 dp->lasttouched = m->ticks;
423 alreadyon = fl.motor & MOTORBIT(dp->dev);
424 if(!alreadyon){
425 fl.motor |= MOTORBIT(dp->dev);
426 outb(Pdor, fl.motor | Fintena | Fena | dp->dev);
427 /* wait for drive to spin up */
428 timedsleep(return0, 0, 750);
429
430 /* clear any pending interrupts */
431 floppysense();
432 }
433
434 /* set transfer rate */
435 if(fl.rate != dp->t->rate){
436 fl.rate = dp->t->rate;
437 outb(Pdsr, fl.rate);
438 }
439
440 /* get drive to a known cylinder */
441 if(dp->confused)
442 for(tries = 0; tries < 4; tries++)
443 if(floppyrecal(dp) >= 0)
444 break;
445 dp->lasttouched = m->ticks;
446 fl.selected = dp;
447 if(dp->confused)
448 return -1;
449 return 0;
450}
451
452/*
453 * stop the floppy if it hasn't been used in 5 seconds
454 */
455static void
456floppyoff(FDrive *dp)
457{
458 fl.motor &= ~MOTORBIT(dp->dev);
459 outb(Pdor, fl.motor | Fintena | Fena | dp->dev);
460}
461
462/*
463 * send a command to the floppy
464 */
465static int
466floppycmd(void)
467{
468 int i;
469 int tries;
470
471 fl.nstat = 0;
472 for(i = 0; i < fl.ncmd; i++){
473 for(tries = 0; ; tries++){
474 if((inb(Pmsr)&(Ffrom|Fready)) == Fready)
475 break;
476 if(tries > 1000){
477 DPRINT("cmd %ux can't be sent (%d)\n", fl.cmd[0], i);
478 fldump();
479
480 /* empty fifo, might have been a bad command */
481 floppyresult();
482 return -1;
483 }
484 microdelay(1);
485 }
486 outb(Pfdata, fl.cmd[i]);
487 }
488 return 0;
489}
490
491/*
492 * get a command result from the floppy
493 *
494 * when the controller goes ready waiting for a command
495 * (instead of sending results), we're done
496 *
497 */
498static int
499floppyresult(void)
500{
501 int i, s;
502 int tries;
503
504 /* get the result of the operation */
505 for(i = 0; i < sizeof(fl.stat); i++){
506 /* wait for status byte */
507 for(tries = 0; ; tries++){
508 s = inb(Pmsr)&(Ffrom|Fready);
509 if(s == Fready){
510 fl.nstat = i;
511 return fl.nstat;
512 }
513 if(s == (Ffrom|Fready))
514 break;
515 if(tries > 1000){
516 DPRINT("floppyresult: %d stats\n", i);
517 fldump();
518 fl.confused = 1;
519 return -1;
520 }
521 microdelay(1);
522 }
523 fl.stat[i] = inb(Pfdata);
524 }
525 fl.nstat = sizeof(fl.stat);
526 return fl.nstat;
527}
528
529/*
530 * calculate physical address of a logical byte offset into the disk
531 *
532 * truncate dp->length if it crosses a track boundary
533 */
534static void
535floppypos(FDrive *dp, long off)
536{
537 int lsec;
538 int ltrack;
539 int end;
540
541 lsec = off/dp->t->bytes;
542 ltrack = lsec/dp->t->sectors;
543 dp->tcyl = ltrack/dp->t->heads;
544 dp->tsec = (lsec % dp->t->sectors) + 1;
545 dp->thead = (lsec/dp->t->sectors) % dp->t->heads;
546
547 /*
548 * can't read across track boundaries.
549 * if so, decrement the bytes to be read.
550 */
551 end = (ltrack+1)*dp->t->sectors*dp->t->bytes;
552 if(off+dp->len > end)
553 dp->len = end - off;
554}
555
556/*
557 * get the interrupt cause from the floppy.
558 */
559static int
560floppysense(void)
561{
562 fl.ncmd = 0;
563 fl.cmd[fl.ncmd++] = Fsense;
564 if(floppycmd() < 0)
565 return -1;
566 if(floppyresult() < 2){
567 DPRINT("can't read sense response\n");
568 fldump();
569 fl.confused = 1;
570 return -1;
571 }
572 return 0;
573}
574
575static int
576cmddone(void *a)
577{
578 USED(a);
579 return fl.ncmd == 0;
580}
581
582/*
583 * Wait for a floppy interrupt. If none occurs in 5 seconds, we
584 * may have missed one. This only happens on some portables which
585 * do power management behind our backs. Call the interrupt
586 * routine to try to clear any conditions.
587 */
588static void
589floppywait(int slow)
590{
591 timedsleep(cmddone, 0, slow ? 5000 : 1000);
592 if(!cmddone(0)){
593 floppyintr(0);
594 fl.confused = 1;
595 }
596}
597
598/*
599 * we've lost the floppy position, go to cylinder 0.
600 */
601static int
602floppyrecal(FDrive *dp)
603{
604 dp->ccyl = -1;
605 dp->cyl = -1;
606
607 fl.ncmd = 0;
608 fl.cmd[fl.ncmd++] = Frecal;
609 fl.cmd[fl.ncmd++] = dp->dev;
610 if(floppycmd() < 0)
611 return -1;
612 floppywait(1);
613 if(fl.nstat < 2){
614 DPRINT("recalibrate: confused %ux\n", inb(Pmsr));
615 fl.confused = 1;
616 return -1;
617 }
618 if((fl.stat[0] & (Codemask|Seekend)) != Seekend){
619 DPRINT("recalibrate: failed\n");
620 dp->confused = 1;
621 return -1;
622 }
623 dp->cyl = fl.stat[1];
624 if(dp->cyl != 0){
625 DPRINT("recalibrate: wrong cylinder %d\n", dp->cyl);
626 dp->cyl = -1;
627 dp->confused = 1;
628 return -1;
629 }
630
631 dp->confused = 0;
632 return 0;
633}
634
635/*
636 * if the controller or a specific drive is in a confused state,
637 * reset it and get back to a kown state
638 */
639static void
640floppyrevive(void)
641{
642 FDrive *dp;
643
644 /*
645 * reset the controller if it's confused
646 */
647 if(fl.confused){
648 DPRINT("floppyrevive in\n");
649 fldump();
650
651 /* reset controller and turn all motors off */
652 splhi();
653 fl.ncmd = 1;
654 fl.cmd[0] = 0;
655 outb(Pdor, 0);
656 delay(10);
657 outb(Pdor, Fintena|Fena);
658 delay(10);
659 spllo();
660 fl.motor = 0;
661 fl.confused = 0;
662 floppywait(0);
663
664 /* mark all drives in an unknown state */
665 for(dp = fl.d; dp < &fl.d[fl.ndrive]; dp++)
666 dp->confused = 1;
667
668 /* set rate to a known value */
669 outb(Pdsr, 0);
670 fl.rate = 0;
671
672 DPRINT("floppyrevive out\n");
673 fldump();
674 }
675}
676
677/*
678 * seek to the target cylinder
679 *
680 * interrupt, no results
681 */
682static vlong
683pcfloppyseek(FDrive *dp, vlong off)
684{
685 floppypos(dp, off);
686 if(dp->cyl == dp->tcyl){
687 dp->offset = off;
688 return off;
689 }
690 dp->cyl = -1;
691
692 fl.ncmd = 0;
693 fl.cmd[fl.ncmd++] = Fseek;
694 fl.cmd[fl.ncmd++] = (dp->thead<<2) | dp->dev;
695 fl.cmd[fl.ncmd++] = dp->tcyl * dp->t->steps;
696 if(floppycmd() < 0)
697 return -1;
698 floppywait(1);
699 if(fl.nstat < 2){
700 DPRINT("seek: confused\n");
701 fl.confused = 1;
702 return -1;
703 }
704 if((fl.stat[0] & (Codemask|Seekend)) != Seekend){
705 DPRINT("seek: failed\n");
706 dp->confused = 1;
707 return -1;
708 }
709
710 dp->cyl = dp->tcyl;
711 dp->offset = off;
712 DPRINT("seek to %d succeeded\n", dp->offset);
713
714 return dp->offset;
715}
716
717/*
718 * read or write to floppy. try up to three times.
719 */
720static long
721floppyxfer(FDrive *dp, int cmd, void *a, long off, long n)
722{
723 long offset;
724 int tries;
725
726 if(off >= dp->t->cap)
727 return 0;
728 if(off + n > dp->t->cap)
729 n = dp->t->cap - off;
730
731 /* retry on error (until it gets ridiculous) */
732 for(tries = 0; tries < dp->maxtries; tries++){
733
734 dp->len = n;
735 if(pcfloppyseek(dp, off) < 0){
736 DPRINT("xfer: seek failed\n");
737 dp->confused = 1;
738 continue;
739 }
740
741 /*
742 * set up the dma (dp->len may be trimmed)
743 */
744 dp->len = dmasetup(DMAchan, a, dp->len, cmd==Fread);
745 if(dp->len < 0){
746 buggery:
747 dmaend(DMAchan);
748 continue;
749 }
750
751 /*
752 * start operation
753 */
754 fl.ncmd = 0;
755 fl.cmd[fl.ncmd++] = cmd | (dp->t->heads > 1 ? Fmulti : 0);
756 fl.cmd[fl.ncmd++] = (dp->thead<<2) | dp->dev;
757 fl.cmd[fl.ncmd++] = dp->tcyl;
758 fl.cmd[fl.ncmd++] = dp->thead;
759 fl.cmd[fl.ncmd++] = dp->tsec;
760 fl.cmd[fl.ncmd++] = dp->t->bcode;
761 fl.cmd[fl.ncmd++] = dp->t->sectors;
762 fl.cmd[fl.ncmd++] = dp->t->gpl;
763 fl.cmd[fl.ncmd++] = 0xFF;
764 if(floppycmd() < 0)
765 goto buggery;
766
767 /*
768 * give bus to DMA, floppyintr() will read result
769 */
770 floppywait(0);
771 dmaend(DMAchan);
772
773 /*
774 * check for errors
775 */
776 if(fl.nstat < 7){
777 DPRINT("xfer: confused\n");
778 fl.confused = 1;
779 continue;
780 }
781 if((fl.stat[0] & Codemask)!=0 || fl.stat[1] || fl.stat[2]){
782 DPRINT("xfer: failed %ux %ux %ux\n", fl.stat[0],
783 fl.stat[1], fl.stat[2]);
784 DPRINT("offset %lud len %ld\n", off, dp->len);
785 if((fl.stat[0]&Codemask)==Cmdexec && fl.stat[1]==Overrun){
786 DPRINT("DMA overrun: retry\n");
787 } else
788 dp->confused = 1;
789 continue;
790 }
791
792 /*
793 * check for correct cylinder
794 */
795 offset = fl.stat[3] * dp->t->heads + fl.stat[4];
796 offset = offset*dp->t->sectors + fl.stat[5] - 1;
797 offset = offset * c2b[fl.stat[6]];
798 if(offset != off+dp->len){
799 DPRINT("xfer: ends on wrong cyl\n");
800 dp->confused = 1;
801 continue;
802 }
803
804 dp->lasttouched = m->ticks;
805 dp->maxtries = 20;
806 return dp->len;
807 }
808
809 return -1;
810}
811
812/*
813void
814floppymemwrite(void)
815{
816 int i;
817 int n;
818 uchar *a;
819 FDrive *dp;
820
821 dp = &fl.d[0];
822 a = (uchar*)0x80000000;
823 n = 0;
824 while(n < 1440*1024){
825 i = floppyxfer(dp, Fwrite, a+n, n, 1440*1024-n);
826 if(i <= 0)
827 break;
828 n += i;
829 }
830 print("floppymemwrite wrote %d bytes\n", n);
831splhi(); for(;;);
832}
833*/
834
835static void
836floppyintr(Ureg *ur)
837{
838 USED(ur);
839 switch(fl.cmd[0]&~Fmulti){
840 case Fread:
841 case Fwrite:
842 case Fformat:
843 case Fdumpreg:
844 floppyresult();
845 break;
846 case Fseek:
847 case Frecal:
848 default:
849 floppysense(); /* to clear interrupt */
850 break;
851 }
852 fl.ncmd = 0;
853}
os/boot/pc/devfloppy.h+196−0
@@ -0,0 +1,196 @@
1typedef struct FController FController;
2typedef struct FDrive FDrive;
3typedef struct FType FType;
4
5static void floppyintr(Ureg*);
6static int floppyon(FDrive*);
7static void floppyoff(FDrive*);
8static void floppysetdef(FDrive*);
9
10/*
11 * a floppy drive
12 */
13struct FDrive
14{
15 FType *t; /* floppy type */
16 int dt; /* drive type */
17 int dev;
18
19 ulong lasttouched; /* time last touched */
20 int cyl; /* current arm position */
21 int confused; /* needs to be recalibrated */
22 int offset; /* current offset */
23 int vers;
24 int maxtries;
25
26 int tcyl; /* target cylinder */
27 int thead; /* target head */
28 int tsec; /* target sector */
29 long len; /* size of xfer */
30
31 uchar *cache; /* track cache */
32 int ccyl;
33 int chead;
34
35// Rendez r; /* waiting here for motor to spin up */
36 void *aux;
37};
38
39/*
40 * controller for 4 floppys
41 */
42struct FController
43{
44// QLock; /* exclusive access to the contoller */
45
46 int ndrive;
47 FDrive *d; /* the floppy drives */
48 FDrive *selected;
49 int rate; /* current rate selected */
50 uchar cmd[14]; /* command */
51 int ncmd; /* # command bytes */
52 uchar stat[14]; /* command status */
53 int nstat; /* # status bytes */
54 int confused; /* controler needs to be reset */
55// Rendez r; /* wait here for command termination */
56 int motor; /* bit mask of spinning disks */
57// Rendez kr; /* for motor watcher */
58};
59
60/*
61 * floppy types (all MFM encoding)
62 */
63struct FType
64{
65 char *name;
66 int dt; /* compatible drive type */
67 int bytes; /* bytes/sector */
68 int sectors; /* sectors/track */
69 int heads; /* number of heads */
70 int steps; /* steps per cylinder */
71 int tracks; /* tracks/disk */
72 int gpl; /* intersector gap length for read/write */
73 int fgpl; /* intersector gap length for format */
74 int rate; /* rate code */
75
76 /*
77 * these depend on previous entries and are set filled in
78 * by floppyinit
79 */
80 int bcode; /* coded version of bytes for the controller */
81 long cap; /* drive capacity in bytes */
82 long tsize; /* track size in bytes */
83};
84/* bits in the registers */
85enum
86{
87 /* status registers a & b */
88 Psra= 0x3f0,
89 Psrb= 0x3f1,
90
91 /* digital output register */
92 Pdor= 0x3f2,
93 Fintena= 0x8, /* enable floppy interrupt */
94 Fena= 0x4, /* 0 == reset controller */
95
96 /* main status register */
97 Pmsr= 0x3f4,
98 Fready= 0x80, /* ready to be touched */
99 Ffrom= 0x40, /* data from controller */
100 Ffloppybusy= 0x10, /* operation not over */
101
102 /* data register */
103 Pfdata= 0x3f5,
104 Frecal= 0x07, /* recalibrate cmd */
105 Fseek= 0x0f, /* seek cmd */
106 Fsense= 0x08, /* sense cmd */
107 Fread= 0x66, /* read cmd */
108 Freadid= 0x4a, /* read track id */
109 Fspec= 0x03, /* set hold times */
110 Fwrite= 0x45, /* write cmd */
111 Fformat= 0x4d, /* format cmd */
112 Fmulti= 0x80, /* or'd with Fread or Fwrite for multi-head */
113 Fdumpreg= 0x0e, /* dump internal registers */
114
115 /* digital input register */
116 Pdir= 0x3F7, /* disk changed port (read only) */
117 Pdsr= 0x3F7, /* data rate select port (write only) */
118 Fchange= 0x80, /* disk has changed */
119
120 /* status 0 byte */
121 Drivemask= 3<<0,
122 Seekend= 1<<5,
123 Codemask= (3<<6)|(3<<3),
124 Cmdexec= 1<<6,
125
126 /* status 1 byte */
127 Overrun= 0x10,
128};
129
130/*
131 * types of drive (from PC equipment byte)
132 */
133enum
134{
135 Tnone= 0,
136 T360kb= 1,
137 T1200kb= 2,
138 T720kb= 3,
139 T1440kb= 4,
140};
141
142static void
143pcfloppyintr(Ureg *ur, void *a)
144{
145 USED(a);
146
147 floppyintr(ur);
148}
149
150void
151floppysetup0(FController *fl)
152{
153 uchar equip;
154
155 /*
156 * Read nvram for types of floppies 0 & 1.
157 * Always try floppy 0.
158 */
159 equip = nvramread(0x10);
160 fl->ndrive = 1;
161
162 if(equip & 0xf)
163 fl->ndrive++;
164
165 /*
166 * Allocate the drive storage.
167 * There's always one.
168 */
169 fl->d = xalloc(fl->ndrive*sizeof(FDrive));
170 fl->d[0].dt = (equip >> 4) & 0xf;
171 if(fl->d[0].dt == Tnone)
172 fl->d[0].dt = T1440kb;
173
174 if(fl->ndrive == 2)
175 fl->d[1].dt = equip & 0xf;
176}
177
178void
179floppysetup1(FController*)
180{
181// intrenable(VectorFLOPPY, pcfloppyintr, fl, BUSUNKNOWN);
182 setvec(VectorFLOPPY, pcfloppyintr, 0);
183}
184
185
186static vlong pcfloppyseek(FDrive*, vlong);
187FController fl;
188
189vlong
190floppyseek(Fs *fs, vlong off)
191{
192 FDrive *dp;
193
194 dp = &fl.d[fs->dev];
195 return pcfloppyseek(dp, off);
196}
os/boot/pc/devi82365.c+1205−0
@@ -0,0 +1,1205 @@
1#include "u.h"
2#include "lib.h"
3#include "mem.h"
4#include "dat.h"
5#include "fns.h"
6#include "error.h"
7#include "io.h"
8
9/*
10 * Support for up to 4 Slot card slots. Generalizing above that is hard
11 * since addressing is not obvious. - presotto
12 *
13 * WARNING: This has never been tried with more than one card slot.
14 */
15
16/*
17 * Intel 82365SL PCIC controller for the PCMCIA or
18 * Cirrus Logic PD6710/PD6720 which is mostly register compatible
19 */
20enum
21{
22 /*
23 * registers indices
24 */
25 Rid= 0x0, /* identification and revision */
26 Ris= 0x1, /* interface status */
27 Rpc= 0x2, /* power control */
28 Foutena= (1<<7), /* output enable */
29 Fautopower= (1<<5), /* automatic power switching */
30 Fcardena= (1<<4), /* PC card enable */
31 Rigc= 0x3, /* interrupt and general control */
32 Fiocard= (1<<5), /* I/O card (vs memory) */
33 Fnotreset= (1<<6), /* reset if not set */
34 FSMIena= (1<<4), /* enable change interrupt on SMI */
35 Rcsc= 0x4, /* card status change */
36 Rcscic= 0x5, /* card status change interrupt config */
37 Fchangeena= (1<<3), /* card changed */
38 Fbwarnena= (1<<1), /* card battery warning */
39 Fbdeadena= (1<<0), /* card battery dead */
40 Rwe= 0x6, /* address window enable */
41 Fmem16= (1<<5), /* use A23-A12 to decode address */
42 Rio= 0x7, /* I/O control */
43 Fwidth16= (1<<0), /* 16 bit data width */
44 Fiocs16= (1<<1), /* IOCS16 determines data width */
45 Fzerows= (1<<2), /* zero wait state */
46 Ftiming= (1<<3), /* timing register to use */
47 Riobtm0lo= 0x8, /* I/O address 0 start low byte */
48 Riobtm0hi= 0x9, /* I/O address 0 start high byte */
49 Riotop0lo= 0xa, /* I/O address 0 stop low byte */
50 Riotop0hi= 0xb, /* I/O address 0 stop high byte */
51 Riobtm1lo= 0xc, /* I/O address 1 start low byte */
52 Riobtm1hi= 0xd, /* I/O address 1 start high byte */
53 Riotop1lo= 0xe, /* I/O address 1 stop low byte */
54 Riotop1hi= 0xf, /* I/O address 1 stop high byte */
55 Rmap= 0x10, /* map 0 */
56
57 /*
58 * CL-PD67xx extension registers
59 */
60 Rmisc1= 0x16, /* misc control 1 */
61 F5Vdetect= (1<<0),
62 Fvcc3V= (1<<1),
63 Fpmint= (1<<2),
64 Fpsirq= (1<<3),
65 Fspeaker= (1<<4),
66 Finpack= (1<<7),
67 Rfifo= 0x17, /* fifo control */
68 Fflush= (1<<7), /* flush fifo */
69 Rmisc2= 0x1E, /* misc control 2 */
70 Flowpow= (1<<1), /* low power mode */
71 Rchipinfo= 0x1F, /* chip information */
72 Ratactl= 0x26, /* ATA control */
73
74 /*
75 * offsets into the system memory address maps
76 */
77 Mbtmlo= 0x0, /* System mem addr mapping start low byte */
78 Mbtmhi= 0x1, /* System mem addr mapping start high byte */
79 F16bit= (1<<7), /* 16-bit wide data path */
80 Mtoplo= 0x2, /* System mem addr mapping stop low byte */
81 Mtophi= 0x3, /* System mem addr mapping stop high byte */
82 Ftimer1= (1<<6), /* timer set 1 */
83 Mofflo= 0x4, /* Card memory offset address low byte */
84 Moffhi= 0x5, /* Card memory offset address high byte */
85 Fregactive= (1<<6), /* attribute memory */
86
87 Mbits= 13, /* msb of Mchunk */
88 Mchunk= 1<<Mbits, /* logical mapping granularity */
89 Nmap= 4, /* max number of maps to use */
90
91 /*
92 * configuration registers - they start at an offset in attribute
93 * memory found in the CIS.
94 */
95 Rconfig= 0,
96 Creset= (1<<7), /* reset device */
97 Clevel= (1<<6), /* level sensitive interrupt line */
98
99 Maxctab= 8, /* maximum configuration table entries */
100};
101
102static int pcmcia_pcmspecial(char *, ISAConf *);
103static void pcmcia_pcmspecialclose(int);
104
105#define MAP(x,o) (Rmap + (x)*0x8 + o)
106
107typedef struct I82365 I82365;
108typedef struct Slot Slot;
109typedef struct Conftab Conftab;
110typedef struct Cisdat Cisdat;
111/* a controller */
112enum
113{
114 Ti82365,
115 Tpd6710,
116 Tpd6720,
117 Tvg46x,
118};
119struct I82365
120{
121 int type;
122 int dev;
123 int nslot;
124 int xreg; /* index register address */
125 int dreg; /* data register address */
126 int irq;
127};
128static I82365 *controller[4];
129static int ncontroller;
130
131/* configuration table entry */
132struct Conftab
133{
134 int index;
135 ushort irqs; /* legal irqs */
136 uchar irqtype;
137 uchar bit16; /* true for 16 bit access */
138 struct {
139 ulong start;
140 ulong len;
141 } io[16];
142 int nio;
143 uchar vpp1;
144 uchar vpp2;
145 uchar memwait;
146 ulong maxwait;
147 ulong readywait;
148 ulong otherwait;
149};
150
151/* cis memory walking */
152struct Cisdat
153{
154 uchar *cisbase;
155 int cispos;
156 int cisskip;
157 int cislen;
158};
159
160/* a card slot */
161struct Slot
162{
163 Lock;
164 int ref;
165
166 I82365 *cp; /* controller for this slot */
167 long memlen; /* memory length */
168 uchar base; /* index register base */
169 uchar slotno; /* slot number */
170
171 /* status */
172 uchar special; /* in use for a special device */
173 uchar already; /* already inited */
174 uchar occupied;
175 uchar battery;
176 uchar wrprot;
177 uchar powered;
178 uchar configed;
179 uchar enabled;
180 uchar busy;
181
182 /* cis info */
183 char verstr[512]; /* version string */
184 uchar cpresent; /* config registers present */
185 ulong caddr; /* relative address of config registers */
186 int nctab; /* number of config table entries */
187 Conftab ctab[Maxctab];
188 Conftab *def; /* default conftab */
189
190 /* for walking through cis */
191 Cisdat;
192
193 /* memory maps */
194 Lock mlock; /* lock down the maps */
195 int time;
196 PCMmap mmap[Nmap]; /* maps, last is always for the kernel */
197};
198static Slot *slot;
199static Slot *lastslot;
200static nslot;
201
202static void cisread(Slot*);
203static void i82365intr(Ureg*, void*);
204static void i82365reset(void);
205static int pcmio(int, ISAConf*);
206static long pcmread(int, int, void*, long, vlong);
207static long pcmwrite(int, int, void*, long, vlong);
208
209static void i82365dump(Slot*);
210
211void
212devi82365link(void)
213{
214 static int already;
215
216 if(already)
217 return;
218 already = 1;
219
220 if (_pcmspecial)
221 return;
222
223 _pcmspecial = pcmcia_pcmspecial;
224 _pcmspecialclose = pcmcia_pcmspecialclose;
225}
226
227/*
228 * reading and writing card registers
229 */
230static uchar
231rdreg(Slot *pp, int index)
232{
233 outb(pp->cp->xreg, pp->base + index);
234 return inb(pp->cp->dreg);
235}
236static void
237wrreg(Slot *pp, int index, uchar val)
238{
239 outb(pp->cp->xreg, pp->base + index);
240 outb(pp->cp->dreg, val);
241}
242
243/*
244 * get info about card
245 */
246static void
247slotinfo(Slot *pp)
248{
249 uchar isr;
250
251 isr = rdreg(pp, Ris);
252 pp->occupied = (isr & (3<<2)) == (3<<2);
253 pp->powered = isr & (1<<6);
254 pp->battery = (isr & 3) == 3;
255 pp->wrprot = isr & (1<<4);
256 pp->busy = isr & (1<<5);
257}
258
259static int
260vcode(int volt)
261{
262 switch(volt){
263 case 5:
264 return 1;
265 case 12:
266 return 2;
267 default:
268 return 0;
269 }
270}
271
272/*
273 * enable the slot card
274 */
275static void
276slotena(Slot *pp)
277{
278 if(pp->enabled)
279 return;
280
281 /* power up and unreset, wait's are empirical (???) */
282 wrreg(pp, Rpc, Fautopower|Foutena|Fcardena);
283 delay(300);
284 wrreg(pp, Rigc, 0);
285 delay(100);
286 wrreg(pp, Rigc, Fnotreset);
287 delay(500);
288
289 /* get configuration */
290 slotinfo(pp);
291 if(pp->occupied){
292 cisread(pp);
293 pp->enabled = 1;
294 } else
295 wrreg(pp, Rpc, Fautopower);
296}
297
298/*
299 * disable the slot card
300 */
301static void
302slotdis(Slot *pp)
303{
304 wrreg(pp, Rpc, 0); /* turn off card power */
305 wrreg(pp, Rwe, 0); /* no windows */
306 pp->enabled = 0;
307}
308
309/*
310 * status change interrupt
311 */
312static void
313i82365intr(Ureg *, void *)
314{
315 uchar csc, was;
316 Slot *pp;
317
318 if(slot == 0)
319 return;
320
321 for(pp = slot; pp < lastslot; pp++){
322 csc = rdreg(pp, Rcsc);
323 was = pp->occupied;
324 slotinfo(pp);
325 if(csc & (1<<3) && was != pp->occupied){
326 if(!pp->occupied)
327 slotdis(pp);
328 }
329 }
330}
331
332enum
333{
334 Mshift= 12,
335 Mgran= (1<<Mshift), /* granularity of maps */
336 Mmask= ~(Mgran-1), /* mask for address bits important to the chip */
337};
338
339/*
340 * get a map for pc card region, return corrected len
341 */
342PCMmap*
343pcmmap(int slotno, ulong offset, int len, int attr)
344{
345 Slot *pp;
346 uchar we, bit;
347 PCMmap *m, *nm;
348 int i;
349 ulong e;
350
351 pp = slot + slotno;
352 lock(&pp->mlock);
353
354 /* convert offset to granularity */
355 if(len <= 0)
356 len = 1;
357 e = ROUND(offset+len, Mgran);
358 offset &= Mmask;
359 len = e - offset;
360
361 /* look for a map that covers the right area */
362 we = rdreg(pp, Rwe);
363 bit = 1;
364 nm = 0;
365 for(m = pp->mmap; m < &pp->mmap[Nmap]; m++){
366 if((we & bit))
367 if(m->attr == attr)
368 if(offset >= m->ca && e <= m->cea){
369
370 m->ref++;
371 unlock(&pp->mlock);
372 return m;
373 }
374 bit <<= 1;
375 if(nm == 0 && m->ref == 0)
376 nm = m;
377 }
378 m = nm;
379 if(m == 0){
380 unlock(&pp->mlock);
381 return 0;
382 }
383
384 /* if isa space isn't big enough, free it and get more */
385 if(m->len < len){
386 if(m->isa){
387 umbfree(m->isa, m->len);
388 m->len = 0;
389 }
390 m->isa = PADDR(umbmalloc(0, len, Mgran));
391 if(m->isa == 0){
392 print("pcmmap %d: out of isa space\n", len);
393 unlock(&pp->mlock);
394 return 0;
395 }
396 m->len = len;
397 }
398
399 /* set up new map */
400 m->ca = offset;
401 m->cea = m->ca + m->len;
402 m->attr = attr;
403 i = m-pp->mmap;
404 bit = 1<<i;
405 wrreg(pp, Rwe, we & ~bit); /* disable map before changing it */
406 wrreg(pp, MAP(i, Mbtmlo), m->isa>>Mshift);
407 wrreg(pp, MAP(i, Mbtmhi), (m->isa>>(Mshift+8)) | F16bit);
408 wrreg(pp, MAP(i, Mtoplo), (m->isa+m->len-1)>>Mshift);
409 wrreg(pp, MAP(i, Mtophi), ((m->isa+m->len-1)>>(Mshift+8)));
410 offset -= m->isa;
411 offset &= (1<<25)-1;
412 offset >>= Mshift;
413 wrreg(pp, MAP(i, Mofflo), offset);
414 wrreg(pp, MAP(i, Moffhi), (offset>>8) | (attr ? Fregactive : 0));
415 wrreg(pp, Rwe, we | bit); /* enable map */
416 m->ref = 1;
417
418 unlock(&pp->mlock);
419 return m;
420}
421
422void
423pcmunmap(int slotno, PCMmap* m)
424{
425 Slot *pp;
426
427 pp = slot + slotno;
428 lock(&pp->mlock);
429 m->ref--;
430 unlock(&pp->mlock);
431}
432
433static void
434increfp(Slot *pp)
435{
436 lock(pp);
437 if(pp->ref++ == 0)
438 slotena(pp);
439 unlock(pp);
440}
441
442static void
443decrefp(Slot *pp)
444{
445 lock(pp);
446 if(pp->ref-- == 1)
447 slotdis(pp);
448 unlock(pp);
449}
450
451/*
452 * look for a card whose version contains 'idstr'
453 */
454static int
455pcmcia_pcmspecial(char *idstr, ISAConf *isa)
456{
457 Slot *pp;
458 extern char *strstr(char*, char*);
459 int enabled;
460
461 i82365reset();
462 for(pp = slot; pp < lastslot; pp++){
463 if(pp->special)
464 continue; /* already taken */
465 enabled = 0;
466 /* make sure we don't power on cards when we already know what's
467 * in them. We'll reread every two minutes if necessary
468 */
469 if (pp->verstr[0] == '\0') {
470 increfp(pp);
471 enabled++;
472 }
473
474 if(pp->occupied) {
475 if(strstr(pp->verstr, idstr)) {
476 if (!enabled)
477 increfp(pp);
478 if(isa == 0 || pcmio(pp->slotno, isa) == 0){
479 pp->special = 1;
480 return pp->slotno;
481 }
482 }
483 } else
484 pp->special = 1;
485 if (enabled)
486 decrefp(pp);
487 }
488 return -1;
489}
490
491static void
492pcmcia_pcmspecialclose(int slotno)
493{
494 Slot *pp;
495
496 print("pcmspecialclose called\n");
497 if(slotno >= nslot)
498 panic("pcmspecialclose");
499 pp = slot + slotno;
500 pp->special = 0;
501 decrefp(pp);
502}
503
504static char *chipname[] =
505{
506[Ti82365] "Intel 82365SL",
507[Tpd6710] "Cirrus Logic PD6710",
508[Tpd6720] "Cirrus Logic PD6720",
509[Tvg46x] "Vadem VG-46x",
510};
511
512static I82365*
513i82365probe(int x, int d, int dev)
514{
515 uchar c, id;
516 I82365 *cp;
517 ISAConf isa;
518 int i, nslot;
519
520 outb(x, Rid + (dev<<7));
521 id = inb(d);
522 if((id & 0xf0) != 0x80)
523 return 0; /* not this family */
524
525 cp = xalloc(sizeof(I82365));
526 cp->xreg = x;
527 cp->dreg = d;
528 cp->dev = dev;
529 cp->type = Ti82365;
530 cp->nslot = 2;
531
532 switch(id){
533 case 0x82:
534 case 0x83:
535 case 0x84:
536 /* could be a cirrus */
537 outb(x, Rchipinfo + (dev<<7));
538 outb(d, 0);
539 c = inb(d);
540 if((c & 0xc0) != 0xc0)
541 break;
542 c = inb(d);
543 if((c & 0xc0) != 0x00)
544 break;
545 if(c & 0x20){
546 cp->type = Tpd6720;
547 } else {
548 cp->type = Tpd6710;
549 cp->nslot = 1;
550 }
551
552 /* low power mode */
553 outb(x, Rmisc2 + (dev<<7));
554 c = inb(d);
555 outb(d, c & ~Flowpow);
556 break;
557 }
558
559 if(cp->type == Ti82365){
560 outb(x, 0x0E + (dev<<7));
561 outb(x, 0x37 + (dev<<7));
562 outb(x, 0x3A + (dev<<7));
563 c = inb(d);
564 outb(d, c|0xC0);
565 outb(x, Rid + (dev<<7));
566 c = inb(d);
567 if(c != id && !(c & 0x08))
568 print("#y%d: id %uX changed to %uX\n", ncontroller, id, c);
569 if(c & 0x08)
570 cp->type = Tvg46x;
571 outb(x, 0x3A + (dev<<7));
572 c = inb(d);
573 outb(d, c & ~0xC0);
574 }
575
576 memset(&isa, 0, sizeof(ISAConf));
577 if(isaconfig("pcmcia", ncontroller, &isa) && isa.irq)
578 cp->irq = isa.irq;
579 else
580 cp->irq = VectorPCMCIA - VectorPIC;
581
582 for(i = 0; i < isa.nopt; i++){
583 if(cistrncmp(isa.opt[i], "nslot=", 6))
584 continue;
585 nslot = strtol(&isa.opt[i][6], nil, 0);
586 if(nslot > 0 && nslot <= 2)
587 cp->nslot = nslot;
588 }
589
590 controller[ncontroller++] = cp;
591 return cp;
592}
593
594static void
595i82365dump(Slot *pp)
596{
597 int i;
598
599 for(i = 0; i < 0x40; i++){
600 if((i&0x0F) == 0)
601 print("\n%2.2uX: ", i);
602 if(((i+1) & 0x0F) == 0x08)
603 print(" - ");
604 print("%2.2uX ", rdreg(pp, i));
605 }
606 print("\n");
607}
608
609/*
610 * set up for slot cards
611 */
612static void
613i82365reset(void)
614{
615 static int already;
616 int i, j;
617 I82365 *cp;
618 Slot *pp;
619
620 if(already)
621 return;
622 already = 1;
623
624
625 /* look for controllers */
626 i82365probe(0x3E0, 0x3E1, 0);
627 i82365probe(0x3E0, 0x3E1, 1);
628 i82365probe(0x3E2, 0x3E3, 0);
629 i82365probe(0x3E2, 0x3E3, 1);
630
631 for(i = 0; i < ncontroller; i++)
632 nslot += controller[i]->nslot;
633 slot = xalloc(nslot * sizeof(Slot));
634
635 /* if the card is there turn on 5V power to keep its battery alive */
636 lastslot = slot;
637 for(i = 0; i < ncontroller; i++){
638 cp = controller[i];
639 print("#y%d: %d slot %s: port 0x%uX irq %d\n",
640 i, cp->nslot, chipname[cp->type], cp->xreg, cp->irq);
641 for(j = 0; j < cp->nslot; j++){
642 pp = lastslot++;
643 pp->slotno = pp - slot;
644 pp->memlen = 64*MB;
645 pp->base = (cp->dev<<7) | (j<<6);
646 pp->cp = cp;
647 slotdis(pp);
648
649 /* interrupt on status change */
650 wrreg(pp, Rcscic, (cp->irq<<4) | Fchangeena);
651 rdreg(pp, Rcsc);
652 }
653
654 /* for card management interrupts */
655 setvec(cp->irq+VectorPIC, i82365intr, 0);
656 }
657}
658
659/*
660 * configure the Slot for IO. We assume very heavily that we can read
661 * configuration info from the CIS. If not, we won't set up correctly.
662 */
663static int
664pcmio(int slotno, ISAConf *isa)
665{
666 uchar we, x, *p;
667 Slot *pp;
668 Conftab *ct, *et, *t;
669 PCMmap *m;
670 int i, index, irq;
671 char *cp;
672
673 irq = isa->irq;
674 if(irq == 2)
675 irq = 9;
676
677 if(slotno > nslot)
678 return -1;
679 pp = slot + slotno;
680
681 if(!pp->occupied)
682 return -1;
683
684 et = &pp->ctab[pp->nctab];
685
686 ct = 0;
687 for(i = 0; i < isa->nopt; i++){
688 if(strncmp(isa->opt[i], "index=", 6))
689 continue;
690 index = strtol(&isa->opt[i][6], &cp, 0);
691 if(cp == &isa->opt[i][6] || index >= pp->nctab)
692 return -1;
693 ct = &pp->ctab[index];
694 }
695 if(ct == 0){
696
697 /* assume default is right */
698 if(pp->def)
699 ct = pp->def;
700 else
701 ct = pp->ctab;
702
703 /* try for best match */
704 if(ct->nio == 0
705 || ct->io[0].start != isa->port || ((1<<irq) & ct->irqs) == 0){
706 for(t = pp->ctab; t < et; t++)
707 if(t->nio
708 && t->io[0].start == isa->port
709 && ((1<<irq) & t->irqs)){
710 ct = t;
711 break;
712 }
713 }
714 if(ct->nio == 0 || ((1<<irq) & ct->irqs) == 0){
715 for(t = pp->ctab; t < et; t++)
716 if(t->nio && ((1<<irq) & t->irqs)){
717 ct = t;
718 break;
719 }
720 }
721 if(ct->nio == 0){
722 for(t = pp->ctab; t < et; t++)
723 if(t->nio){
724 ct = t;
725 break;
726 }
727 }
728 }
729
730 if(ct == et || ct->nio == 0)
731 return -1;
732 if(isa->port == 0 && ct->io[0].start == 0)
733 return -1;
734
735 /* route interrupts */
736 isa->irq = irq;
737 wrreg(pp, Rigc, irq | Fnotreset | Fiocard);
738
739 /* set power and enable device */
740 x = vcode(ct->vpp1);
741 wrreg(pp, Rpc, x|Fautopower|Foutena|Fcardena);
742
743 /* 16-bit data path */
744 if(ct->bit16)
745 x = Ftiming|Fiocs16|Fwidth16;
746 else
747 x = Ftiming;
748 if(ct->nio == 2 && ct->io[1].start)
749 x |= x<<4;
750 wrreg(pp, Rio, x);
751
752 /* enable io port map 0 */
753 if(isa->port == 0)
754 isa->port = ct->io[0].start;
755 we = rdreg(pp, Rwe);
756 wrreg(pp, Riobtm0lo, isa->port);
757 wrreg(pp, Riobtm0hi, isa->port>>8);
758 i = isa->port+ct->io[0].len-1;
759 wrreg(pp, Riotop0lo, i);
760 wrreg(pp, Riotop0hi, i>>8);
761 we |= 1<<6;
762 if(ct->nio == 2 && ct->io[1].start){
763 wrreg(pp, Riobtm1lo, ct->io[1].start);
764 wrreg(pp, Riobtm1hi, ct->io[1].start>>8);
765 i = ct->io[1].start+ct->io[1].len-1;
766 wrreg(pp, Riotop1lo, i);
767 wrreg(pp, Riotop1hi, i>>8);
768 we |= 1<<7;
769 }
770 wrreg(pp, Rwe, we);
771
772 /* only touch Rconfig if it is present */
773 if(pp->cpresent & (1<<Rconfig)){
774 /* Reset adapter */
775 m = pcmmap(slotno, pp->caddr + Rconfig, 1, 1);
776 p = KADDR(m->isa + pp->caddr + Rconfig - m->ca);
777
778 /* set configuration and interrupt type */
779 x = ct->index;
780 if((ct->irqtype & 0x20) && ((ct->irqtype & 0x40)==0 || isa->irq>7))
781 x |= Clevel;
782 *p = x;
783 delay(5);
784
785 pcmunmap(slotno, m);
786 }
787 return 0;
788}
789
790/*
791 * read and crack the card information structure enough to set
792 * important parameters like power
793 */
794static void tcfig(Slot*, Cisdat*, int);
795static void tentry(Slot*, Cisdat*, int);
796static void tvers1(Slot*, Cisdat*, int);
797
798struct {
799 int n;
800 void (*parse)(Slot*, Cisdat*, int);
801} cistab[] = {
802 0x15, tvers1,
803 0x1A, tcfig,
804 0x1B, tentry,
805};

400 more lines aren’t shown here.

os/boot/pc/devpccard.c+1957−0

This diff is large: its 1958 lines aren’t shown here.

os/boot/pc/devsd.c+617−0

This diff is large: its 618 lines aren’t shown here.

os/boot/pc/dma.c+245−0

This diff is large: its 246 lines aren’t shown here.

os/boot/pc/dosboot.c+582−0

This diff is large: its 583 lines aren’t shown here.

os/boot/pc/dosfs.h+62−0

This diff is large: its 63 lines aren’t shown here.

os/boot/pc/eipfmt.c+145−0

This diff is large: its 146 lines aren’t shown here.

os/boot/pc/error.h+58−0

This diff is large: its 59 lines aren’t shown here.

os/boot/pc/ether.c+282−0

This diff is large: its 283 lines aren’t shown here.

os/boot/pc/ether2000.c+110−0

This diff is large: its 111 lines aren’t shown here.

os/boot/pc/ether2114x.c+1652−0

This diff is large: its 1653 lines aren’t shown here.

os/boot/pc/ether589.c+211−0

This diff is large: its 212 lines aren’t shown here.

os/boot/pc/ether79c970.c+539−0

This diff is large: its 540 lines aren’t shown here.

os/boot/pc/ether8003.c+258−0

This diff is large: its 259 lines aren’t shown here.

os/boot/pc/ether8139.c+614−0

This diff is large: its 615 lines aren’t shown here.

os/boot/pc/ether8169.c+847−0

This diff is large: its 848 lines aren’t shown here.

os/boot/pc/ether82557.c+881−0

This diff is large: its 882 lines aren’t shown here.

os/boot/pc/ether83815.c+825−0

This diff is large: its 826 lines aren’t shown here.

os/boot/pc/ether8390.c+715−0

This diff is large: its 716 lines aren’t shown here.

os/boot/pc/ether8390.h+71−0

This diff is large: its 72 lines aren’t shown here.

os/boot/pc/etherec2t.c+155−0

This diff is large: its 156 lines aren’t shown here.

os/boot/pc/etherelnk3.c+1898−0

This diff is large: its 1899 lines aren’t shown here.

os/boot/pc/etherif.h+46−0

This diff is large: its 47 lines aren’t shown here.

os/boot/pc/etherigbe.c+1706−0

This diff is large: its 1707 lines aren’t shown here.

os/boot/pc/ethermii.c+224−0

This diff is large: its 225 lines aren’t shown here.

os/boot/pc/ethermii.h+116−0

This diff is large: its 117 lines aren’t shown here.

os/boot/pc/etherrhine.c+676−0

This diff is large: its 677 lines aren’t shown here.

os/boot/pc/fns.h+155−0

This diff is large: its 156 lines aren’t shown here.

os/boot/pc/fs.c+94−0

This diff is large: its 95 lines aren’t shown here.

os/boot/pc/fs.h+36−0

This diff is large: its 37 lines aren’t shown here.

os/boot/pc/getcallerpc.c+8−0

This diff is large: its 9 lines aren’t shown here.

os/boot/pc/ilock.c+24−0

This diff is large: its 25 lines aren’t shown here.

os/boot/pc/inflate.c+199−0

This diff is large: its 200 lines aren’t shown here.

os/boot/pc/io.h+201−0

This diff is large: its 202 lines aren’t shown here.

os/boot/pc/ip.h+100−0

This diff is large: its 101 lines aren’t shown here.

os/boot/pc/kbd.c+489−0

This diff is large: its 490 lines aren’t shown here.

os/boot/pc/kfs.h+57−0

This diff is large: its 58 lines aren’t shown here.

os/boot/pc/kfsboot.c+256−0

This diff is large: its 257 lines aren’t shown here.

os/boot/pc/l.s+1079−0

This diff is large: its 1080 lines aren’t shown here.

os/boot/pc/lib.h+102−0

This diff is large: its 103 lines aren’t shown here.

os/boot/pc/load.c+563−0

This diff is large: its 564 lines aren’t shown here.

os/boot/pc/mbr.s+259−0

This diff is large: its 260 lines aren’t shown here.

os/boot/pc/mem.h+114−0

This diff is large: its 115 lines aren’t shown here.

os/boot/pc/memory.c+504−0

This diff is large: its 505 lines aren’t shown here.

os/boot/pc/mkfile+241−0

This diff is large: its 242 lines aren’t shown here.

os/boot/pc/noether.c+40−0

This diff is large: its 41 lines aren’t shown here.

os/boot/pc/part.c+344−0

This diff is large: its 345 lines aren’t shown here.

os/boot/pc/pbs.s+372−0

This diff is large: its 373 lines aren’t shown here.

os/boot/pc/pbsdisk+0−0

Binary file not shown.

os/boot/pc/pbsdisk.s+344−0

This diff is large: its 345 lines aren’t shown here.

os/boot/pc/pbsdisklba+0−0

Binary file not shown.

os/boot/pc/pbsdisklba.s+327−0

This diff is large: its 328 lines aren’t shown here.

os/boot/pc/pbslba.s+362−0

This diff is large: its 363 lines aren’t shown here.

os/boot/pc/pci.c+852−0

This diff is large: its 853 lines aren’t shown here.

os/boot/pc/print.c+31−0

This diff is large: its 32 lines aren’t shown here.

os/boot/pc/queue.c+44−0

This diff is large: its 45 lines aren’t shown here.

os/boot/pc/sd.h+127−0

This diff is large: its 128 lines aren’t shown here.

os/boot/pc/sd53c8xx.c+2120−0

This diff is large: its 2121 lines aren’t shown here.

os/boot/pc/sd53c8xx.i+769−0

This diff is large: its 770 lines aren’t shown here.

os/boot/pc/sdata.c+1639−0

This diff is large: its 1640 lines aren’t shown here.

os/boot/pc/sdmylex.c+1294−0

This diff is large: its 1295 lines aren’t shown here.

os/boot/pc/sdscsi.c+376−0

This diff is large: its 377 lines aren’t shown here.

os/boot/pc/trap.c+331−0

This diff is large: its 332 lines aren’t shown here.

os/boot/pc/ureg.h+27−0

This diff is large: its 28 lines aren’t shown here.

os/boot/pc/x16.h+159−0

This diff is large: its 160 lines aren’t shown here.

os/boot/puma/8250.c+312−0

This diff is large: its 313 lines aren’t shown here.

os/boot/puma/alarm.c+123−0

This diff is large: its 124 lines aren’t shown here.

os/boot/puma/armv4.h+99−0

This diff is large: its 100 lines aren’t shown here.

os/boot/puma/boot.h+12−0

This diff is large: its 13 lines aren’t shown here.

os/boot/puma/bootp.c+502−0

This diff is large: its 503 lines aren’t shown here.

os/boot/puma/cga.c+92−0

This diff is large: its 93 lines aren’t shown here.

os/boot/puma/clock.c+154−0

This diff is large: its 155 lines aren’t shown here.

os/boot/puma/conf.c+181−0

This diff is large: its 182 lines aren’t shown here.

os/boot/puma/console.c+181−0

This diff is large: its 182 lines aren’t shown here.

os/boot/puma/dat.h+205−0

This diff is large: its 206 lines aren’t shown here.

os/boot/puma/div.s+122−0

This diff is large: its 123 lines aren’t shown here.

os/boot/puma/donprint.c+332−0

This diff is large: its 333 lines aren’t shown here.

os/boot/puma/dosboot.c+614−0

This diff is large: its 615 lines aren’t shown here.

os/boot/puma/dosfs.h+110−0

This diff is large: its 111 lines aren’t shown here.

os/boot/puma/ebsit.trap.c+206−0

This diff is large: its 207 lines aren’t shown here.

os/boot/puma/ether.c+156−0

This diff is large: its 157 lines aren’t shown here.

os/boot/puma/ether.h+82−0

This diff is large: its 83 lines aren’t shown here.

os/boot/puma/ether8900.c+555−0

This diff is large: its 556 lines aren’t shown here.

os/boot/puma/flash.c+226−0

This diff is large: its 227 lines aren’t shown here.

os/boot/puma/fns.h+111−0

This diff is large: its 112 lines aren’t shown here.

os/boot/puma/hard.c+773−0

This diff is large: its 774 lines aren’t shown here.

os/boot/puma/io.h+3−0

This diff is large: its 4 lines aren’t shown here.

os/boot/puma/ip.h+98−0

This diff is large: its 99 lines aren’t shown here.

os/boot/puma/kbd.c+482−0

This diff is large: its 483 lines aren’t shown here.

os/boot/puma/l.s+427−0

This diff is large: its 428 lines aren’t shown here.

os/boot/puma/lib.h+107−0

This diff is large: its 108 lines aren’t shown here.

os/boot/puma/main.c+552−0

This diff is large: its 553 lines aren’t shown here.

os/boot/puma/mem.h+38−0

This diff is large: its 39 lines aren’t shown here.

os/boot/puma/mkfile+71−0

This diff is large: its 72 lines aren’t shown here.

os/boot/puma/outb.c+20−0

This diff is large: its 21 lines aren’t shown here.

os/boot/puma/plan9boot.c+93−0

This diff is large: its 94 lines aren’t shown here.

os/boot/puma/puma.c+123−0

This diff is large: its 124 lines aren’t shown here.

os/boot/puma/puma.h+435−0

This diff is large: its 436 lines aren’t shown here.

os/boot/puma/qio.c+128−0

This diff is large: its 129 lines aren’t shown here.

os/boot/puma/rmap.c+104−0

This diff is large: its 105 lines aren’t shown here.

os/boot/puma/squeeze.h+34−0

This diff is large: its 35 lines aren’t shown here.

os/boot/puma/sum.c+13−0

This diff is large: its 14 lines aren’t shown here.

os/boot/puma/trap.c+190−0

This diff is large: its 191 lines aren’t shown here.

os/boot/puma/ureg.h+22−0

This diff is large: its 23 lines aren’t shown here.

os/boot/puma/zqs.c+216−0

This diff is large: its 217 lines aren’t shown here.

os/boot/rpcg/NOTICE+3−0

This diff is large: its 4 lines aren’t shown here.

os/boot/rpcg/alarm.c+123−0

This diff is large: its 124 lines aren’t shown here.

os/boot/rpcg/all.h+6−0

This diff is large: its 7 lines aren’t shown here.

os/boot/rpcg/archrpcg.c+279−0

This diff is large: its 280 lines aren’t shown here.

os/boot/rpcg/archrpcg.h+48−0

This diff is large: its 49 lines aren’t shown here.

os/boot/rpcg/boot.h+8−0

This diff is large: its 9 lines aren’t shown here.

os/boot/rpcg/bootp.c+509−0

This diff is large: its 510 lines aren’t shown here.

os/boot/rpcg/clock.c+71−0

This diff is large: its 72 lines aren’t shown here.

os/boot/rpcg/conf.c+173−0

This diff is large: its 174 lines aren’t shown here.

os/boot/rpcg/console.c+173−0

This diff is large: its 174 lines aren’t shown here.

os/boot/rpcg/cpm.c+162−0

This diff is large: its 163 lines aren’t shown here.

os/boot/rpcg/crc32.c+42−0

This diff is large: its 43 lines aren’t shown here.

os/boot/rpcg/dat.h+217−0

This diff is large: its 218 lines aren’t shown here.

os/boot/rpcg/defont0.c+216−0

This diff is large: its 217 lines aren’t shown here.

os/boot/rpcg/devether.c+157−0

This diff is large: its 158 lines aren’t shown here.

os/boot/rpcg/devuart.c+230−0

This diff is large: its 231 lines aren’t shown here.

os/boot/rpcg/dload.c+103−0

This diff is large: its 104 lines aren’t shown here.

os/boot/rpcg/donprint.c+332−0

This diff is large: its 333 lines aren’t shown here.

os/boot/rpcg/dosboot.c+614−0

This diff is large: its 615 lines aren’t shown here.

os/boot/rpcg/dosfs.h+110−0

This diff is large: its 111 lines aren’t shown here.

os/boot/rpcg/etherif.h+59−0

This diff is large: its 60 lines aren’t shown here.

os/boot/rpcg/etherscc.c+411−0

This diff is large: its 412 lines aren’t shown here.

os/boot/rpcg/fblt.c+531−0

This diff is large: its 532 lines aren’t shown here.

os/boot/rpcg/flash.c+212−0

This diff is large: its 213 lines aren’t shown here.

os/boot/rpcg/fns.h+118−0

This diff is large: its 119 lines aren’t shown here.

os/boot/rpcg/g.mx+1987−0

This diff is large: its 1988 lines aren’t shown here.

os/boot/rpcg/gbitbltclip.c+52−0

This diff is large: its 53 lines aren’t shown here.

os/boot/rpcg/gnot.h+71−0

This diff is large: its 72 lines aren’t shown here.

os/boot/rpcg/i2c.c+360−0

This diff is large: its 361 lines aren’t shown here.

os/boot/rpcg/initfads.c+187−0

This diff is large: its 188 lines aren’t shown here.

os/boot/rpcg/initpaq.c+101−0

This diff is large: its 102 lines aren’t shown here.

os/boot/rpcg/initrpcg.c+91−0

This diff is large: its 92 lines aren’t shown here.

os/boot/rpcg/io.h+463−0

This diff is large: its 464 lines aren’t shown here.

os/boot/rpcg/ip.h+98−0

This diff is large: its 99 lines aren’t shown here.

os/boot/rpcg/l.s+388−0

This diff is large: its 389 lines aren’t shown here.

os/boot/rpcg/lib.h+106−0

This diff is large: its 107 lines aren’t shown here.

os/boot/rpcg/libg.h+418−0

This diff is large: its 419 lines aren’t shown here.

os/boot/rpcg/main.c+527−0

This diff is large: its 528 lines aren’t shown here.

os/boot/rpcg/mem.c+0−0

Empty file added.

os/boot/rpcg/mem.h+94−0

This diff is large: its 95 lines aren’t shown here.

os/boot/rpcg/mkfile+120−0

This diff is large: its 121 lines aren’t shown here.

os/boot/rpcg/ms2.c+179−0

This diff is large: its 180 lines aren’t shown here.

os/boot/rpcg/plan9boot.c+96−0

This diff is large: its 97 lines aren’t shown here.

os/boot/rpcg/qbromrpcg+0−0

Binary file not shown.

os/boot/rpcg/qio.c+128−0

This diff is large: its 129 lines aren’t shown here.

os/boot/rpcg/rmap.c+104−0

This diff is large: its 105 lines aren’t shown here.

os/boot/rpcg/screen.c+242−0

This diff is large: its 243 lines aren’t shown here.

os/boot/rpcg/sload+0−0

Binary file not shown.

os/boot/rpcg/sload.c+71−0

This diff is large: its 72 lines aren’t shown here.

os/boot/rpcg/squeeze.h+34−0

This diff is large: its 35 lines aren’t shown here.

os/boot/rpcg/trap.c+233−0

This diff is large: its 234 lines aren’t shown here.

os/boot/rpcg/uartboot.c+189−0

This diff is large: its 190 lines aren’t shown here.

os/boot/rpcg/ureg.h+43−0

This diff is large: its 44 lines aren’t shown here.

os/boot/rpcg/zqs.c+234−0

This diff is large: its 235 lines aren’t shown here.

os/cerf1110/Mk+8−0

This diff is large: its 9 lines aren’t shown here.

os/cerf1110/NOTICE+2−0

This diff is large: its 3 lines aren’t shown here.

os/cerf1110/README+22−0

This diff is large: its 23 lines aren’t shown here.

os/cerf1110/archcerf.c+177−0

This diff is large: its 178 lines aren’t shown here.

os/cerf1110/cerf+159−0

This diff is large: its 160 lines aren’t shown here.

os/cerf1110/dat.h+135−0

This diff is large: its 136 lines aren’t shown here.

os/cerf1110/devata.c+1200−0

This diff is large: its 1201 lines aren’t shown here.

os/cerf1110/devcerf.c+128−0

This diff is large: its 129 lines aren’t shown here.

os/cerf1110/ether8900.c+702−0

This diff is large: its 703 lines aren’t shown here.

os/cerf1110/fns.h+179−0

This diff is large: its 180 lines aren’t shown here.

os/cerf1110/io.h+1−0

This diff is large: its 2 lines aren’t shown here.

os/cerf1110/main.c+255−0

This diff is large: its 256 lines aren’t shown here.

os/cerf1110/mem.h+200−0

This diff is large: its 201 lines aren’t shown here.

os/cerf1110/mkfile+101−0

This diff is large: its 102 lines aren’t shown here.

os/cerf250/NOTICE+2−0

This diff is large: its 3 lines aren’t shown here.

os/cerf250/README+44−0

This diff is large: its 45 lines aren’t shown here.

os/cerf250/archcerf.c+266−0

This diff is large: its 267 lines aren’t shown here.

os/cerf250/cerf+163−0

This diff is large: its 164 lines aren’t shown here.

os/cerf250/dat.h+135−0

This diff is large: its 136 lines aren’t shown here.

os/cerf250/devpcf8563.c+371−0

This diff is large: its 372 lines aren’t shown here.

os/cerf250/ether91c111.c+1056−0

This diff is large: its 1057 lines aren’t shown here.

os/cerf250/fns.h+168−0

This diff is large: its 169 lines aren’t shown here.

os/cerf250/io.h+1−0

This diff is large: its 2 lines aren’t shown here.

os/cerf250/main.c+351−0

This diff is large: its 352 lines aren’t shown here.

os/cerf250/mem.h+174−0

This diff is large: its 175 lines aren’t shown here.

os/cerf250/mkfile+102−0

This diff is large: its 103 lines aren’t shown here.

os/cerf250/uart.h+118−0

This diff is large: its 119 lines aren’t shown here.

os/cerf405/NOTICE+3−0

This diff is large: its 4 lines aren’t shown here.

os/cerf405/README+45−0

This diff is large: its 46 lines aren’t shown here.

os/cerf405/cerf+139−0

This diff is large: its 140 lines aren’t shown here.

os/cerf405/clock.c+159−0

This diff is large: its 160 lines aren’t shown here.

os/cerf405/compile.c+34−0

This diff is large: its 35 lines aren’t shown here.

os/cerf405/dat.h+159−0

This diff is large: its 160 lines aren’t shown here.

os/cerf405/devboot.c+132−0

This diff is large: its 133 lines aren’t shown here.

os/cerf405/devether.c+617−0

This diff is large: its 618 lines aren’t shown here.

os/cerf405/devrtc.c+369−0

This diff is large: its 370 lines aren’t shown here.

os/cerf405/devuart.c+1064−0

This diff is large: its 1065 lines aren’t shown here.

os/cerf405/etheremac.c+829−0

This diff is large: its 830 lines aren’t shown here.

os/cerf405/etherif.h+37−0

This diff is large: its 38 lines aren’t shown here.

os/cerf405/fns.h+147−0

This diff is large: its 148 lines aren’t shown here.

os/cerf405/fpi.h+61−0

This diff is large: its 62 lines aren’t shown here.

os/cerf405/fpipower.c+970−0

This diff is large: its 971 lines aren’t shown here.

os/cerf405/gpio.c+106−0

This diff is large: its 107 lines aren’t shown here.

os/cerf405/iic.c+605−0

This diff is large: its 606 lines aren’t shown here.

os/cerf405/inb.s+127−0

This diff is large: its 128 lines aren’t shown here.

os/cerf405/io.h+301−0

This diff is large: its 302 lines aren’t shown here.

os/cerf405/l.s+795−0

This diff is large: its 796 lines aren’t shown here.

os/cerf405/main.c+719−0

This diff is large: its 720 lines aren’t shown here.

os/cerf405/mal.c+334−0

This diff is large: its 335 lines aren’t shown here.

os/cerf405/mem.h+147−0

This diff is large: its 148 lines aren’t shown here.

os/cerf405/mkfile+104−0

This diff is large: its 105 lines aren’t shown here.

os/cerf405/mmu.c+122−0

This diff is large: its 123 lines aren’t shown here.

os/cerf405/nand.c+96−0

This diff is large: its 97 lines aren’t shown here.

os/cerf405/nofp.s+31−0

This diff is large: its 32 lines aren’t shown here.

os/cerf405/pci.c+981−0

This diff is large: its 982 lines aren’t shown here.

os/cerf405/physmem.h+22−0

This diff is large: its 23 lines aren’t shown here.

os/cerf405/powerbreak.c+123−0

This diff is large: its 124 lines aren’t shown here.

os/cerf405/rmap.c+106−0

This diff is large: its 107 lines aren’t shown here.

os/cerf405/tlb.s+30−0

This diff is large: its 31 lines aren’t shown here.

os/cerf405/trap.c+581−0

This diff is large: its 582 lines aren’t shown here.

os/cerf405/uart.c+139−0

This diff is large: its 140 lines aren’t shown here.

os/cerf405/uart.h+101−0

This diff is large: its 102 lines aren’t shown here.

os/fads/NOTICE+4−0

This diff is large: its 5 lines aren’t shown here.

os/fads/archfads.c+619−0

This diff is large: its 620 lines aren’t shown here.

os/fads/archfads.h+33−0

This diff is large: its 34 lines aren’t shown here.

os/fads/dat.h+162−0

This diff is large: its 163 lines aren’t shown here.

os/fads/fads+121−0

This diff is large: its 122 lines aren’t shown here.

os/fads/fns.h+117−0

This diff is large: its 118 lines aren’t shown here.

os/fads/io.h+1−0

This diff is large: its 2 lines aren’t shown here.

os/fads/main.c+392−0

This diff is large: its 393 lines aren’t shown here.

os/fads/mem.h+157−0

This diff is large: its 158 lines aren’t shown here.

os/fads/mkfile+107−0

This diff is large: its 108 lines aren’t shown here.

os/fads/mmu.c+20−0

This diff is large: its 21 lines aren’t shown here.

os/fads/tlb.s+23−0

This diff is large: its 24 lines aren’t shown here.

os/init/README+5−0

This diff is large: its 6 lines aren’t shown here.

os/init/bootinit.b+628−0

This diff is large: its 629 lines aren’t shown here.

os/init/cerf405.b+598−0

This diff is large: its 599 lines aren’t shown here.

os/init/cerfinit.b+612−0

This diff is large: its 613 lines aren’t shown here.

os/init/evalinit.b+119−0

This diff is large: its 120 lines aren’t shown here.

os/init/geninit.b+93−0

This diff is large: its 94 lines aren’t shown here.

os/init/i4e.b+210−0

This diff is large: its 211 lines aren’t shown here.

os/init/init.b+613−0

This diff is large: its 614 lines aren’t shown here.

os/init/ipaqinit.b+697−0

This diff is large: its 698 lines aren’t shown here.

os/init/ipeinit.b+620−0

This diff is large: its 621 lines aren’t shown here.

os/init/jsinit.b+213−0

This diff is large: its 214 lines aren’t shown here.

os/init/mkfile+27−0

This diff is large: its 28 lines aren’t shown here.

os/init/mpcinit.b+383−0

This diff is large: its 384 lines aren’t shown here.

os/init/pcdemo.b+273−0

This diff is large: its 274 lines aren’t shown here.

os/init/pcinit.b+405−0

This diff is large: its 406 lines aren’t shown here.

os/init/reminit.b+239−0

This diff is large: its 240 lines aren’t shown here.

os/init/rpcginit.b+610−0

This diff is large: its 611 lines aren’t shown here.

os/init/shell.b+97−0

This diff is large: its 98 lines aren’t shown here.

os/init/soeinit.b+613−0

This diff is large: its 614 lines aren’t shown here.

os/init/srvinit.b+209−0

This diff is large: its 210 lines aren’t shown here.

os/init/wminit.b+231−0

This diff is large: its 232 lines aren’t shown here.

os/ip/arp.c+681−0

This diff is large: its 682 lines aren’t shown here.

os/ip/bootp.c+231−0

This diff is large: its 232 lines aren’t shown here.

os/ip/compress.c+520−0

This diff is large: its 521 lines aren’t shown here.

os/ip/devip.c+1419−0

This diff is large: its 1420 lines aren’t shown here.

os/ip/dhcp.c+447−0

This diff is large: its 448 lines aren’t shown here.

os/ip/eipconvtest.c+152−0

This diff is large: its 153 lines aren’t shown here.

os/ip/esp.c+866−0

This diff is large: its 867 lines aren’t shown here.

os/ip/ethermedium.c+792−0

This diff is large: its 793 lines aren’t shown here.

os/ip/gre.c+282−0

This diff is large: its 283 lines aren’t shown here.

os/ip/icmp.c+490−0

This diff is large: its 491 lines aren’t shown here.

os/ip/icmp6.c+917−0

This diff is large: its 918 lines aren’t shown here.

os/ip/igmp.c+291−0

This diff is large: its 292 lines aren’t shown here.

os/ip/ihbootp.c+323−0

This diff is large: its 324 lines aren’t shown here.

os/ip/il.c+1408−0

This diff is large: its 1409 lines aren’t shown here.

os/ip/ip.c+805−0

This diff is large: its 806 lines aren’t shown here.

os/ip/ip.h+673−0

This diff is large: its 674 lines aren’t shown here.

os/ip/ipaux.c+730−0

This diff is large: its 731 lines aren’t shown here.

os/ip/ipifc.c+1721−0

This diff is large: its 1722 lines aren’t shown here.

os/ip/ipmux.c+857−0

This diff is large: its 858 lines aren’t shown here.

os/ip/iproute.c+852−0

This diff is large: its 853 lines aren’t shown here.

os/ip/iprouter.c+56−0

This diff is large: its 57 lines aren’t shown here.

os/ip/ipv6.c+747−0

This diff is large: its 748 lines aren’t shown here.

os/ip/ipv6.h+185−0

This diff is large: its 186 lines aren’t shown here.

os/ip/kernel.h+10−0

This diff is large: its 11 lines aren’t shown here.

os/ip/loopbackmedium.c+121−0

This diff is large: its 122 lines aren’t shown here.

os/ip/netdevmedium.c+153−0

This diff is large: its 154 lines aren’t shown here.

os/ip/netlog.c+263−0

This diff is large: its 264 lines aren’t shown here.

os/ip/nullmedium.c+39−0

This diff is large: its 40 lines aren’t shown here.

os/ip/pktmedium.c+79−0

This diff is large: its 80 lines aren’t shown here.

os/ip/plan9.c+36−0

This diff is large: its 37 lines aren’t shown here.

os/ip/ppp.c+1656−0

This diff is large: its 1657 lines aren’t shown here.

os/ip/ppp.h+258−0

This diff is large: its 259 lines aren’t shown here.

os/ip/pppmedium.c+192−0

This diff is large: its 193 lines aren’t shown here.

os/ip/ptclbsum.c+72−0

This diff is large: its 73 lines aren’t shown here.

os/ip/rudp.c+1085−0

This diff is large: its 1086 lines aren’t shown here.

os/ip/tcp.c+3177−0

This diff is large: its 3178 lines aren’t shown here.

os/ip/udp.c+649−0

This diff is large: its 650 lines aren’t shown here.

os/ipaq1110/Mk+8−0

This diff is large: its 9 lines aren’t shown here.

os/ipaq1110/NOTICE+6−0

This diff is large: its 7 lines aren’t shown here.

os/ipaq1110/README+65−0

This diff is large: its 66 lines aren’t shown here.

os/ipaq1110/archipaq.c+376−0

This diff is large: its 377 lines aren’t shown here.

os/ipaq1110/dat.h+135−0

This diff is large: its 136 lines aren’t shown here.

os/ipaq1110/defont.c+290−0

This diff is large: its 291 lines aren’t shown here.

os/ipaq1110/devaudio.c+1056−0

This diff is large: its 1057 lines aren’t shown here.

os/ipaq1110/devipaq.c+762−0

This diff is large: its 763 lines aren’t shown here.

os/ipaq1110/etherwavelan.c+1307−0

This diff is large: its 1308 lines aren’t shown here.

os/ipaq1110/fns.h+179−0

This diff is large: its 180 lines aren’t shown here.

os/ipaq1110/inflate+0−0

Binary file not shown.

os/ipaq1110/io.h+60−0

This diff is large: its 61 lines aren’t shown here.

os/ipaq1110/ipaq+172−0

This diff is large: its 173 lines aren’t shown here.

os/ipaq1110/lcd.c+185−0

This diff is large: its 186 lines aren’t shown here.

os/ipaq1110/main.c+255−0

This diff is large: its 256 lines aren’t shown here.

os/ipaq1110/mem.h+200−0

This diff is large: its 201 lines aren’t shown here.

os/ipaq1110/mkfile+103−0

This diff is large: its 104 lines aren’t shown here.

os/ipaq1110/screen.c+917−0

This diff is large: its 918 lines aren’t shown here.

os/ipaq1110/screen.h+64−0

This diff is large: its 65 lines aren’t shown here.

os/ipaq1110/tstdraw.b+107−0

This diff is large: its 108 lines aren’t shown here.

os/ipaq1110/upd+4−0

This diff is large: its 5 lines aren’t shown here.

os/ipengine/NOTICE+4−0

This diff is large: its 5 lines aren’t shown here.

os/ipengine/README+40−0

This diff is large: its 41 lines aren’t shown here.

os/ipengine/archipe.c+488−0

This diff is large: its 489 lines aren’t shown here.

os/ipengine/archipe.h+32−0

This diff is large: its 33 lines aren’t shown here.

os/ipengine/dat.h+162−0

This diff is large: its 163 lines aren’t shown here.

os/ipengine/devfpga.c+389−0

This diff is large: its 390 lines aren’t shown here.

os/ipengine/flash28f320b3b.c+43−0

This diff is large: its 44 lines aren’t shown here.

os/ipengine/fns.h+120−0

This diff is large: its 121 lines aren’t shown here.

os/ipengine/io.h+1−0

This diff is large: its 2 lines aren’t shown here.

os/ipengine/ipe+109−0

This diff is large: its 110 lines aren’t shown here.

os/ipengine/main.c+348−0

This diff is large: its 349 lines aren’t shown here.

os/ipengine/mem.h+156−0

This diff is large: its 157 lines aren’t shown here.

os/ipengine/mkfile+105−0

This diff is large: its 106 lines aren’t shown here.

os/ipengine/mmu.c+20−0

This diff is large: its 21 lines aren’t shown here.

os/ipengine/tlb.s+21−0

This diff is large: its 22 lines aren’t shown here.

os/js/README+10−0

This diff is large: its 11 lines aren’t shown here.

os/js/audio.h+9−0

This diff is large: its 10 lines aren’t shown here.

os/js/clock.c+104−0

This diff is large: its 105 lines aren’t shown here.

os/js/cs4231.h+20−0

This diff is large: its 21 lines aren’t shown here.

os/js/dat.h+163−0

This diff is large: its 164 lines aren’t shown here.

os/js/devcs4231.c+1186−0

This diff is large: its 1187 lines aren’t shown here.

os/js/devrtc.c+413−0

This diff is large: its 414 lines aren’t shown here.

os/js/fns.h+110−0

This diff is large: its 111 lines aren’t shown here.

os/js/fsv.c+198−0

This diff is large: its 199 lines aren’t shown here.

os/js/io.h+224−0

This diff is large: its 225 lines aren’t shown here.

os/js/iob.c+13−0

This diff is large: its 14 lines aren’t shown here.

os/js/js+104−0

This diff is large: its 105 lines aren’t shown here.

os/js/kbd.c+482−0

This diff is large: its 483 lines aren’t shown here.

os/js/l.s+560−0

This diff is large: its 561 lines aren’t shown here.

os/js/main.c+564−0

This diff is large: its 565 lines aren’t shown here.

os/js/mem.h+149−0

This diff is large: its 150 lines aren’t shown here.

os/js/mkfile+77−0

This diff is large: its 78 lines aren’t shown here.

os/js/mmu.c+252−0

This diff is large: its 253 lines aren’t shown here.

os/js/ns16552.h+81−0

This diff is large: its 82 lines aren’t shown here.

os/js/rom.c+103−0

This diff is large: its 104 lines aren’t shown here.

os/js/rom.h+57−0

This diff is large: its 58 lines aren’t shown here.

os/js/screen.c+483−0

This diff is large: its 484 lines aren’t shown here.

os/js/screen.h+49−0

This diff is large: its 50 lines aren’t shown here.

os/js/softcursor.h+13−0

This diff is large: its 14 lines aren’t shown here.

os/js/superio.c+216−0

This diff is large: its 217 lines aren’t shown here.

os/js/trap.c+472−0

This diff is large: its 473 lines aren’t shown here.

os/js/ureg.h+45−0

This diff is large: its 46 lines aren’t shown here.

os/ks32/Mk+7−0

This diff is large: its 8 lines aren’t shown here.

os/ks32/NOTICE+2−0

This diff is large: its 3 lines aren’t shown here.

os/ks32/archevaluator7t.c+161−0

This diff is large: its 162 lines aren’t shown here.

os/ks32/armv7.h+19−0

This diff is large: its 20 lines aren’t shown here.

os/ks32/clock.c+287−0

This diff is large: its 288 lines aren’t shown here.

os/ks32/dat.h+218−0

This diff is large: its 219 lines aren’t shown here.

os/ks32/devuart.c+719−0

This diff is large: its 720 lines aren’t shown here.

os/ks32/download.ps+1040−0

This diff is large: its 1041 lines aren’t shown here.

os/ks32/evaluator7t+110−0

This diff is large: its 111 lines aren’t shown here.

os/ks32/fns.h+145−0

This diff is large: its 146 lines aren’t shown here.

os/ks32/fpi.h+61−0

This diff is large: its 62 lines aren’t shown here.

os/ks32/fpiarm.c+483−0

This diff is large: its 484 lines aren’t shown here.

os/ks32/io.h+168−0

This diff is large: its 169 lines aren’t shown here.

os/ks32/l.s+205−0

This diff is large: its 206 lines aren’t shown here.

os/ks32/main.c+289−0

This diff is large: its 290 lines aren’t shown here.

os/ks32/mem.h+54−0

This diff is large: its 55 lines aren’t shown here.

os/ks32/mkfile+115−0

This diff is large: its 116 lines aren’t shown here.

os/ks32/not.c+3−0

This diff is large: its 4 lines aren’t shown here.

os/ks32/squirt+2−0

This diff is large: its 3 lines aren’t shown here.

os/ks32/trap.c+525−0

This diff is large: its 526 lines aren’t shown here.

os/manga/Mk+8−0

This diff is large: its 9 lines aren’t shown here.

os/manga/archmanga.c+164−0

This diff is large: its 165 lines aren’t shown here.

os/manga/clock.c+166−0

This diff is large: its 167 lines aren’t shown here.

os/manga/dat.h+128−0

This diff is large: its 129 lines aren’t shown here.

os/manga/devether.c+765−0

This diff is large: its 766 lines aren’t shown here.

os/manga/devusb.c+931−0

This diff is large: its 932 lines aren’t shown here.

os/manga/eswnotes+41−0

This diff is large: its 42 lines aren’t shown here.

os/manga/ether8139.c+744−0

This diff is large: its 745 lines aren’t shown here.

os/manga/etherif.h+44−0

This diff is large: its 45 lines aren’t shown here.

os/manga/etherks8695.c+1169−0

This diff is large: its 1170 lines aren’t shown here.

os/manga/flashif.h+82−0

This diff is large: its 83 lines aren’t shown here.

os/manga/fns.h+163−0

This diff is large: its 164 lines aren’t shown here.

os/manga/fpi.h+61−0

This diff is large: its 62 lines aren’t shown here.

os/manga/fpiarm.c+483−0

This diff is large: its 484 lines aren’t shown here.

os/manga/gpio.c+75−0

This diff is large: its 76 lines aren’t shown here.

os/manga/inb.c+85−0

This diff is large: its 86 lines aren’t shown here.

os/manga/io.h+320−0

This diff is large: its 321 lines aren’t shown here.

os/manga/ioring.c+72−0

This diff is large: its 73 lines aren’t shown here.

os/manga/l.s+404−0

This diff is large: its 405 lines aren’t shown here.

os/manga/main.c+317−0

This diff is large: its 318 lines aren’t shown here.

os/manga/manga+137−0

This diff is large: its 138 lines aren’t shown here.

os/manga/mem.h+133−0

This diff is large: its 134 lines aren’t shown here.

os/manga/mkfile+89−0

This diff is large: its 90 lines aren’t shown here.

os/manga/mmu.c+244−0

This diff is large: its 245 lines aren’t shown here.

os/manga/pci.c+1007−0

This diff is large: its 1008 lines aren’t shown here.

os/manga/pinflate+0−0

Binary file not shown.

os/manga/trap.c+498−0

This diff is large: its 499 lines aren’t shown here.

os/manga/uartks8695.c+629−0

This diff is large: its 630 lines aren’t shown here.

os/manga/usb.h+160−0

This diff is large: its 161 lines aren’t shown here.

os/manga/usbuhci.c+1556−0

This diff is large: its 1557 lines aren’t shown here.

os/mpc/800io.h+666−0

This diff is large: its 667 lines aren’t shown here.

os/mpc/NOTICE+3−0

This diff is large: its 4 lines aren’t shown here.

os/mpc/clock.c+145−0

This diff is large: its 146 lines aren’t shown here.

os/mpc/cpm.c+695−0

This diff is large: its 696 lines aren’t shown here.

os/mpc/cpmtimer.c+179−0

This diff is large: its 180 lines aren’t shown here.

os/mpc/devata.c+1194−0

This diff is large: its 1195 lines aren’t shown here.

os/mpc/devbench.c+243−0

This diff is large: its 244 lines aren’t shown here.

os/mpc/devboot.c+132−0

This diff is large: its 133 lines aren’t shown here.

os/mpc/devether.c+617−0

This diff is large: its 618 lines aren’t shown here.

os/mpc/devpcmcia.c+1076−0

This diff is large: its 1077 lines aren’t shown here.

os/mpc/devrtc.c+258−0

This diff is large: its 259 lines aren’t shown here.

os/mpc/devtouch.c+497−0

This diff is large: its 498 lines aren’t shown here.

os/mpc/devuart.c+1450−0

This diff is large: its 1451 lines aren’t shown here.

os/mpc/dsp.c+289−0

This diff is large: its 290 lines aren’t shown here.

os/mpc/dsp.h+62−0

This diff is large: its 63 lines aren’t shown here.

os/mpc/etherif.h+37−0

This diff is large: its 38 lines aren’t shown here.

os/mpc/etherscc.c+528−0

This diff is large: its 529 lines aren’t shown here.

os/mpc/faultpower.c+49−0

This diff is large: its 50 lines aren’t shown here.

os/mpc/fp.s+205−0

This diff is large: its 206 lines aren’t shown here.

os/mpc/fpi.h+61−0

This diff is large: its 62 lines aren’t shown here.

os/mpc/fpipower.c+970−0

This diff is large: its 971 lines aren’t shown here.

os/mpc/i2c.c+439−0

This diff is large: its 440 lines aren’t shown here.

os/mpc/i2c_spi.srx+149−0

This diff is large: its 150 lines aren’t shown here.

os/mpc/inb.s+120−0

This diff is large: its 121 lines aren’t shown here.

os/mpc/kbd.c+20−0

This diff is large: its 21 lines aren’t shown here.

os/mpc/l.s+685−0

This diff is large: its 686 lines aren’t shown here.

os/mpc/nofp.s+31−0

This diff is large: its 32 lines aren’t shown here.

os/mpc/pcmcia.h+19−0

This diff is large: its 20 lines aren’t shown here.

os/mpc/pit.c+68−0

This diff is large: its 69 lines aren’t shown here.

os/mpc/powerbreak.c+123−0

This diff is large: its 124 lines aren’t shown here.

os/mpc/rmap.c+106−0

This diff is large: its 107 lines aren’t shown here.

os/mpc/screen.c+832−0

This diff is large: its 833 lines aren’t shown here.

os/mpc/screen.h+60−0

This diff is large: its 61 lines aren’t shown here.

os/mpc/spi.c+243−0

This diff is large: its 244 lines aren’t shown here.

os/mpc/trap.c+554−0

This diff is large: its 555 lines aren’t shown here.

os/mpc/usb.h+62−0

This diff is large: its 63 lines aren’t shown here.

os/omap/README+4−0

This diff is large: its 5 lines aren’t shown here.

os/pc/NOTICE+8−0

This diff is large: its 9 lines aren’t shown here.

os/pc/README+9−0

This diff is large: its 10 lines aren’t shown here.

os/pc/apbootstrap.h+15−0

This diff is large: its 16 lines aren’t shown here.

os/pc/apbootstrap.s+110−0

This diff is large: its 111 lines aren’t shown here.

os/pc/apic.c+378−0

This diff is large: its 379 lines aren’t shown here.

os/pc/apm.c+151−0

This diff is large: its 152 lines aren’t shown here.

os/pc/apmjump.s+98−0

This diff is large: its 99 lines aren’t shown here.

os/pc/archmp.c+138−0

This diff is large: its 139 lines aren’t shown here.

os/pc/audio.h+15−0

This diff is large: its 16 lines aren’t shown here.

os/pc/cga.c+127−0

This diff is large: its 128 lines aren’t shown here.

os/pc/cgamemscr.c+203−0

This diff is large: its 204 lines aren’t shown here.

os/pc/crystal.h+1118−0

This diff is large: its 1119 lines aren’t shown here.

os/pc/dat.h+258−0

This diff is large: its 259 lines aren’t shown here.

os/pc/devarch.c+940−0

This diff is large: its 941 lines aren’t shown here.

os/pc/devds1620.c+368−0

This diff is large: its 369 lines aren’t shown here.

os/pc/devether.c+539−0

This diff is large: its 540 lines aren’t shown here.

os/pc/devfloppy.c+1082−0

This diff is large: its 1083 lines aren’t shown here.

os/pc/devi82365.c+1044−0

This diff is large: its 1045 lines aren’t shown here.

os/pc/devlm78.c+346−0

This diff is large: its 347 lines aren’t shown here.

os/pc/devlpt.c+245−0

This diff is large: its 246 lines aren’t shown here.

os/pc/devmouse.c+672−0

This diff is large: its 673 lines aren’t shown here.

os/pc/devmpeg.c+1063−0

This diff is large: its 1064 lines aren’t shown here.

os/pc/devpccard.c+1949−0

This diff is large: its 1950 lines aren’t shown here.

os/pc/devpnp.c+652−0

This diff is large: its 653 lines aren’t shown here.

os/pc/devrtc.c+461−0

This diff is large: its 462 lines aren’t shown here.

os/pc/devtv.c+1826−0

This diff is large: its 1827 lines aren’t shown here.

os/pc/devusb.c+951−0

This diff is large: its 952 lines aren’t shown here.

os/pc/devvga.c+620−0

This diff is large: its 621 lines aren’t shown here.

os/pc/devzt5512.c+308−0

This diff is large: its 309 lines aren’t shown here.

os/pc/dma.c+237−0

This diff is large: its 238 lines aren’t shown here.

os/pc/ether2000.c+230−0

This diff is large: its 231 lines aren’t shown here.

os/pc/ether2114x.c+1828−0

This diff is large: its 1829 lines aren’t shown here.

os/pc/ether589.c+214−0

This diff is large: its 215 lines aren’t shown here.

os/pc/ether79c960.c+523−0

This diff is large: its 524 lines aren’t shown here.

os/pc/ether79c970.c+640−0

This diff is large: its 641 lines aren’t shown here.

os/pc/ether8003.c+271−0

This diff is large: its 272 lines aren’t shown here.

os/pc/ether8139.c+755−0

This diff is large: its 756 lines aren’t shown here.

os/pc/ether82543gc.c+1367−0

This diff is large: its 1368 lines aren’t shown here.

os/pc/ether82557.c+1325−0

This diff is large: its 1326 lines aren’t shown here.

os/pc/ether83815.c+994−0

This diff is large: its 995 lines aren’t shown here.

os/pc/ether8390.c+812−0

This diff is large: its 813 lines aren’t shown here.

os/pc/ether8390.h+74−0

This diff is large: its 75 lines aren’t shown here.

os/pc/etherec2t.c+173−0

This diff is large: its 174 lines aren’t shown here.

os/pc/etherelnk3.c+2132−0

This diff is large: its 2133 lines aren’t shown here.

os/pc/etherga620.c+1224−0

This diff is large: its 1225 lines aren’t shown here.

os/pc/etherga620fw.h+4858−0

This diff is large: its 4859 lines aren’t shown here.

os/pc/etherif.h+39−0

This diff is large: its 40 lines aren’t shown here.

os/pc/etherigbe.c+1968−0

This diff is large: its 1969 lines aren’t shown here.

os/pc/etherrhine.c+734−0

This diff is large: its 735 lines aren’t shown here.

os/pc/ethersmc.c+780−0

This diff is large: its 781 lines aren’t shown here.

os/pc/etherwavelan.c+196−0

This diff is large: its 197 lines aren’t shown here.

os/pc/flashif.h+82−0

This diff is large: its 83 lines aren’t shown here.

os/pc/flashzpc.c+371−0

This diff is large: its 372 lines aren’t shown here.

os/pc/floppy.h+183−0

This diff is large: its 184 lines aren’t shown here.

os/pc/fns.h+162−0

This diff is large: its 163 lines aren’t shown here.

os/pc/fpi.h+61−0

This diff is large: its 62 lines aren’t shown here.

os/pc/fpi387.c+743−0

This diff is large: its 744 lines aren’t shown here.

os/pc/fpsave.s+9−0

This diff is large: its 10 lines aren’t shown here.

os/pc/i8250.c+328−0

This diff is large: its 329 lines aren’t shown here.

os/pc/i8253.c+314−0

This diff is large: its 315 lines aren’t shown here.

os/pc/i8259.c+199−0

This diff is large: its 200 lines aren’t shown here.

os/pc/io.h+323−0

This diff is large: its 324 lines aren’t shown here.

os/pc/kbd.c+477−0

This diff is large: its 478 lines aren’t shown here.

os/pc/l.s+953−0

This diff is large: its 954 lines aren’t shown here.

os/pc/main.c+457−0

This diff is large: its 458 lines aren’t shown here.

os/pc/mem.h+144−0

This diff is large: its 145 lines aren’t shown here.

os/pc/memory.c+570−0

This diff is large: its 571 lines aren’t shown here.

os/pc/mkfile+83−0

This diff is large: its 84 lines aren’t shown here.

os/pc/mmu.c+321−0

This diff is large: its 322 lines aren’t shown here.

os/pc/mouse.c+84−0

This diff is large: its 85 lines aren’t shown here.

os/pc/mp.c+815−0

This diff is large: its 816 lines aren’t shown here.

os/pc/mp.h+225−0

This diff is large: its 226 lines aren’t shown here.

os/pc/pc+139−0

This diff is large: its 140 lines aren’t shown here.

os/pc/pc4e+145−0

This diff is large: its 146 lines aren’t shown here.

os/pc/pcdisk+154−0

This diff is large: its 155 lines aren’t shown here.

os/pc/pci.acid+252−0

This diff is large: its 253 lines aren’t shown here.

os/pc/pci.c+1341−0

This diff is large: its 1342 lines aren’t shown here.

os/pc/pcidb.acid+2848−0

This diff is large: its 2849 lines aren’t shown here.

os/pc/pcmciamodem.c+75−0

This diff is large: its 76 lines aren’t shown here.

os/pc/piix4smbus.c+213−0

This diff is large: its 214 lines aren’t shown here.

os/pc/pix+153−0

This diff is large: its 154 lines aren’t shown here.

os/pc/ps2mouse.c+84−0

This diff is large: its 85 lines aren’t shown here.

os/pc/ptclbsum386.s+126−0

This diff is large: its 127 lines aren’t shown here.

os/pc/screen.c+410−0

This diff is large: its 411 lines aren’t shown here.

os/pc/screen.h+173−0

This diff is large: its 174 lines aren’t shown here.

os/pc/sd53c8xx.c+2138−0

This diff is large: its 2139 lines aren’t shown here.

os/pc/sd53c8xx.i+773−0

This diff is large: its 774 lines aren’t shown here.

os/pc/sd53c8xx.n+448−0

This diff is large: its 449 lines aren’t shown here.

os/pc/sdata.c+2206−0

This diff is large: its 2207 lines aren’t shown here.

os/pc/sdmylex.c+1249−0

This diff is large: its 1250 lines aren’t shown here.

os/pc/sdscsi.c+394−0

This diff is large: its 395 lines aren’t shown here.

os/pc/trap.c+571−0

This diff is large: its 572 lines aren’t shown here.

os/pc/tv.h+15−0

This diff is large: its 16 lines aren’t shown here.

os/pc/uarti8250.c+740−0

This diff is large: its 741 lines aren’t shown here.

os/pc/uartisa.c+98−0

This diff is large: its 99 lines aren’t shown here.

os/pc/uartpci.c+137−0

This diff is large: its 138 lines aren’t shown here.

os/pc/usb.h+160−0

This diff is large: its 161 lines aren’t shown here.

os/pc/usbuhci.c+1538−0

This diff is large: its 1539 lines aren’t shown here.

os/pc/vga.c+241−0

This diff is large: its 242 lines aren’t shown here.

os/pc/vga.h+75−0

This diff is large: its 76 lines aren’t shown here.

os/pc/vga3dfx.c+258−0

This diff is large: its 259 lines aren’t shown here.

os/pc/vgaark2000pv.c+190−0

This diff is large: its 191 lines aren’t shown here.

os/pc/vgabt485.c+245−0

This diff is large: its 246 lines aren’t shown here.

os/pc/vgaclgd542x.c+291−0

This diff is large: its 292 lines aren’t shown here.

os/pc/vgaclgd546x.c+277−0

This diff is large: its 278 lines aren’t shown here.

os/pc/vgact65545.c+149−0

This diff is large: its 150 lines aren’t shown here.

os/pc/vgacyber938x.c+225−0

This diff is large: its 226 lines aren’t shown here.

os/pc/vgaet4000.c+270−0

This diff is large: its 271 lines aren’t shown here.

os/pc/vgahiqvideo.c+274−0

This diff is large: its 275 lines aren’t shown here.

os/pc/vgai81x.c+282−0

This diff is large: its 283 lines aren’t shown here.

os/pc/vgamach64xx.c+1250−0

This diff is large: its 1251 lines aren’t shown here.

os/pc/vgamga2164w.c+289−0

This diff is large: its 290 lines aren’t shown here.

os/pc/vgamga4xx.c+603−0

This diff is large: its 604 lines aren’t shown here.

os/pc/vganeomagic.c+541−0

This diff is large: its 542 lines aren’t shown here.

os/pc/vganvidia.c+373−0

This diff is large: its 374 lines aren’t shown here.

os/pc/vgargb524.c+236−0

This diff is large: its 237 lines aren’t shown here.

os/pc/vgas3.c+620−0

This diff is large: its 621 lines aren’t shown here.

os/pc/vgasavage.c+571−0

This diff is large: its 572 lines aren’t shown here.

os/pc/vgat2r4.c+586−0

This diff is large: its 587 lines aren’t shown here.

os/pc/vgatvp3020.c+216−0

This diff is large: its 217 lines aren’t shown here.

os/pc/vgatvp3026.c+189−0

This diff is large: its 190 lines aren’t shown here.

os/pc/vgavmware.c+386−0

This diff is large: its 387 lines aren’t shown here.

os/pc/vgax.c+102−0

This diff is large: its 103 lines aren’t shown here.

os/pc/wavelan.c+1268−0

This diff is large: its 1269 lines aren’t shown here.

os/pc/wavelan.h+327−0

This diff is large: its 328 lines aren’t shown here.

os/pc/x86break.c+138−0

This diff is large: its 139 lines aren’t shown here.

os/pc/zoran.h+907−0

This diff is large: its 908 lines aren’t shown here.

os/port/NOTICE+18−0

This diff is large: its 19 lines aren’t shown here.

os/port/alarm.c+41−0

This diff is large: its 42 lines aren’t shown here.

os/port/alloc.c+963−0

This diff is large: its 964 lines aren’t shown here.

os/port/allocb.c+159−0

This diff is large: its 160 lines aren’t shown here.

os/port/chan.c+1431−0

This diff is large: its 1432 lines aren’t shown here.

os/port/cis.c+539−0

This diff is large: its 540 lines aren’t shown here.

os/port/dev.c+434−0

This diff is large: its 435 lines aren’t shown here.

os/port/devXXX.c+147−0

This diff is large: its 148 lines aren’t shown here.

os/port/devaudio.c+947−0

This diff is large: its 948 lines aren’t shown here.

os/port/devbench.c+1165−0

This diff is large: its 1166 lines aren’t shown here.

os/port/devboot.c+150−0

This diff is large: its 151 lines aren’t shown here.

os/port/devbridge.c+1206−0

This diff is large: its 1207 lines aren’t shown here.

os/port/devcap.c+248−0

This diff is large: its 249 lines aren’t shown here.

os/port/devcons.c+1274−0

This diff is large: its 1275 lines aren’t shown here.

os/port/devdbg.c+1000−0

This diff is large: its 1001 lines aren’t shown here.

os/port/devdraw.c+2088−0

This diff is large: its 2089 lines aren’t shown here.

os/port/devds.c+605−0

This diff is large: its 606 lines aren’t shown here.

os/port/devdup.c+151−0

This diff is large: its 152 lines aren’t shown here.

os/port/devdynld.c+365−0

This diff is large: its 366 lines aren’t shown here.

os/port/devenv.c+338−0

This diff is large: its 339 lines aren’t shown here.

os/port/devflash.c+641−0

This diff is large: its 642 lines aren’t shown here.

os/port/devftl.c+1365−0

This diff is large: its 1366 lines aren’t shown here.

os/port/devi2c.c+227−0

This diff is large: its 228 lines aren’t shown here.

os/port/devindir.c+40−0

This diff is large: its 41 lines aren’t shown here.

os/port/devkprof.c+230−0

This diff is large: its 231 lines aren’t shown here.

os/port/devlogfs.c+1531−0

This diff is large: its 1532 lines aren’t shown here.

os/port/devloopback.c+743−0

This diff is large: its 744 lines aren’t shown here.

os/port/devmnt.c+1204−0

This diff is large: its 1205 lines aren’t shown here.

os/port/devns16552.c+1090−0

This diff is large: its 1091 lines aren’t shown here.

os/port/devpci.c+227−0

This diff is large: its 228 lines aren’t shown here.

os/port/devpipe.c+464−0

This diff is large: its 465 lines aren’t shown here.

os/port/devpointer.c+279−0

This diff is large: its 280 lines aren’t shown here.

os/port/devprof.c+722−0

This diff is large: its 723 lines aren’t shown here.

os/port/devprog.c+1510−0

This diff is large: its 1511 lines aren’t shown here.

os/port/devroot.c+153−0

This diff is large: its 154 lines aren’t shown here.

os/port/devsd.c+1474−0

This diff is large: its 1475 lines aren’t shown here.

os/port/devsign.c+446−0

This diff is large: its 447 lines aren’t shown here.

os/port/devsrv.c+726−0

This diff is large: its 727 lines aren’t shown here.

os/port/devssl.c+1436−0

This diff is large: its 1437 lines aren’t shown here.

os/port/devtest.c+125−0

This diff is large: its 126 lines aren’t shown here.

os/port/devtinyfs.c+915−0

This diff is large: its 916 lines aren’t shown here.

os/port/devtk.c+180−0

This diff is large: its 181 lines aren’t shown here.

os/port/devuart.c+748−0

This diff is large: its 749 lines aren’t shown here.

os/port/dial.c+417−0

This diff is large: its 418 lines aren’t shown here.

os/port/dis.c+1125−0

This diff is large: its 1126 lines aren’t shown here.

os/port/discall.c+185−0

This diff is large: its 186 lines aren’t shown here.

os/port/dynld.c+75−0

This diff is large: its 76 lines aren’t shown here.

os/port/edf.c+626−0

This diff is large: its 627 lines aren’t shown here.

os/port/edf.h+53−0

This diff is large: its 54 lines aren’t shown here.

os/port/error.h+64−0

This diff is large: its 65 lines aren’t shown here.

os/port/ethermii.c+238−0

This diff is large: its 239 lines aren’t shown here.

os/port/ethermii.h+116−0

This diff is large: its 117 lines aren’t shown here.

os/port/ethersink.c+65−0

This diff is large: its 66 lines aren’t shown here.

os/port/exception.c+216−0

This diff is large: its 217 lines aren’t shown here.

os/port/exportfs.c+1325−0

This diff is large: its 1326 lines aren’t shown here.

os/port/flashamd29f0x0.c+167−0

This diff is large: its 168 lines aren’t shown here.

os/port/flashcfi16.c+134−0

This diff is large: its 135 lines aren’t shown here.

os/port/flashcfi8.c+143−0

This diff is large: its 144 lines aren’t shown here.

os/port/flashif.h+147−0

This diff is large: its 148 lines aren’t shown here.

os/port/flashintel+179−0

This diff is large: its 180 lines aren’t shown here.

os/port/flashnand.c+337−0

This diff is large: its 338 lines aren’t shown here.

os/port/fpi.c+304−0

This diff is large: its 305 lines aren’t shown here.

os/port/fpimem.c+136−0

This diff is large: its 137 lines aren’t shown here.

os/port/inferno.c+1030−0

This diff is large: its 1031 lines aren’t shown here.

os/port/latin1.c+76−0

This diff is large: its 77 lines aren’t shown here.

os/port/latin1.h+100−0

This diff is large: its 101 lines aren’t shown here.

os/port/lib.h+211−0

This diff is large: its 212 lines aren’t shown here.

os/port/log.c+186−0

This diff is large: its 187 lines aren’t shown here.

os/port/master+89−0

This diff is large: its 90 lines aren’t shown here.

os/port/master.local+10−0

This diff is large: its 11 lines aren’t shown here.

os/port/mkdevc+216−0

This diff is large: its 217 lines aren’t shown here.

os/port/mkdevlist+86−0

This diff is large: its 87 lines aren’t shown here.

os/port/mkroot+119−0

This diff is large: its 120 lines aren’t shown here.

os/port/mul64fract.c+39−0

This diff is large: its 40 lines aren’t shown here.

os/port/netaux.c+67−0

This diff is large: its 68 lines aren’t shown here.

os/port/netif.c+671−0

This diff is large: its 672 lines aren’t shown here.

os/port/netif.h+134−0

This diff is large: its 135 lines aren’t shown here.

os/port/nocache.c+49−0

This diff is large: its 50 lines aren’t shown here.

os/port/nodynld.c+48−0

This diff is large: its 49 lines aren’t shown here.

os/port/noenv.c+33−0

This diff is large: its 34 lines aren’t shown here.

os/port/noscreen.c+9−0

This diff is large: its 10 lines aren’t shown here.

os/port/parse.c+114−0

This diff is large: its 115 lines aren’t shown here.

os/port/pgrp.c+278−0

This diff is large: its 279 lines aren’t shown here.

os/port/portbreak.c+161−0

This diff is large: its 162 lines aren’t shown here.

os/port/portclock.c+277−0

This diff is large: its 278 lines aren’t shown here.

os/port/portdat.h+673−0

This diff is large: its 674 lines aren’t shown here.

os/port/portfns.h+319−0

This diff is large: its 320 lines aren’t shown here.

os/port/portmkfile+152−0

This diff is large: its 153 lines aren’t shown here.

os/port/print.c+31−0

This diff is large: its 32 lines aren’t shown here.

os/port/proc.c+788−0

This diff is large: its 789 lines aren’t shown here.

os/port/qio.c+1529−0

This diff is large: its 1530 lines aren’t shown here.

os/port/qlock.c+111−0

This diff is large: its 112 lines aren’t shown here.

os/port/random.c+156−0

This diff is large: its 157 lines aren’t shown here.

os/port/rdb.c+112−0

This diff is large: its 113 lines aren’t shown here.

os/port/sd.h+132−0

This diff is large: its 133 lines aren’t shown here.

os/port/swcursor.c+358−0

This diff is large: its 359 lines aren’t shown here.

os/port/sysfile.c+1125−0

This diff is large: its 1126 lines aren’t shown here.

os/port/taslock.c+126−0

This diff is large: its 127 lines aren’t shown here.

os/port/tod.c+283−0

This diff is large: its 284 lines aren’t shown here.

os/port/uart.h+104−0

This diff is large: its 105 lines aren’t shown here.

os/port/xalloc.c+246−0

This diff is large: its 247 lines aren’t shown here.

os/pxa/NOTICE+2−0

This diff is large: its 3 lines aren’t shown here.

os/pxa/clock.c+318−0

This diff is large: its 319 lines aren’t shown here.

os/pxa/devether.c+617−0

This diff is large: its 618 lines aren’t shown here.

os/pxa/devrtc.c+169−0

This diff is large: its 170 lines aren’t shown here.

os/pxa/devuart.c+1070−0

This diff is large: its 1071 lines aren’t shown here.

os/pxa/dma.c+244−0

This diff is large: its 245 lines aren’t shown here.

os/pxa/etherif.h+41−0

This diff is large: its 42 lines aren’t shown here.

os/pxa/fpi.h+61−0

This diff is large: its 62 lines aren’t shown here.

os/pxa/fpiarm.c+483−0

This diff is large: its 484 lines aren’t shown here.

os/pxa/gpio.c+88−0

This diff is large: its 89 lines aren’t shown here.

os/pxa/i2c.c+561−0

This diff is large: its 562 lines aren’t shown here.

os/pxa/l.s+548−0

This diff is large: its 549 lines aren’t shown here.

os/pxa/mmu.c+252−0

This diff is large: its 253 lines aren’t shown here.

os/pxa/pxaio.h+383−0

This diff is large: its 384 lines aren’t shown here.

os/pxa/sa1110break.c+360−0

This diff is large: its 361 lines aren’t shown here.

os/pxa/trap.c+587−0

This diff is large: its 588 lines aren’t shown here.

os/rpcg/NOTICE+4−0

This diff is large: its 5 lines aren’t shown here.

os/rpcg/archrpcg.c+428−0

This diff is large: its 429 lines aren’t shown here.

os/rpcg/archrpcg.h+48−0

This diff is large: its 49 lines aren’t shown here.

os/rpcg/clock.c+145−0

This diff is large: its 146 lines aren’t shown here.

os/rpcg/dat.h+162−0

This diff is large: its 163 lines aren’t shown here.

os/rpcg/fns.h+119−0

This diff is large: its 120 lines aren’t shown here.

os/rpcg/io.h+1−0

This diff is large: its 2 lines aren’t shown here.

os/rpcg/main.c+392−0

This diff is large: its 393 lines aren’t shown here.

os/rpcg/mem.h+157−0

This diff is large: its 158 lines aren’t shown here.

os/rpcg/mkfile+108−0

This diff is large: its 109 lines aren’t shown here.

os/rpcg/mmu.c+20−0

This diff is large: its 21 lines aren’t shown here.

os/rpcg/rpcg+122−0

This diff is large: its 123 lines aren’t shown here.

os/rpcg/tlb.s+24−0

This diff is large: its 25 lines aren’t shown here.

os/sa1110/clock.c+317−0

This diff is large: its 318 lines aren’t shown here.

os/sa1110/devether.c+617−0

This diff is large: its 618 lines aren’t shown here.

os/sa1110/devgpio.c+165−0

This diff is large: its 166 lines aren’t shown here.

os/sa1110/devpcmcia.c+761−0

This diff is large: its 762 lines aren’t shown here.

os/sa1110/devpower.c+377−0

This diff is large: its 378 lines aren’t shown here.

os/sa1110/devrtc.c+169−0

This diff is large: its 170 lines aren’t shown here.

os/sa1110/devuart.c+781−0

This diff is large: its 782 lines aren’t shown here.

os/sa1110/dma.c+233−0

This diff is large: its 234 lines aren’t shown here.

os/sa1110/etherif.h+41−0

This diff is large: its 42 lines aren’t shown here.

os/sa1110/fpi.h+61−0

This diff is large: its 62 lines aren’t shown here.

os/sa1110/fpiarm.c+483−0

This diff is large: its 484 lines aren’t shown here.

os/sa1110/gscreen.c+587−0

This diff is large: its 588 lines aren’t shown here.

os/sa1110/gscreen.h+87−0

This diff is large: its 88 lines aren’t shown here.

os/sa1110/i2c.h+16−0

This diff is large: its 17 lines aren’t shown here.

os/sa1110/i2cgpio.c+274−0

This diff is large: its 275 lines aren’t shown here.

os/sa1110/l.s+530−0

This diff is large: its 531 lines aren’t shown here.

os/sa1110/l3gpio.c+246−0

This diff is large: its 247 lines aren’t shown here.

os/sa1110/mmu.c+140−0

This diff is large: its 141 lines aren’t shown here.

os/sa1110/sa1110break.c+360−0

This diff is large: its 361 lines aren’t shown here.

os/sa1110/sa1110io.h+500−0

This diff is large: its 501 lines aren’t shown here.

os/sa1110/softcursor.c+365−0

This diff is large: its 366 lines aren’t shown here.

os/sa1110/suspend.c+161−0

This diff is large: its 162 lines aren’t shown here.

os/sa1110/trap.c+601−0

This diff is large: its 602 lines aren’t shown here.

utils/0a/a.h+183−0

This diff is large: its 184 lines aren’t shown here.

utils/0a/a.y+588−0

This diff is large: its 589 lines aren’t shown here.

utils/0a/l.s+703−0

This diff is large: its 704 lines aren’t shown here.

utils/0a/lex.c+697−0

This diff is large: its 698 lines aren’t shown here.

utils/0a/mkfile+30−0

This diff is large: its 31 lines aren’t shown here.

utils/0c/cgen.c+1148−0

This diff is large: its 1149 lines aren’t shown here.

utils/0c/enam.c+118−0

This diff is large: its 119 lines aren’t shown here.

utils/0c/gc.h+332−0

This diff is large: its 333 lines aren’t shown here.

utils/0c/list.c+244−0

This diff is large: its 245 lines aren’t shown here.

utils/0c/mkenam+15−0

This diff is large: its 16 lines aren’t shown here.

utils/0c/mkfile+30−0

This diff is large: its 31 lines aren’t shown here.

utils/0c/mul.c+608−0

This diff is large: its 609 lines aren’t shown here.

utils/0c/peep.c+694−0

This diff is large: its 695 lines aren’t shown here.

utils/0c/reg.c+1151−0

This diff is large: its 1152 lines aren’t shown here.

utils/0c/sgen.c+569−0

This diff is large: its 570 lines aren’t shown here.

utils/0c/swt.c+727−0

This diff is large: its 728 lines aren’t shown here.

utils/0c/txt.c+1483−0

This diff is large: its 1484 lines aren’t shown here.

utils/0c/v.out.h+201−0

This diff is large: its 202 lines aren’t shown here.

utils/0l/Nt.c+77−0

This diff is large: its 78 lines aren’t shown here.

utils/0l/Plan9.c+57−0

This diff is large: its 58 lines aren’t shown here.

utils/0l/Posix.c+80−0

This diff is large: its 81 lines aren’t shown here.

utils/0l/asm.c+1433−0

This diff is large: its 1434 lines aren’t shown here.

utils/0l/enam.c+122−0

This diff is large: its 123 lines aren’t shown here.

utils/0l/l.h+329−0

This diff is large: its 330 lines aren’t shown here.

utils/0l/list.c+277−0

This diff is large: its 278 lines aren’t shown here.

utils/0l/mkfile+30−0

This diff is large: its 31 lines aren’t shown here.

utils/0l/noop.c+420−0

This diff is large: its 421 lines aren’t shown here.

utils/0l/obj.c+1384−0

This diff is large: its 1385 lines aren’t shown here.

utils/0l/optab.c+221−0

This diff is large: its 222 lines aren’t shown here.

utils/0l/pass.c+498−0

This diff is large: its 499 lines aren’t shown here.

utils/0l/sched.c+709−0

This diff is large: its 710 lines aren’t shown here.

utils/0l/span.c+628−0

This diff is large: its 629 lines aren’t shown here.

utils/1a/a.h+198−0

This diff is large: its 199 lines aren’t shown here.

utils/1a/a.y+402−0

This diff is large: its 403 lines aren’t shown here.

utils/1a/l.s+479−0

This diff is large: its 480 lines aren’t shown here.

utils/1a/lex.c+925−0

This diff is large: its 926 lines aren’t shown here.

utils/1a/mkfile+30−0

This diff is large: its 31 lines aren’t shown here.

utils/1c/cgen.c+1396−0

This diff is large: its 1397 lines aren’t shown here.

utils/1c/enam.c+425−0

This diff is large: its 426 lines aren’t shown here.

utils/1c/gc.h+339−0

This diff is large: its 340 lines aren’t shown here.

utils/1c/list.c+319−0

This diff is large: its 320 lines aren’t shown here.

utils/1c/mkfile+29−0

This diff is large: its 30 lines aren’t shown here.

utils/1c/mul.c+174−0

This diff is large: its 175 lines aren’t shown here.

utils/1c/peep.c+1060−0

This diff is large: its 1061 lines aren’t shown here.

utils/1c/reg.c+1221−0

This diff is large: its 1222 lines aren’t shown here.

utils/1c/sgen.c+694−0

This diff is large: its 695 lines aren’t shown here.

utils/1c/swt.c+964−0

This diff is large: its 965 lines aren’t shown here.

utils/1c/txt.c+903−0

This diff is large: its 904 lines aren’t shown here.

utils/1l/Nt.c+77−0

This diff is large: its 78 lines aren’t shown here.

utils/1l/Plan9.c+57−0

This diff is large: its 58 lines aren’t shown here.

utils/1l/Posix.c+80−0

This diff is large: its 81 lines aren’t shown here.

utils/1l/asm.c+1534−0

This diff is large: its 1535 lines aren’t shown here.

utils/1l/l.h+268−0

This diff is large: its 269 lines aren’t shown here.

utils/1l/list.c+334−0

This diff is large: its 335 lines aren’t shown here.

utils/1l/mkfile+32−0

This diff is large: its 33 lines aren’t shown here.

utils/1l/obj.c+1380−0

This diff is large: its 1381 lines aren’t shown here.

utils/1l/optab.c+444−0

This diff is large: its 445 lines aren’t shown here.

utils/1l/pass.c+673−0

This diff is large: its 674 lines aren’t shown here.

utils/1l/span.c+515−0

This diff is large: its 516 lines aren’t shown here.

utils/2a/a.h+200−0

This diff is large: its 201 lines aren’t shown here.

utils/2a/a.y+540−0

This diff is large: its 541 lines aren’t shown here.

utils/2a/l.s+479−0

This diff is large: its 480 lines aren’t shown here.

utils/2a/lex.c+935−0

This diff is large: its 936 lines aren’t shown here.

utils/2a/mkfile+30−0

This diff is large: its 31 lines aren’t shown here.

utils/2c/2.out.h+523−0

This diff is large: its 524 lines aren’t shown here.

utils/2c/Update+7−0

This diff is large: its 8 lines aren’t shown here.

utils/2c/cgen.c+1404−0

This diff is large: its 1405 lines aren’t shown here.

utils/2c/enam.c+425−0

This diff is large: its 426 lines aren’t shown here.

utils/2c/gc.h+357−0

This diff is large: its 358 lines aren’t shown here.

utils/2c/list.c+384−0

This diff is large: its 385 lines aren’t shown here.

utils/2c/mkfile+30−0

This diff is large: its 31 lines aren’t shown here.

utils/2c/mul.c+174−0

This diff is large: its 175 lines aren’t shown here.

utils/2c/peep.c+1076−0

This diff is large: its 1077 lines aren’t shown here.

utils/2c/reg.c+1275−0

This diff is large: its 1276 lines aren’t shown here.

utils/2c/sgen.c+819−0

This diff is large: its 820 lines aren’t shown here.

utils/2c/swt.c+1046−0

This diff is large: its 1047 lines aren’t shown here.

utils/2c/txt.c+940−0

This diff is large: its 941 lines aren’t shown here.

utils/2l/Nt.c+77−0

This diff is large: its 78 lines aren’t shown here.

utils/2l/Plan9.c+57−0

This diff is large: its 58 lines aren’t shown here.

utils/2l/Posix.c+80−0

This diff is large: its 81 lines aren’t shown here.

utils/2l/asm.c+1569−0

This diff is large: its 1570 lines aren’t shown here.

utils/2l/l.h+263−0

This diff is large: its 264 lines aren’t shown here.

utils/2l/list.c+395−0

This diff is large: its 396 lines aren’t shown here.

utils/2l/mkfile+26−0

This diff is large: its 27 lines aren’t shown here.

utils/2l/obj.c+1402−0

This diff is large: its 1403 lines aren’t shown here.

utils/2l/optab.c+444−0

This diff is large: its 445 lines aren’t shown here.

utils/2l/pass.c+538−0

This diff is large: its 539 lines aren’t shown here.

utils/2l/span.c+551−0

This diff is large: its 552 lines aren’t shown here.

utils/5a/a.h+182−0

This diff is large: its 183 lines aren’t shown here.

utils/5a/a.y+673−0

This diff is large: its 674 lines aren’t shown here.

utils/5a/lex.c+689−0

This diff is large: its 690 lines aren’t shown here.

utils/5a/mkfile+30−0

This diff is large: its 31 lines aren’t shown here.

utils/5c/5.out.h+197−0

This diff is large: its 198 lines aren’t shown here.

utils/5c/cgen.c+1156−0

This diff is large: its 1157 lines aren’t shown here.

utils/5c/enam.c+98−0

This diff is large: its 99 lines aren’t shown here.

utils/5c/gc.h+349−0

This diff is large: its 350 lines aren’t shown here.

utils/5c/list.c+304−0

This diff is large: its 305 lines aren’t shown here.

utils/5c/mkenam+15−0

This diff is large: its 16 lines aren’t shown here.

utils/5c/mkfile+30−0

This diff is large: its 31 lines aren’t shown here.

utils/5c/mul.c+609−0

This diff is large: its 610 lines aren’t shown here.

utils/5c/peep.c+1440−0

This diff is large: its 1441 lines aren’t shown here.

utils/5c/reg.c+1157−0

This diff is large: its 1158 lines aren’t shown here.

utils/5c/sgen.c+613−0

This diff is large: its 614 lines aren’t shown here.

utils/5c/swt.c+757−0

This diff is large: its 758 lines aren’t shown here.

utils/5c/txt.c+1249−0

This diff is large: its 1250 lines aren’t shown here.

utils/5coff/5coff.c+316−0

This diff is large: its 317 lines aren’t shown here.

utils/5coff/NOTICE+27−0

This diff is large: its 28 lines aren’t shown here.

utils/5coff/auxi.c+251−0

This diff is large: its 252 lines aren’t shown here.

utils/5coff/auxi.h+46−0

This diff is large: its 47 lines aren’t shown here.

utils/5coff/coff.c+642−0

This diff is large: its 643 lines aren’t shown here.

utils/5coff/mkfile+23−0

This diff is large: its 24 lines aren’t shown here.

utils/5coff/readcoff.c+298−0

This diff is large: its 299 lines aren’t shown here.

utils/5cv/5cv.c+353−0

This diff is large: its 354 lines aren’t shown here.

utils/5cv/mkfile+18−0

This diff is large: its 19 lines aren’t shown here.

utils/5l/Nt.c+77−0

This diff is large: its 78 lines aren’t shown here.

utils/5l/Plan9.c+57−0

This diff is large: its 58 lines aren’t shown here.

utils/5l/Posix.c+80−0

This diff is large: its 81 lines aren’t shown here.

utils/5l/asm.c+1793−0

This diff is large: its 1794 lines aren’t shown here.

utils/5l/l.h+444−0

This diff is large: its 445 lines aren’t shown here.

utils/5l/list.c+360−0

This diff is large: its 361 lines aren’t shown here.

utils/5l/mkfile+32−0

This diff is large: its 33 lines aren’t shown here.

utils/5l/noop.c+894−0

This diff is large: its 895 lines aren’t shown here.

utils/5l/obj.c+1557−0

This diff is large: its 1558 lines aren’t shown here.

utils/5l/optab.c+253−0

This diff is large: its 254 lines aren’t shown here.

utils/5l/pass.c+942−0

This diff is large: its 943 lines aren’t shown here.

utils/5l/span.c+1262−0

This diff is large: its 1263 lines aren’t shown here.

utils/5l/thumb.c+1637−0

This diff is large: its 1638 lines aren’t shown here.

utils/6c/6.out.h+820−0

This diff is large: its 821 lines aren’t shown here.

utils/8a/a.h+194−0

This diff is large: its 195 lines aren’t shown here.

utils/8a/a.y+520−0

This diff is large: its 521 lines aren’t shown here.

utils/8a/l.s+704−0

This diff is large: its 705 lines aren’t shown here.

utils/8a/lex.c+895−0

This diff is large: its 896 lines aren’t shown here.

utils/8a/mkfile+30−0

This diff is large: its 31 lines aren’t shown here.

utils/8c/8.out.h+445−0

This diff is large: its 446 lines aren’t shown here.

utils/8c/cgen.c+1821−0

This diff is large: its 1822 lines aren’t shown here.

utils/8c/cgen64.c+2711−0

This diff is large: its 2712 lines aren’t shown here.

utils/8c/div.c+206−0

This diff is large: its 207 lines aren’t shown here.

utils/8c/enam.c+337−0

This diff is large: its 338 lines aren’t shown here.

utils/8c/gc.h+374−0

This diff is large: its 375 lines aren’t shown here.

utils/8c/list.c+282−0

This diff is large: its 283 lines aren’t shown here.

utils/8c/machcap.c+86−0

This diff is large: its 87 lines aren’t shown here.

utils/8c/mkenam+15−0

This diff is large: its 16 lines aren’t shown here.

utils/8c/mkfile+35−0

This diff is large: its 36 lines aren’t shown here.

utils/8c/mul.c+428−0

This diff is large: its 429 lines aren’t shown here.

utils/8c/peep.c+757−0

This diff is large: its 758 lines aren’t shown here.

utils/8c/reg.c+1255−0

This diff is large: its 1256 lines aren’t shown here.

utils/8c/sgen.c+842−0

This diff is large: its 843 lines aren’t shown here.

utils/8c/swt.c+647−0

This diff is large: its 648 lines aren’t shown here.

utils/8c/txt.c+1410−0

This diff is large: its 1411 lines aren’t shown here.

utils/8l/Nt.c+77−0

This diff is large: its 78 lines aren’t shown here.

utils/8l/Plan9.c+57−0

This diff is large: its 58 lines aren’t shown here.

utils/8l/Posix.c+80−0

This diff is large: its 81 lines aren’t shown here.

utils/8l/asm.c+502−0

This diff is large: its 503 lines aren’t shown here.

utils/8l/l.h+349−0

This diff is large: its 350 lines aren’t shown here.

utils/8l/list.c+292−0

This diff is large: its 293 lines aren’t shown here.

utils/8l/mkfile+29−0

This diff is large: its 30 lines aren’t shown here.

utils/8l/obj.c+1492−0

This diff is large: its 1493 lines aren’t shown here.

utils/8l/optab.c+654−0

This diff is large: its 655 lines aren’t shown here.

utils/8l/pass.c+763−0

This diff is large: its 764 lines aren’t shown here.

utils/8l/span.c+1387−0

This diff is large: its 1388 lines aren’t shown here.

utils/NOTICE+34−0

This diff is large: its 35 lines aren’t shown here.

utils/acid/386+146−0

This diff is large: its 147 lines aren’t shown here.

utils/acid/B.sh+7−0

This diff is large: its 8 lines aren’t shown here.

utils/acid/acid.h+317−0

This diff is large: its 318 lines aren’t shown here.

utils/acid/arm+1−0

This diff is large: its 2 lines aren’t shown here.

utils/acid/builtin.c+1285−0

This diff is large: its 1286 lines aren’t shown here.

utils/acid/dbg.y+402−0

This diff is large: its 403 lines aren’t shown here.

utils/acid/dot.c+152−0

This diff is large: its 153 lines aren’t shown here.

This diff is larger than a page shows: the files after these aren’t listed. Clone the repository to see all of it.