Browse Source

Plan 9 from Bell Labs 2005-11-07

David du Colombier 18 years ago
parent
commit
c0a86e3567
100 changed files with 5253 additions and 3112 deletions
  1. 248 247
      dist/replica/_plan9.db
  2. 247 246
      dist/replica/plan9.db
  3. 273 0
      dist/replica/plan9.log
  4. 22 19
      sys/include/a.out.h
  5. 59 55
      sys/include/mach.h
  6. 21 5
      sys/lib/acid/leak
  7. 17 5
      sys/man/1/strip
  8. 6 3
      sys/man/3/vga
  9. 9 1
      sys/man/4/factotum
  10. 14 0
      sys/man/8/plan9.ini
  11. 13 10
      sys/man/8/statusbar
  12. 0 1
      sys/man/8/vga
  13. 1 1
      sys/src/9/alphapc/apc
  14. 11 4
      sys/src/9/alphapc/dat.h
  15. 1 4
      sys/src/9/alphapc/devvga.c
  16. 3 1
      sys/src/9/alphapc/fns.h
  17. 7 7
      sys/src/9/alphapc/main.c
  18. 21 7
      sys/src/9/alphapc/mmu.c
  19. 20 7
      sys/src/9/alphapc/screen.h
  20. 0 2
      sys/src/9/alphapc/sd53c8xx.c
  21. 12 4
      sys/src/9/bitsy/dat.h
  22. 19 1
      sys/src/9/bitsy/devpenmouse.c
  23. 38 49
      sys/src/9/bitsy/main.c
  24. 1 1
      sys/src/9/bitsy/mkfile
  25. 1 21
      sys/src/9/bitsy/sdata.c
  26. 3 1
      sys/src/9/boot/bootauth.c
  27. 11 5
      sys/src/9/mtx/dat.h
  28. 3 7
      sys/src/9/mtx/main.c
  29. 10 10
      sys/src/9/pc/apbootstrap.s
  30. 13 0
      sys/src/9/pc/apic.c
  31. 2 0
      sys/src/9/pc/apm.c
  32. 2 0
      sys/src/9/pc/archmp.c
  33. 19 7
      sys/src/9/pc/dat.h
  34. 2 0
      sys/src/9/pc/devarch.c
  35. 4 5
      sys/src/9/pc/devether.c
  36. 5 3
      sys/src/9/pc/devlml.c
  37. 8 6
      sys/src/9/pc/devpccard.c
  38. 13 13
      sys/src/9/pc/devtv.c
  39. 33 5
      sys/src/9/pc/devvga.c
  40. 3 4
      sys/src/9/pc/dma.c
  41. 0 3
      sys/src/9/pc/ether79c970.c
  42. 17 17
      sys/src/9/pc/ether8139.c
  43. 8 7
      sys/src/9/pc/ether8169.c
  44. 6 6
      sys/src/9/pc/ether82543gc.c
  45. 10 10
      sys/src/9/pc/ether82557.c
  46. 2 0
      sys/src/9/pc/ether83815.c
  47. 3 3
      sys/src/9/pc/ether8390.c
  48. 5 5
      sys/src/9/pc/etherdp83820.c
  49. 4 4
      sys/src/9/pc/etherelnk3.c
  50. 6 6
      sys/src/9/pc/etherga620.c
  51. 10 8
      sys/src/9/pc/etherigbe.c
  52. 1 1
      sys/src/9/pc/ethervt6102.c
  53. 6 5
      sys/src/9/pc/etherwavelan.c
  54. 24 10
      sys/src/9/pc/fns.h
  55. 15 0
      sys/src/9/pc/i8259.c
  56. 269 21
      sys/src/9/pc/l.s
  57. 42 17
      sys/src/9/pc/main.c
  58. 36 25
      sys/src/9/pc/mem.h
  59. 364 88
      sys/src/9/pc/memory.c
  60. 38 17
      sys/src/9/pc/mkfile
  61. 656 282
      sys/src/9/pc/mmu.c
  62. 10 5
      sys/src/9/pc/mp.c
  63. 2 0
      sys/src/9/pc/mp.h
  64. 2 0
      sys/src/9/pc/pc
  65. 4 1
      sys/src/9/pc/pcauth
  66. 1 0
      sys/src/9/pc/pccd
  67. 2 0
      sys/src/9/pc/pccpu
  68. 2 0
      sys/src/9/pc/pccpuf
  69. 2 0
      sys/src/9/pc/pcdisk
  70. 2 0
      sys/src/9/pc/pcf
  71. 2 0
      sys/src/9/pc/pcflop
  72. 19 0
      sys/src/9/pc/pci.c
  73. 132 0
      sys/src/9/pc/realmode.c
  74. 0 7
      sys/src/9/pc/reboot.h
  75. 339 28
      sys/src/9/pc/screen.c
  76. 25 7
      sys/src/9/pc/screen.h
  77. 190 68
      sys/src/9/pc/sd53c8xx.c
  78. 0 773
      sys/src/9/pc/sd53c8xx.i
  79. 36 25
      sys/src/9/pc/sd53c8xx.n
  80. 103 91
      sys/src/9/pc/sdata.c
  81. 1346 0
      sys/src/9/pc/sdmv50xx.c
  82. 1 7
      sys/src/9/pc/sdmylex.c
  83. 0 20
      sys/src/9/pc/sdscsi.c
  84. 39 10
      sys/src/9/pc/trap.c
  85. 12 3
      sys/src/9/pc/vga.c
  86. 23 80
      sys/src/9/pc/vga3dfx.c
  87. 2 1
      sys/src/9/pc/vgaark2000pv.c
  88. 1 0
      sys/src/9/pc/vgabt485.c
  89. 4 30
      sys/src/9/pc/vgaclgd542x.c
  90. 29 87
      sys/src/9/pc/vgaclgd546x.c
  91. 2 1
      sys/src/9/pc/vgact65545.c
  92. 17 39
      sys/src/9/pc/vgacyber938x.c
  93. 2 1
      sys/src/9/pc/vgaet4000.c
  94. 15 61
      sys/src/9/pc/vgahiqvideo.c
  95. 38 88
      sys/src/9/pc/vgai81x.c
  96. 13 53
      sys/src/9/pc/vgamach64xx.c
  97. 22 73
      sys/src/9/pc/vgamga2164w.c
  98. 41 93
      sys/src/9/pc/vgamga4xx.c
  99. 27 84
      sys/src/9/pc/vganeomagic.c
  100. 29 74
      sys/src/9/pc/vganvidia.c

File diff suppressed because it is too large
+ 248 - 247
dist/replica/_plan9.db


+ 247 - 246
dist/replica/plan9.db

@@ -1,25 +1,25 @@
 386 - 20000000775 sys sys 1010957353 0
 386 - 20000000775 sys sys 1010957353 0
-386/9load - 775 sys sys 1112757508 215872
-386/9loaddebug - 775 sys sys 1126926546 310558
-386/9loadlite - 775 sys sys 1112757508 135244
-386/9loadlitedebug - 775 sys sys 1126926546 198805
-386/9pc - 775 sys sys 1130961222 1855993
-386/9pc.gz - 664 sys sys 1126005796 645747
-386/9pccpu - 775 sys sys 1130961225 1519780
-386/9pccpu.gz - 664 sys sys 1126005799 530959
-386/9pcdisk - 775 sys sys 1130961229 2047043
-386/9pcdisk.gz - 664 sys sys 1126005804 736406
-386/9pcf - 775 sys sys 1130961234 2390000
-386/9pcf.gz - 664 sys sys 1126005809 888685
-386/9pxeload - 775 sys sys 1112757508 215872
+386/9load - 775 sys sys 1131317303 216948
+386/9loaddebug - 775 sys sys 1131317308 311884
+386/9loadlite - 775 sys sys 1131317306 135668
+386/9loadlitedebug - 775 sys sys 1131317312 200131
+386/9pc - 775 sys sys 1131327135 1881573
+386/9pc.gz - 664 sys sys 1131327137 658788
+386/9pccpu - 775 sys sys 1131327140 1555849
+386/9pccpu.gz - 664 sys sys 1131327141 552578
+386/9pcdisk - 775 sys sys 1131327146 2072564
+386/9pcdisk.gz - 664 sys sys 1131327148 746868
+386/9pcf - 775 sys sys 1131327153 2415653
+386/9pcf.gz - 664 sys sys 1131327156 900998
+386/9pxeload - 775 sys sys 1131317321 216948
 386/_9pcdisk.gz - 664 sys sys 1039764191 695837
 386/_9pcdisk.gz - 664 sys sys 1039764191 695837
 386/bin - 20000000775 sys sys 1018897690 0
 386/bin - 20000000775 sys sys 1018897690 0
 386/bin/8a - 775 sys sys 1130594690 116001
 386/bin/8a - 775 sys sys 1130594690 116001
-386/bin/8c - 775 sys sys 1131163700 358353
+386/bin/8c - 775 sys sys 1131296671 358395
 386/bin/8l - 775 sys sys 1130384229 115712
 386/bin/8l - 775 sys sys 1130384229 115712
 386/bin/9660srv - 775 sys sys 1130594690 104069
 386/bin/9660srv - 775 sys sys 1130594690 104069
 386/bin/aan - 775 sys sys 1130594690 130742
 386/bin/aan - 775 sys sys 1130594690 130742
-386/bin/acid - 775 sys sys 1130594691 390519
+386/bin/acid - 775 sys sys 1131296672 400034
 386/bin/acme - 775 sys sys 1131109821 428636
 386/bin/acme - 775 sys sys 1131109821 428636
 386/bin/ape - 20000000775 sys sys 1016944144 0
 386/bin/ape - 20000000775 sys sys 1016944144 0
 386/bin/ape/basename - 775 sys sys 1127360557 132862
 386/bin/ape/basename - 775 sys sys 1127360557 132862
@@ -38,7 +38,7 @@
 386/bin/ape/tar - 775 sys sys 1130594693 61935
 386/bin/ape/tar - 775 sys sys 1130594693 61935
 386/bin/ape/uname - 775 sys sys 1127360563 132691
 386/bin/ape/uname - 775 sys sys 1127360563 132691
 386/bin/aquarela - 775 sys sys 1064598027 319170
 386/bin/aquarela - 775 sys sys 1064598027 319170
-386/bin/ar - 775 sys sys 1130594693 110870
+386/bin/ar - 775 sys sys 1131296672 111983
 386/bin/archfs - 775 sys sys 1130731906 141206
 386/bin/archfs - 775 sys sys 1130731906 141206
 386/bin/ascii - 775 sys sys 1130594693 64691
 386/bin/ascii - 775 sys sys 1130594693 64691
 386/bin/astro - 775 sys sys 1130384233 138837
 386/bin/astro - 775 sys sys 1130384233 138837
@@ -53,7 +53,7 @@
 386/bin/auth/debug - 775 sys sys 1130594696 101087
 386/bin/auth/debug - 775 sys sys 1130594696 101087
 386/bin/auth/disable - 775 sys sys 1020319057 146
 386/bin/auth/disable - 775 sys sys 1020319057 146
 386/bin/auth/enable - 775 sys sys 1020319057 134
 386/bin/auth/enable - 775 sys sys 1020319057 134
-386/bin/auth/factotum - 775 sys sys 1130731907 312978
+386/bin/auth/factotum - 775 sys sys 1131296673 313125
 386/bin/auth/fgui - 775 sys sys 1131109822 217996
 386/bin/auth/fgui - 775 sys sys 1131109822 217996
 386/bin/auth/guard.srv - 775 sys sys 1130594697 142873
 386/bin/auth/guard.srv - 775 sys sys 1130594697 142873
 386/bin/auth/iam - 775 sys sys 1085076981 50791
 386/bin/auth/iam - 775 sys sys 1085076981 50791
@@ -117,18 +117,18 @@
 386/bin/aux/mklatinkbd - 775 sys sys 1130594709 64202
 386/bin/aux/mklatinkbd - 775 sys sys 1130594709 64202
 386/bin/aux/mnihongo - 775 sys sys 1131109822 139403
 386/bin/aux/mnihongo - 775 sys sys 1131109822 139403
 386/bin/aux/mouse - 775 sys sys 1130384253 44044
 386/bin/aux/mouse - 775 sys sys 1130384253 44044
-386/bin/aux/ms2 - 775 sys sys 1130594710 85700
+386/bin/aux/ms2 - 775 sys sys 1131296673 87464
 386/bin/aux/msexceltables - 775 sys sys 1130594710 81256
 386/bin/aux/msexceltables - 775 sys sys 1130594710 81256
 386/bin/aux/mswordstrings - 775 sys sys 1130594710 65340
 386/bin/aux/mswordstrings - 775 sys sys 1130594710 65340
 386/bin/aux/na - 775 sys sys 1130594710 154218
 386/bin/aux/na - 775 sys sys 1130594710 154218
 386/bin/aux/nfsmount - 775 sys sys 1130594711 234124
 386/bin/aux/nfsmount - 775 sys sys 1130594711 234124
-386/bin/aux/nfsserver - 775 sys sys 1130594711 185436
+386/bin/aux/nfsserver - 775 sys sys 1131296673 185439
 386/bin/aux/olefs - 775 sys sys 1130731910 143686
 386/bin/aux/olefs - 775 sys sys 1130731910 143686
 386/bin/aux/p9bitpost - 775 sys sys 1104121982 127974
 386/bin/aux/p9bitpost - 775 sys sys 1104121982 127974
 386/bin/aux/pcmcia - 775 sys sys 1130384255 46923
 386/bin/aux/pcmcia - 775 sys sys 1130384255 46923
-386/bin/aux/pcnfsd - 775 sys sys 1130594712 129362
+386/bin/aux/pcnfsd - 775 sys sys 1131296674 129365
 386/bin/aux/portmap - 775 sys sys 1130594713 143642
 386/bin/aux/portmap - 775 sys sys 1130594713 143642
-386/bin/aux/portmapper - 775 sys sys 1130594713 128248
+386/bin/aux/portmapper - 775 sys sys 1131296674 128251
 386/bin/aux/postgif - 775 sys sys 1087442507 175380
 386/bin/aux/postgif - 775 sys sys 1087442507 175380
 386/bin/aux/postprint - 775 sys sys 1087442507 160041
 386/bin/aux/postprint - 775 sys sys 1087442507 160041
 386/bin/aux/postreverse - 775 sys sys 1087442508 164726
 386/bin/aux/postreverse - 775 sys sys 1087442508 164726
@@ -188,7 +188,7 @@
 386/bin/cpu - 775 sys sys 1130594724 139130
 386/bin/cpu - 775 sys sys 1130594724 139130
 386/bin/crop - 775 sys sys 1130594724 116040
 386/bin/crop - 775 sys sys 1130594724 116040
 386/bin/date - 775 sys sys 1130384272 43279
 386/bin/date - 775 sys sys 1130384272 43279
-386/bin/db - 775 sys sys 1130594725 336349
+386/bin/db - 775 sys sys 1131302428 345503
 386/bin/dc - 775 sys sys 1130594725 99051
 386/bin/dc - 775 sys sys 1130594725 99051
 386/bin/dd - 775 sys sys 1130384273 45416
 386/bin/dd - 775 sys sys 1130384273 45416
 386/bin/deroff - 775 sys sys 1130594726 74267
 386/bin/deroff - 775 sys sys 1130594726 74267
@@ -225,7 +225,7 @@
 386/bin/faces - 775 sys sys 1131109826 193479
 386/bin/faces - 775 sys sys 1131109826 193479
 386/bin/factor - 775 sys sys 1130594733 61498
 386/bin/factor - 775 sys sys 1130594733 61498
 386/bin/fcp - 775 sys sys 1131163702 82218
 386/bin/fcp - 775 sys sys 1131163702 82218
-386/bin/file - 775 sys sys 1130594733 119129
+386/bin/file - 775 sys sys 1131296674 121021
 386/bin/fmt - 775 sys sys 1130594733 65324
 386/bin/fmt - 775 sys sys 1130594733 65324
 386/bin/fortune - 775 sys sys 1130594734 67159
 386/bin/fortune - 775 sys sys 1130594734 67159
 386/bin/fossil - 20000000775 sys sys 1042005470 0
 386/bin/fossil - 20000000775 sys sys 1042005470 0
@@ -313,8 +313,8 @@
 386/bin/join - 775 sys sys 1130594758 114123
 386/bin/join - 775 sys sys 1130594758 114123
 386/bin/jpg - 775 sys sys 1130594758 174551
 386/bin/jpg - 775 sys sys 1130594758 174551
 386/bin/kbmap - 775 sys sys 1131109830 143398
 386/bin/kbmap - 775 sys sys 1131109830 143398
-386/bin/kprof - 775 sys sys 1130594758 102550
-386/bin/ktrace - 775 sys sys 1130594759 116639
+386/bin/kprof - 775 sys sys 1131296675 105507
+386/bin/ktrace - 775 sys sys 1131296675 121949
 386/bin/lens - 775 sys sys 1131109830 150495
 386/bin/lens - 775 sys sys 1131109830 150495
 386/bin/lex - 775 sys sys 1130594760 98687
 386/bin/lex - 775 sys sys 1130594760 98687
 386/bin/lnfs - 775 sys sys 1130594760 99472
 386/bin/lnfs - 775 sys sys 1130594760 99472
@@ -322,7 +322,7 @@
 386/bin/ls - 775 sys sys 1130594760 82503
 386/bin/ls - 775 sys sys 1130594760 82503
 386/bin/mc - 775 sys sys 1130594760 133643
 386/bin/mc - 775 sys sys 1130594760 133643
 386/bin/md5sum - 775 sys sys 1130594761 61297
 386/bin/md5sum - 775 sys sys 1130594761 61297
-386/bin/mk - 775 sys sys 1130594761 144071
+386/bin/mk - 775 sys sys 1131302428 144690
 386/bin/mkdir - 775 sys sys 1130594761 60996
 386/bin/mkdir - 775 sys sys 1130594761 60996
 386/bin/mkpaqfs - 775 sys sys 1130594762 94532
 386/bin/mkpaqfs - 775 sys sys 1130594762 94532
 386/bin/mntgen - 775 sys sys 1130731913 139629
 386/bin/mntgen - 775 sys sys 1130731913 139629
@@ -346,7 +346,7 @@
 386/bin/netstat - 775 sys sys 1130594767 84696
 386/bin/netstat - 775 sys sys 1130594767 84696
 386/bin/news - 775 sys sys 1130594767 71692
 386/bin/news - 775 sys sys 1130594767 71692
 386/bin/nfs - 775 sys sys 1130731913 315832
 386/bin/nfs - 775 sys sys 1130731913 315832
-386/bin/nm - 775 sys sys 1130594769 121826
+386/bin/nm - 775 sys sys 1131296675 125784
 386/bin/nntpfs - 775 sys sys 1130731914 161341
 386/bin/nntpfs - 775 sys sys 1130731914 161341
 386/bin/ns - 775 sys sys 1130594769 65283
 386/bin/ns - 775 sys sys 1130594769 65283
 386/bin/p - 775 sys sys 1130594769 65013
 386/bin/p - 775 sys sys 1130594769 65013
@@ -364,7 +364,7 @@
 386/bin/ppm - 775 sys sys 1130594773 149370
 386/bin/ppm - 775 sys sys 1130594773 149370
 386/bin/pr - 775 sys sys 1130594773 77431
 386/bin/pr - 775 sys sys 1130594773 77431
 386/bin/primes - 775 sys sys 1130384322 38811
 386/bin/primes - 775 sys sys 1130384322 38811
-386/bin/prof - 775 sys sys 1130594773 107968
+386/bin/prof - 775 sys sys 1131296676 110924
 386/bin/proof - 775 sys sys 1131109832 178492
 386/bin/proof - 775 sys sys 1131109832 178492
 386/bin/ps - 775 sys sys 1130594774 68017
 386/bin/ps - 775 sys sys 1130594774 68017
 386/bin/pwd - 775 sys sys 1130384323 36915
 386/bin/pwd - 775 sys sys 1130384323 36915
@@ -393,10 +393,10 @@
 386/bin/sed - 775 sys sys 1130594781 89546
 386/bin/sed - 775 sys sys 1130594781 89546
 386/bin/seq - 775 sys sys 1130384331 38414
 386/bin/seq - 775 sys sys 1130384331 38414
 386/bin/sha1sum - 775 sys sys 1130594782 61165
 386/bin/sha1sum - 775 sys sys 1130594782 61165
-386/bin/size - 775 sys sys 1130594782 77006
+386/bin/size - 775 sys sys 1131296676 78794
 386/bin/sleep - 775 sys sys 1085077097 3413
 386/bin/sleep - 775 sys sys 1085077097 3413
-386/bin/snap - 775 sys sys 1130594783 303743
-386/bin/snapfs - 775 sys sys 1130731915 373001
+386/bin/snap - 775 sys sys 1131302429 310917
+386/bin/snapfs - 775 sys sys 1131302430 380175
 386/bin/sniffer - 775 sys sys 1038443185 99028
 386/bin/sniffer - 775 sys sys 1038443185 99028
 386/bin/snoopy - 775 sys sys 1130594784 168241
 386/bin/snoopy - 775 sys sys 1130594784 168241
 386/bin/sort - 775 sys sys 1130594784 82308
 386/bin/sort - 775 sys sys 1130594784 82308
@@ -409,13 +409,13 @@
 386/bin/sshnet - 775 sys sys 1130731916 283308
 386/bin/sshnet - 775 sys sys 1130731916 283308
 386/bin/stats - 775 sys sys 1131109834 190360
 386/bin/stats - 775 sys sys 1131109834 190360
 386/bin/strings - 775 sys sys 1130594787 62147
 386/bin/strings - 775 sys sys 1130594787 62147
-386/bin/strip - 775 sys sys 1130594787 62013
+386/bin/strip - 775 sys sys 1131296676 80766
 386/bin/sum - 775 sys sys 1130384338 39488
 386/bin/sum - 775 sys sys 1130384338 39488
 386/bin/swap - 775 sys sys 1130594787 62126
 386/bin/swap - 775 sys sys 1130594787 62126
 386/bin/syscall - 775 sys sys 1130594788 73568
 386/bin/syscall - 775 sys sys 1130594788 73568
 386/bin/tail - 775 sys sys 1130594788 66201
 386/bin/tail - 775 sys sys 1130594788 66201
 386/bin/tar - 775 sys sys 1130594788 97067
 386/bin/tar - 775 sys sys 1130594788 97067
-386/bin/tbl - 775 sys sys 1130594788 113269
+386/bin/tbl - 775 sys sys 1131302431 113308
 386/bin/tcs - 775 sys sys 1130384340 256598
 386/bin/tcs - 775 sys sys 1130384340 256598
 386/bin/tee - 775 sys sys 1130384340 38446
 386/bin/tee - 775 sys sys 1130384340 38446
 386/bin/telco - 775 sys sys 1130594788 103347
 386/bin/telco - 775 sys sys 1130594788 103347
@@ -429,7 +429,7 @@
 386/bin/topng - 775 sys sys 1130594792 138351
 386/bin/topng - 775 sys sys 1130594792 138351
 386/bin/toppm - 775 sys sys 1130594792 165173
 386/bin/toppm - 775 sys sys 1130594792 165173
 386/bin/touch - 775 sys sys 1130594792 63795
 386/bin/touch - 775 sys sys 1130594792 63795
-386/bin/tprof - 775 sys sys 1130594793 290212
+386/bin/tprof - 775 sys sys 1131296677 297344
 386/bin/tr - 775 sys sys 1130594793 61883
 386/bin/tr - 775 sys sys 1130594793 61883
 386/bin/trace - 775 sys sys 1131109834 180855
 386/bin/trace - 775 sys sys 1131109834 180855
 386/bin/troff - 775 sys sys 1127360609 357940
 386/bin/troff - 775 sys sys 1127360609 357940
@@ -521,8 +521,8 @@
 386/include/ape/ureg.h - 664 sys sys 944946041 812
 386/include/ape/ureg.h - 664 sys sys 944946041 812
 386/include/u.h - 664 sys sys 1115924095 1481
 386/include/u.h - 664 sys sys 1115924095 1481
 386/include/ureg.h - 664 sys sys 944946012 523
 386/include/ureg.h - 664 sys sys 944946012 523
-386/init - 775 sys sys 1130594818 101212
-386/ld.com - 775 sys sys 1109598589 72076
+386/init - 775 sys sys 1131317332 101212
+386/ld.com - 775 sys sys 1131317344 72524
 386/lib - 20000000775 sys sys 1016826328 0
 386/lib - 20000000775 sys sys 1016826328 0
 386/lib/ape - 20000000775 sys sys 944969312 0
 386/lib/ape - 20000000775 sys sys 944969312 0
 386/lib/ape/lib9.a - 664 sys sys 1038237538 6378
 386/lib/ape/lib9.a - 664 sys sys 1038237538 6378
@@ -553,7 +553,7 @@
 386/lib/libhttpd.a - 664 sys sys 1127790504 99596
 386/lib/libhttpd.a - 664 sys sys 1127790504 99596
 386/lib/libip.a - 664 sys sys 1116126324 35602
 386/lib/libip.a - 664 sys sys 1116126324 35602
 386/lib/libl.a - 664 sys sys 1115950154 5384
 386/lib/libl.a - 664 sys sys 1115950154 5384
-386/lib/libmach.a - 664 sys sys 1120619355 755696
+386/lib/libmach.a - 664 sys sys 1131296679 782950
 386/lib/libmemdraw.a - 664 sys sys 1120792317 284130
 386/lib/libmemdraw.a - 664 sys sys 1120792317 284130
 386/lib/libmemlayer.a - 664 sys sys 1115950157 47360
 386/lib/libmemlayer.a - 664 sys sys 1115950157 47360
 386/lib/libmp.a - 664 sys sys 1127360619 79944
 386/lib/libmp.a - 664 sys sys 1127360619 79944
@@ -566,10 +566,10 @@
 386/lib/libsunrpc.a - 664 sys sys 1115950160 355994
 386/lib/libsunrpc.a - 664 sys sys 1115950160 355994
 386/lib/libthread.a - 664 sys sys 1127405452 72374
 386/lib/libthread.a - 664 sys sys 1127405452 72374
 386/lib/libventi.a - 664 sys sys 1124766772 97708
 386/lib/libventi.a - 664 sys sys 1124766772 97708
-386/mbr - 775 sys sys 1022125974 407
+386/mbr - 775 sys sys 1131317338 407
 386/mkfile - 664 sys sys 948141303 46
 386/mkfile - 664 sys sys 948141303 46
-386/pbs - 775 sys sys 1022125973 494
-386/pbslba - 775 sys sys 1022125974 507
+386/pbs - 775 sys sys 1131317339 494
+386/pbslba - 775 sys sys 1131317342 507
 68000 - 20000000775 sys sys 947991045 0
 68000 - 20000000775 sys sys 947991045 0
 68000/bin - 20000000775 sys sys 985559408 0
 68000/bin - 20000000775 sys sys 985559408 0
 68000/bin/bitsy - 20000000775 sys sys 985559408 0
 68000/bin/bitsy - 20000000775 sys sys 985559408 0
@@ -5943,7 +5943,7 @@ sys/games/sudoku - 20000000775 sys sys 1117225532 0
 sys/include - 20000000775 sys sys 1016902416 0
 sys/include - 20000000775 sys sys 1016902416 0
 sys/include/9p.h - 664 sys sys 1130649668 4420
 sys/include/9p.h - 664 sys sys 1130649668 4420
 sys/include/String.h - 664 sys sys 1091904425 1319
 sys/include/String.h - 664 sys sys 1091904425 1319
-sys/include/a.out.h - 664 sys sys 1114218489 1291
+sys/include/a.out.h - 664 sys sys 1131293220 1407
 sys/include/ape - 20000000775 sys sys 1014927784 0
 sys/include/ape - 20000000775 sys sys 1014927784 0
 sys/include/ape/Plan9libnet.h - 664 sys sys 944948760 487
 sys/include/ape/Plan9libnet.h - 664 sys sys 944948760 487
 sys/include/ape/ar.h - 664 sys sys 944948759 354
 sys/include/ape/ar.h - 664 sys sys 944948759 354
@@ -6030,7 +6030,7 @@ sys/include/ip.h - 664 sys sys 1103554773 2989
 sys/include/keyboard.h - 664 sys sys 1079577798 815
 sys/include/keyboard.h - 664 sys sys 1079577798 815
 sys/include/libc.h - 664 sys sys 1115925565 19623
 sys/include/libc.h - 664 sys sys 1115925565 19623
 sys/include/libsec.h - 664 sys sys 1124709121 9345
 sys/include/libsec.h - 664 sys sys 1124709121 9345
-sys/include/mach.h - 664 sys sys 1119476886 8368
+sys/include/mach.h - 664 sys sys 1131289126 8586
 sys/include/memdraw.h - 664 sys sys 1091904419 5645
 sys/include/memdraw.h - 664 sys sys 1091904419 5645
 sys/include/memlayer.h - 664 sys sys 1051031022 1851
 sys/include/memlayer.h - 664 sys sys 1051031022 1851
 sys/include/mouse.h - 664 sys sys 1035232010 1003
 sys/include/mouse.h - 664 sys sys 1035232010 1003
@@ -6059,7 +6059,7 @@ sys/lib/acid/alpha - 664 sys sys 944955985 4849
 sys/lib/acid/arm - 664 sys sys 984696197 1842
 sys/lib/acid/arm - 664 sys sys 984696197 1842
 sys/lib/acid/coverage - 664 sys sys 944955985 1746
 sys/lib/acid/coverage - 664 sys sys 944955985 1746
 sys/lib/acid/kernel - 664 sys sys 1126699644 6303
 sys/lib/acid/kernel - 664 sys sys 1126699644 6303
-sys/lib/acid/leak - 664 sys sys 1110989276 2185
+sys/lib/acid/leak - 664 sys sys 1131289472 2363
 sys/lib/acid/mips - 664 sys sys 944955985 5472
 sys/lib/acid/mips - 664 sys sys 944955985 5472
 sys/lib/acid/network - 664 sys sys 1020313817 2499
 sys/lib/acid/network - 664 sys sys 1020313817 2499
 sys/lib/acid/pool - 664 sys sys 1063858105 4898
 sys/lib/acid/pool - 664 sys sys 1063858105 4898
@@ -7355,7 +7355,7 @@ sys/man/1/src - 664 sys sys 954266293 1138
 sys/man/1/ssh - 664 sys sys 1048643947 6622
 sys/man/1/ssh - 664 sys sys 1048643947 6622
 sys/man/1/stop - 664 sys sys 944959673 658
 sys/man/1/stop - 664 sys sys 944959673 658
 sys/man/1/strings - 664 sys sys 944959675 774
 sys/man/1/strings - 664 sys sys 944959675 774
-sys/man/1/strip - 664 sys sys 958580250 448
+sys/man/1/strip - 664 sys sys 1131293239 523
 sys/man/1/sum - 664 sys sys 984772442 1390
 sys/man/1/sum - 664 sys sys 984772442 1390
 sys/man/1/syscall - 664 sys sys 1016466457 1439
 sys/man/1/syscall - 664 sys sys 1016466457 1439
 sys/man/1/tail - 664 sys sys 1113743327 1413
 sys/man/1/tail - 664 sys sys 1113743327 1413
@@ -7567,7 +7567,7 @@ sys/man/3/ssl - 664 sys sys 1018386776 3413
 sys/man/3/tls - 664 sys sys 1045501496 7018
 sys/man/3/tls - 664 sys sys 1045501496 7018
 sys/man/3/uart - 664 sys sys 1102093395 1710
 sys/man/3/uart - 664 sys sys 1102093395 1710
 sys/man/3/usb - 664 sys sys 1126971427 6960
 sys/man/3/usb - 664 sys sys 1126971427 6960
-sys/man/3/vga - 664 sys sys 1020356225 4827
+sys/man/3/vga - 664 sys sys 1131301005 4957
 sys/man/4 - 20000000775 sys sys 1018581459 0
 sys/man/4 - 20000000775 sys sys 1018581459 0
 sys/man/4/0intro - 664 sys sys 944959699 472
 sys/man/4/0intro - 664 sys sys 944959699 472
 sys/man/4/INDEX - 664 sys sys 1104811679 985
 sys/man/4/INDEX - 664 sys sys 1104811679 985
@@ -7581,7 +7581,7 @@ sys/man/4/dossrv - 664 sys sys 1015024813 4176
 sys/man/4/execnet - 664 sys sys 1019866708 1069
 sys/man/4/execnet - 664 sys sys 1019866708 1069
 sys/man/4/exportfs - 664 sys sys 1115314261 4653
 sys/man/4/exportfs - 664 sys sys 1115314261 4653
 sys/man/4/ext2srv - 664 sys sys 1055692986 2409
 sys/man/4/ext2srv - 664 sys sys 1055692986 2409
-sys/man/4/factotum - 664 sys sys 1128483118 14709
+sys/man/4/factotum - 664 sys sys 1131294573 14841
 sys/man/4/fossil - 664 sys sys 1112368411 9546
 sys/man/4/fossil - 664 sys sys 1112368411 9546
 sys/man/4/fs - 664 sys sys 1019058716 3387
 sys/man/4/fs - 664 sys sys 1019058716 3387
 sys/man/4/ftpfs - 664 sys sys 1112563349 4410
 sys/man/4/ftpfs - 664 sys sys 1112563349 4410
@@ -7708,7 +7708,7 @@ sys/man/8/nfsserver - 664 sys sys 1128483119 3397
 sys/man/8/pcmcia - 664 sys sys 944959679 408
 sys/man/8/pcmcia - 664 sys sys 944959679 408
 sys/man/8/pem - 664 sys sys 1060263669 1189
 sys/man/8/pem - 664 sys sys 1060263669 1189
 sys/man/8/ping - 664 sys sys 1084473185 3436
 sys/man/8/ping - 664 sys sys 1084473185 3436
-sys/man/8/plan9.ini - 664 sys sys 1117814755 21579
+sys/man/8/plan9.ini - 664 sys sys 1131294569 22077
 sys/man/8/pop3 - 664 sys sys 1063854676 2720
 sys/man/8/pop3 - 664 sys sys 1063854676 2720
 sys/man/8/ppp - 664 sys sys 1125530075 4414
 sys/man/8/ppp - 664 sys sys 1125530075 4414
 sys/man/8/prep - 664 sys sys 1079705872 13820
 sys/man/8/prep - 664 sys sys 1079705872 13820
@@ -7724,7 +7724,7 @@ sys/man/8/send - 664 sys sys 1045501634 2168
 sys/man/8/smtp - 664 sys sys 1091126310 4724
 sys/man/8/smtp - 664 sys sys 1091126310 4724
 sys/man/8/snoopy - 664 sys sys 1128179510 4054
 sys/man/8/snoopy - 664 sys sys 1128179510 4054
 sys/man/8/stats - 664 sys sys 1067722908 4291
 sys/man/8/stats - 664 sys sys 1067722908 4291
-sys/man/8/statusbar - 664 sys sys 1131209276 1199
+sys/man/8/statusbar - 664 sys sys 1131317865 1251
 sys/man/8/stub - 664 sys sys 1044830500 943
 sys/man/8/stub - 664 sys sys 1044830500 943
 sys/man/8/swap - 664 sys sys 944959679 880
 sys/man/8/swap - 664 sys sys 944959679 880
 sys/man/8/timesync - 664 sys sys 1107606876 1717
 sys/man/8/timesync - 664 sys sys 1107606876 1717
@@ -7734,7 +7734,7 @@ sys/man/8/udpecho - 664 sys sys 954305553 303
 sys/man/8/update - 664 sys sys 961259288 2336
 sys/man/8/update - 664 sys sys 961259288 2336
 sys/man/8/venti - 664 sys sys 1069101926 5422
 sys/man/8/venti - 664 sys sys 1069101926 5422
 sys/man/8/ventiaux - 664 sys sys 1063855987 10487
 sys/man/8/ventiaux - 664 sys sys 1063855987 10487
-sys/man/8/vga - 664 sys sys 1114454069 3936
+sys/man/8/vga - 664 sys sys 1131301001 3864
 sys/man/fonts - 664 sys sys 944959700 218
 sys/man/fonts - 664 sys sys 944959700 218
 sys/man/index.html - 664 sys sys 1019918444 1859
 sys/man/index.html - 664 sys sys 1019918444 1859
 sys/man/mkfile - 664 sys sys 1018974173 2264
 sys/man/mkfile - 664 sys sys 1018974173 2264
@@ -7748,7 +7748,7 @@ sys/man/vol1.ps.gz - 664 sys sys 1020374752 2174519
 sys/src - 20000000775 sys sys 1016902537 0
 sys/src - 20000000775 sys sys 1016902537 0
 sys/src/9 - 20000000775 sys sys 1017795023 0
 sys/src/9 - 20000000775 sys sys 1017795023 0
 sys/src/9/alphapc - 20000000775 sys sys 1018721238 0
 sys/src/9/alphapc - 20000000775 sys sys 1018721238 0
-sys/src/9/alphapc/apc - 664 sys sys 1084331942 629
+sys/src/9/alphapc/apc - 664 sys sys 1131289706 630
 sys/src/9/alphapc/apccpu - 664 sys sys 1084331942 531
 sys/src/9/alphapc/apccpu - 664 sys sys 1084331942 531
 sys/src/9/alphapc/arch164.c - 664 sys sys 1015012783 6100
 sys/src/9/alphapc/arch164.c - 664 sys sys 1015012783 6100
 sys/src/9/alphapc/audio.h - 664 sys sys 1015012783 349
 sys/src/9/alphapc/audio.h - 664 sys sys 1015012783 349
@@ -7756,30 +7756,30 @@ sys/src/9/alphapc/axp.h - 664 sys sys 1015012783 1090
 sys/src/9/alphapc/cga.c - 664 sys sys 1015012783 1814
 sys/src/9/alphapc/cga.c - 664 sys sys 1015012783 1814
 sys/src/9/alphapc/clock.c - 664 sys sys 1032052963 1472
 sys/src/9/alphapc/clock.c - 664 sys sys 1032052963 1472
 sys/src/9/alphapc/cycintr.c - 664 sys sys 1018721238 230
 sys/src/9/alphapc/cycintr.c - 664 sys sys 1018721238 230
-sys/src/9/alphapc/dat.h - 664 sys sys 1127215703 5238
+sys/src/9/alphapc/dat.h - 664 sys sys 1131289707 5196
 sys/src/9/alphapc/devarch.c - 664 sys sys 1039753422 9760
 sys/src/9/alphapc/devarch.c - 664 sys sys 1039753422 9760
-sys/src/9/alphapc/devvga.c - 664 sys sys 1015012784 7513
+sys/src/9/alphapc/devvga.c - 664 sys sys 1131289707 7420
 sys/src/9/alphapc/dma.c - 664 sys sys 1015012784 6112
 sys/src/9/alphapc/dma.c - 664 sys sys 1015012784 6112
 sys/src/9/alphapc/etherif.h - 664 sys sys 1045063621 1025
 sys/src/9/alphapc/etherif.h - 664 sys sys 1045063621 1025
 sys/src/9/alphapc/faultalpha.c - 664 sys sys 1015012784 1257
 sys/src/9/alphapc/faultalpha.c - 664 sys sys 1015012784 1257
 sys/src/9/alphapc/fdc37c93x.c - 664 sys sys 1015012785 1110
 sys/src/9/alphapc/fdc37c93x.c - 664 sys sys 1015012785 1110
 sys/src/9/alphapc/floppy.h - 664 sys sys 1015012785 3783
 sys/src/9/alphapc/floppy.h - 664 sys sys 1015012785 3783
-sys/src/9/alphapc/fns.h - 664 sys sys 1111851541 3572
+sys/src/9/alphapc/fns.h - 664 sys sys 1131289707 3613
 sys/src/9/alphapc/fptrap.c - 664 sys sys 1015012785 707
 sys/src/9/alphapc/fptrap.c - 664 sys sys 1015012785 707
 sys/src/9/alphapc/i8259.c - 664 sys sys 1015012785 3409
 sys/src/9/alphapc/i8259.c - 664 sys sys 1015012785 3409
 sys/src/9/alphapc/initcode - 664 sys sys 1039753419 779
 sys/src/9/alphapc/initcode - 664 sys sys 1039753419 779
 sys/src/9/alphapc/io.h - 664 sys sys 1087657423 4540
 sys/src/9/alphapc/io.h - 664 sys sys 1087657423 4540
 sys/src/9/alphapc/kbd.c - 664 sys sys 1015012785 8676
 sys/src/9/alphapc/kbd.c - 664 sys sys 1015012785 8676
 sys/src/9/alphapc/l.s - 664 sys sys 1067722580 9124
 sys/src/9/alphapc/l.s - 664 sys sys 1067722580 9124
-sys/src/9/alphapc/main.c - 664 sys sys 1126586256 13624
+sys/src/9/alphapc/main.c - 664 sys sys 1131289707 13672
 sys/src/9/alphapc/mem.h - 664 sys sys 1077408326 3131
 sys/src/9/alphapc/mem.h - 664 sys sys 1077408326 3131
 sys/src/9/alphapc/memmove.s - 664 sys sys 1015012786 2936
 sys/src/9/alphapc/memmove.s - 664 sys sys 1015012786 2936
 sys/src/9/alphapc/memset.s - 664 sys sys 1015012786 844
 sys/src/9/alphapc/memset.s - 664 sys sys 1015012786 844
 sys/src/9/alphapc/mkfile - 664 sys sys 1109218102 1682
 sys/src/9/alphapc/mkfile - 664 sys sys 1109218102 1682
-sys/src/9/alphapc/mmu.c - 664 sys sys 1123438209 4905
+sys/src/9/alphapc/mmu.c - 664 sys sys 1131289708 4945
 sys/src/9/alphapc/pci.c - 664 sys sys 1039753420 7868
 sys/src/9/alphapc/pci.c - 664 sys sys 1039753420 7868
-sys/src/9/alphapc/screen.h - 664 sys sys 1060267151 3584
-sys/src/9/alphapc/sd53c8xx.c - 664 sys sys 1015012787 51009
+sys/src/9/alphapc/screen.h - 664 sys sys 1131289708 3818
+sys/src/9/alphapc/sd53c8xx.c - 664 sys sys 1131289709 50963
 sys/src/9/alphapc/sio.c - 664 sys sys 1015012787 293
 sys/src/9/alphapc/sio.c - 664 sys sys 1015012787 293
 sys/src/9/alphapc/trap.c - 664 sys sys 1105030177 18099
 sys/src/9/alphapc/trap.c - 664 sys sys 1105030177 18099
 sys/src/9/bitsy - 20000000775 sys sys 1018721429 0
 sys/src/9/bitsy - 20000000775 sys sys 1018721429 0
@@ -7787,12 +7787,12 @@ sys/src/9/bitsy/Booting101 - 664 sys sys 1054798506 8841
 sys/src/9/bitsy/bitsy - 664 sys sys 1067722592 424
 sys/src/9/bitsy/bitsy - 664 sys sys 1067722592 424
 sys/src/9/bitsy/bitsyreset.s - 664 sys sys 1017695510 2352
 sys/src/9/bitsy/bitsyreset.s - 664 sys sys 1017695510 2352
 sys/src/9/bitsy/clock.c - 664 sys sys 1037028998 4835
 sys/src/9/bitsy/clock.c - 664 sys sys 1037028998 4835
-sys/src/9/bitsy/dat.h - 664 sys sys 1099805278 5857
+sys/src/9/bitsy/dat.h - 664 sys sys 1131289775 5829
 sys/src/9/bitsy/defont.c - 664 sys sys 1017695511 21570
 sys/src/9/bitsy/defont.c - 664 sys sys 1017695511 21570
 sys/src/9/bitsy/devether.c - 664 sys sys 1116097769 10675
 sys/src/9/bitsy/devether.c - 664 sys sys 1116097769 10675
 sys/src/9/bitsy/devflash.c - 664 sys sys 1018386999 16832
 sys/src/9/bitsy/devflash.c - 664 sys sys 1018386999 16832
 sys/src/9/bitsy/devpcmcia.c - 664 sys sys 1099801570 12977
 sys/src/9/bitsy/devpcmcia.c - 664 sys sys 1099801570 12977
-sys/src/9/bitsy/devpenmouse.c - 664 sys sys 1067722592 9296
+sys/src/9/bitsy/devpenmouse.c - 664 sys sys 1131289775 9589
 sys/src/9/bitsy/devuda1341.c - 664 sys sys 1071245420 30346
 sys/src/9/bitsy/devuda1341.c - 664 sys sys 1071245420 30346
 sys/src/9/bitsy/devµc.c - 664 sys sys 1068393562 8125
 sys/src/9/bitsy/devµc.c - 664 sys sys 1068393562 8125
 sys/src/9/bitsy/etherif.h - 664 sys sys 1045501788 913
 sys/src/9/bitsy/etherif.h - 664 sys sys 1045501788 913
@@ -7807,10 +7807,10 @@ sys/src/9/bitsy/gamma.h - 664 sys sys 1017695514 540718
 sys/src/9/bitsy/init9.s - 664 sys sys 1043922398 183
 sys/src/9/bitsy/init9.s - 664 sys sys 1043922398 183
 sys/src/9/bitsy/io.h - 664 sys sys 1064584624 8040
 sys/src/9/bitsy/io.h - 664 sys sys 1064584624 8040
 sys/src/9/bitsy/l.s - 664 sys sys 1055700934 18211
 sys/src/9/bitsy/l.s - 664 sys sys 1055700934 18211
-sys/src/9/bitsy/main.c - 664 sys sys 1126586256 9081
+sys/src/9/bitsy/main.c - 664 sys sys 1131289775 8816
 sys/src/9/bitsy/map - 664 sys sys 1017695515 236
 sys/src/9/bitsy/map - 664 sys sys 1017695515 236
 sys/src/9/bitsy/mem.h - 664 sys sys 1055700932 8049
 sys/src/9/bitsy/mem.h - 664 sys sys 1055700932 8049
-sys/src/9/bitsy/mkfile - 664 sys sys 1072705544 2452
+sys/src/9/bitsy/mkfile - 664 sys sys 1131289775 2459
 sys/src/9/bitsy/mmu.c - 664 sys sys 1123438209 11261
 sys/src/9/bitsy/mmu.c - 664 sys sys 1123438209 11261
 sys/src/9/bitsy/mouse.c - 664 sys sys 1017695516 962
 sys/src/9/bitsy/mouse.c - 664 sys sys 1017695516 962
 sys/src/9/bitsy/paqfiles - 20000000775 sys sys 1020011250 0
 sys/src/9/bitsy/paqfiles - 20000000775 sys sys 1020011250 0
@@ -7827,7 +7827,7 @@ sys/src/9/bitsy/sa1110dma.h - 664 sys sys 1017695520 381
 sys/src/9/bitsy/screen.c - 664 sys sys 1053340962 10145
 sys/src/9/bitsy/screen.c - 664 sys sys 1053340962 10145
 sys/src/9/bitsy/screen.h - 664 sys sys 1017695520 260
 sys/src/9/bitsy/screen.h - 664 sys sys 1017695520 260
 sys/src/9/bitsy/sd.h - 664 sys sys 1037029038 0
 sys/src/9/bitsy/sd.h - 664 sys sys 1037029038 0
-sys/src/9/bitsy/sdata.c - 664 sys sys 1055700868 44660
+sys/src/9/bitsy/sdata.c - 664 sys sys 1131289776 44404
 sys/src/9/bitsy/tar.c - 664 sys sys 1017695521 1375
 sys/src/9/bitsy/tar.c - 664 sys sys 1017695521 1375
 sys/src/9/bitsy/trap.c - 664 sys sys 1105030166 19484
 sys/src/9/bitsy/trap.c - 664 sys sys 1105030166 19484
 sys/src/9/bitsy/uartsa1110.c - 664 sys sys 1037029045 8530
 sys/src/9/bitsy/uartsa1110.c - 664 sys sys 1037029045 8530
@@ -7837,7 +7837,7 @@ sys/src/9/boot - 20000000775 sys sys 1018556557 0
 sys/src/9/boot/aux.c - 664 sys sys 1063857702 2579
 sys/src/9/boot/aux.c - 664 sys sys 1063857702 2579
 sys/src/9/boot/boot.c - 664 sys sys 1130982159 6067
 sys/src/9/boot/boot.c - 664 sys sys 1130982159 6067
 sys/src/9/boot/boot.h - 664 sys sys 1063857659 1785
 sys/src/9/boot/boot.h - 664 sys sys 1063857659 1785
-sys/src/9/boot/bootauth.c - 664 sys sys 1039763726 1097
+sys/src/9/boot/bootauth.c - 664 sys sys 1131289783 1160
 sys/src/9/boot/bootcache.c - 664 sys sys 1063857645 1579
 sys/src/9/boot/bootcache.c - 664 sys sys 1063857645 1579
 sys/src/9/boot/bootip.c - 664 sys sys 1072972133 3418
 sys/src/9/boot/bootip.c - 664 sys sys 1072972133 3418
 sys/src/9/boot/bootmkfile - 664 sys sys 1091732792 404
 sys/src/9/boot/bootmkfile - 664 sys sys 1091732792 404
@@ -7887,7 +7887,7 @@ sys/src/9/mkfile - 664 sys sys 1063857477 205
 sys/src/9/mtx - 20000000775 sys sys 1018721288 0
 sys/src/9/mtx - 20000000775 sys sys 1018721288 0
 sys/src/9/mtx/clock.c - 664 sys sys 1032053278 1293
 sys/src/9/mtx/clock.c - 664 sys sys 1032053278 1293
 sys/src/9/mtx/cycintr.c - 664 sys sys 1018721285 230
 sys/src/9/mtx/cycintr.c - 664 sys sys 1018721285 230
-sys/src/9/mtx/dat.h - 664 sys sys 1127215703 3897
+sys/src/9/mtx/dat.h - 664 sys sys 1131289814 3843
 sys/src/9/mtx/devarch.c - 664 sys sys 1018721285 6793
 sys/src/9/mtx/devarch.c - 664 sys sys 1018721285 6793
 sys/src/9/mtx/devether.c - 664 sys sys 1116097786 9281
 sys/src/9/mtx/devether.c - 664 sys sys 1116097786 9281
 sys/src/9/mtx/devrtc.c - 664 sys sys 1018721285 6772
 sys/src/9/mtx/devrtc.c - 664 sys sys 1018721285 6772
@@ -7900,7 +7900,7 @@ sys/src/9/mtx/initcode - 664 sys sys 1039753442 444
 sys/src/9/mtx/io.h - 664 sys sys 1087657404 4817
 sys/src/9/mtx/io.h - 664 sys sys 1087657404 4817
 sys/src/9/mtx/kbd.c - 664 sys sys 1018721286 8358
 sys/src/9/mtx/kbd.c - 664 sys sys 1018721286 8358
 sys/src/9/mtx/l.s - 664 sys sys 1067722599 10730
 sys/src/9/mtx/l.s - 664 sys sys 1067722599 10730
-sys/src/9/mtx/main.c - 664 sys sys 1126586256 8342
+sys/src/9/mtx/main.c - 664 sys sys 1131289814 8307
 sys/src/9/mtx/mem.h - 664 sys sys 1026848200 5959
 sys/src/9/mtx/mem.h - 664 sys sys 1026848200 5959
 sys/src/9/mtx/mkfile - 664 sys sys 1072972534 1520
 sys/src/9/mtx/mkfile - 664 sys sys 1072972534 1520
 sys/src/9/mtx/mmu.c - 664 sys sys 1123438210 4421
 sys/src/9/mtx/mmu.c - 664 sys sys 1123438210 4421
@@ -7913,83 +7913,83 @@ sys/src/9/mtx/trap.c - 664 sys sys 1105030157 15882
 sys/src/9/mtx/uarti8250.c - 664 sys sys 1018721288 11590
 sys/src/9/mtx/uarti8250.c - 664 sys sys 1018721288 11590
 sys/src/9/pc - 20000000775 sys sys 1018721225 0
 sys/src/9/pc - 20000000775 sys sys 1018721225 0
 sys/src/9/pc/apbootstrap.h - 664 sys sys 1018553448 928
 sys/src/9/pc/apbootstrap.h - 664 sys sys 1018553448 928
-sys/src/9/pc/apbootstrap.s - 664 sys sys 1015014512 3037
-sys/src/9/pc/apic.c - 664 sys sys 1084475126 8643
-sys/src/9/pc/apm.c - 664 sys sys 1015014513 3697
+sys/src/9/pc/apbootstrap.s - 664 sys sys 1131293655 3037
+sys/src/9/pc/apic.c - 664 sys sys 1131290206 8748
+sys/src/9/pc/apm.c - 664 sys sys 1131290210 3723
 sys/src/9/pc/apmjump.s - 664 sys sys 1032058947 1527
 sys/src/9/pc/apmjump.s - 664 sys sys 1032058947 1527
-sys/src/9/pc/archmp.c - 664 sys sys 1084475127 2311
+sys/src/9/pc/archmp.c - 664 sys sys 1131290214 2357
 sys/src/9/pc/audio.h - 664 sys sys 1015014513 343
 sys/src/9/pc/audio.h - 664 sys sys 1015014513 343
 sys/src/9/pc/cga.c - 664 sys sys 1015014513 1843
 sys/src/9/pc/cga.c - 664 sys sys 1015014513 1843
-sys/src/9/pc/dat.h - 664 sys sys 1091904418 6281
-sys/src/9/pc/devarch.c - 664 sys sys 1115566123 18554
-sys/src/9/pc/devether.c - 664 sys sys 1116173410 10327
+sys/src/9/pc/dat.h - 664 sys sys 1131290217 6462
+sys/src/9/pc/devarch.c - 664 sys sys 1131290259 18594
+sys/src/9/pc/devether.c - 664 sys sys 1131290265 10315
 sys/src/9/pc/devfloppy.c - 664 sys sys 1055689885 20024
 sys/src/9/pc/devfloppy.c - 664 sys sys 1055689885 20024
 sys/src/9/pc/devi82365.c - 664 sys sys 1099761153 20505
 sys/src/9/pc/devi82365.c - 664 sys sys 1099761153 20505
 sys/src/9/pc/devlm78.c - 664 sys sys 1128255048 6291
 sys/src/9/pc/devlm78.c - 664 sys sys 1128255048 6291
-sys/src/9/pc/devlml.c - 664 sys sys 1026847636 7486
+sys/src/9/pc/devlml.c - 664 sys sys 1131290276 7505
 sys/src/9/pc/devlml.h - 664 sys sys 1026847636 2948
 sys/src/9/pc/devlml.h - 664 sys sys 1026847636 2948
 sys/src/9/pc/devlpt.c - 664 sys sys 1015014514 4420
 sys/src/9/pc/devlpt.c - 664 sys sys 1015014514 4420
-sys/src/9/pc/devpccard.c - 664 sys sys 1107531947 40194
+sys/src/9/pc/devpccard.c - 664 sys sys 1131290281 40203
 sys/src/9/pc/devrtc.c - 664 sys sys 1015014515 7167
 sys/src/9/pc/devrtc.c - 664 sys sys 1015014515 7167
-sys/src/9/pc/devtv.c - 664 sys sys 1091734484 45725
+sys/src/9/pc/devtv.c - 664 sys sys 1131290299 45676
 sys/src/9/pc/devusb.c - 664 sys sys 1105193103 18364
 sys/src/9/pc/devusb.c - 664 sys sys 1105193103 18364
-sys/src/9/pc/devvga.c - 664 sys sys 1063857412 8714
-sys/src/9/pc/dma.c - 664 sys sys 1015014515 4736
+sys/src/9/pc/devvga.c - 664 sys sys 1131290315 9332
+sys/src/9/pc/dma.c - 664 sys sys 1131290319 4715
 sys/src/9/pc/ether2000.c - 664 sys sys 1089299187 4819
 sys/src/9/pc/ether2000.c - 664 sys sys 1089299187 4819
 sys/src/9/pc/ether2114x.c - 664 sys sys 1081706476 41545
 sys/src/9/pc/ether2114x.c - 664 sys sys 1081706476 41545
 sys/src/9/pc/ether589.c - 664 sys sys 1015014516 4644
 sys/src/9/pc/ether589.c - 664 sys sys 1015014516 4644
-sys/src/9/pc/ether79c970.c - 664 sys sys 1071245466 14094
+sys/src/9/pc/ether79c970.c - 664 sys sys 1131290338 13953
 sys/src/9/pc/ether8003.c - 664 sys sys 1015014516 6665
 sys/src/9/pc/ether8003.c - 664 sys sys 1015014516 6665
-sys/src/9/pc/ether8139.c - 664 sys sys 1121393473 18385
-sys/src/9/pc/ether8169.c - 664 sys sys 1121391723 22704
-sys/src/9/pc/ether82543gc.c - 664 sys sys 1055689887 32296
-sys/src/9/pc/ether82557.c - 664 sys sys 1117550886 30121
-sys/src/9/pc/ether83815.c - 664 sys sys 1115744557 23481
-sys/src/9/pc/ether8390.c - 664 sys sys 1112382834 17701
+sys/src/9/pc/ether8139.c - 664 sys sys 1131290376 18400
+sys/src/9/pc/ether8169.c - 664 sys sys 1131290377 22723
+sys/src/9/pc/ether82543gc.c - 664 sys sys 1131290377 32294
+sys/src/9/pc/ether82557.c - 664 sys sys 1131290377 30107
+sys/src/9/pc/ether83815.c - 664 sys sys 1131287537 23542
+sys/src/9/pc/ether8390.c - 664 sys sys 1131290377 17702
 sys/src/9/pc/ether8390.h - 664 sys sys 1015014517 1511
 sys/src/9/pc/ether8390.h - 664 sys sys 1015014517 1511
-sys/src/9/pc/etherdp83820.c - 664 sys sys 1083469193 29134
+sys/src/9/pc/etherdp83820.c - 664 sys sys 1131290378 29128
 sys/src/9/pc/etherec2t.c - 664 sys sys 1086960044 4039
 sys/src/9/pc/etherec2t.c - 664 sys sys 1086960044 4039
-sys/src/9/pc/etherelnk3.c - 664 sys sys 1081706477 48724
-sys/src/9/pc/etherga620.c - 664 sys sys 1074785126 28754
+sys/src/9/pc/etherelnk3.c - 664 sys sys 1131290378 48733
+sys/src/9/pc/etherga620.c - 664 sys sys 1131290379 28748
 sys/src/9/pc/etherga620fw.h - 664 sys sys 1026847642 222295
 sys/src/9/pc/etherga620fw.h - 664 sys sys 1026847642 222295
 sys/src/9/pc/etherif.h - 664 sys sys 1088178711 961
 sys/src/9/pc/etherif.h - 664 sys sys 1088178711 961
-sys/src/9/pc/etherigbe.c - 664 sys sys 1127393123 44412
+sys/src/9/pc/etherigbe.c - 664 sys sys 1131290379 44431
 sys/src/9/pc/ethermii.c - 664 sys sys 1084331434 4612
 sys/src/9/pc/ethermii.c - 664 sys sys 1084331434 4612
 sys/src/9/pc/ethermii.h - 664 sys sys 1086873891 3258
 sys/src/9/pc/ethermii.h - 664 sys sys 1086873891 3258
 sys/src/9/pc/etherrhine.c - 664 sys sys 1081706478 13799
 sys/src/9/pc/etherrhine.c - 664 sys sys 1081706478 13799
 sys/src/9/pc/ethersink.c - 664 sys sys 1048644103 1076
 sys/src/9/pc/ethersink.c - 664 sys sys 1048644103 1076
 sys/src/9/pc/ethersmc.c - 664 sys sys 1071245461 15103
 sys/src/9/pc/ethersmc.c - 664 sys sys 1071245461 15103
-sys/src/9/pc/ethervt6102.c - 664 sys sys 1109202304 22569
-sys/src/9/pc/etherwavelan.c - 664 sys sys 1107448246 3723
+sys/src/9/pc/ethervt6102.c - 664 sys sys 1131290379 22572
+sys/src/9/pc/etherwavelan.c - 664 sys sys 1131290380 3747
 sys/src/9/pc/floppy.h - 664 sys sys 1055700609 3835
 sys/src/9/pc/floppy.h - 664 sys sys 1055700609 3835
-sys/src/9/pc/fns.h - 664 sys sys 1111851554 4198
+sys/src/9/pc/fns.h - 664 sys sys 1131290383 4461
 sys/src/9/pc/hcwAMC.h - 664 sys sys 1026860163 166004
 sys/src/9/pc/hcwAMC.h - 664 sys sys 1026860163 166004
 sys/src/9/pc/i8253.c - 664 sys sys 1096379063 6279
 sys/src/9/pc/i8253.c - 664 sys sys 1096379063 6279
-sys/src/9/pc/i8259.c - 664 sys sys 1015014519 4423
+sys/src/9/pc/i8259.c - 664 sys sys 1131290399 4586
 sys/src/9/pc/init9.c - 664 sys sys 1040002518 94
 sys/src/9/pc/init9.c - 664 sys sys 1040002518 94
 sys/src/9/pc/initcode.s - 664 sys sys 1015014519 282
 sys/src/9/pc/initcode.s - 664 sys sys 1015014519 282
 sys/src/9/pc/io.h - 664 sys sys 1099761152 8095
 sys/src/9/pc/io.h - 664 sys sys 1099761152 8095
 sys/src/9/pc/kbd.c - 664 sys sys 1130848300 12362
 sys/src/9/pc/kbd.c - 664 sys sys 1130848300 12362
-sys/src/9/pc/l.s - 664 sys sys 1115566067 23833
-sys/src/9/pc/main.c - 664 sys sys 1126586232 14691
-sys/src/9/pc/mem.h - 664 sys sys 1018553448 4573
-sys/src/9/pc/memory.c - 664 sys sys 1071245460 13028
-sys/src/9/pc/mkfile - 664 sys sys 1067810339 3219
-sys/src/9/pc/mmu.c - 664 sys sys 1125564128 10489
+sys/src/9/pc/l.s - 664 sys sys 1131290403 28347
+sys/src/9/pc/main.c - 664 sys sys 1131290418 15224
+sys/src/9/pc/mem.h - 664 sys sys 1131290422 5209
+sys/src/9/pc/memory.c - 664 sys sys 1131290429 18222
+sys/src/9/pc/mkfile - 664 sys sys 1131294850 3580
+sys/src/9/pc/mmu.c - 664 sys sys 1131326224 19739
 sys/src/9/pc/mouse.c - 664 sys sys 1098479254 7057
 sys/src/9/pc/mouse.c - 664 sys sys 1098479254 7057
-sys/src/9/pc/mp.c - 664 sys sys 1123637234 17024
-sys/src/9/pc/mp.h - 664 sys sys 1015014520 6575
+sys/src/9/pc/mp.c - 664 sys sys 1131326235 17157
+sys/src/9/pc/mp.h - 664 sys sys 1131290475 6638
 sys/src/9/pc/nv_dma.h - 664 sys sys 1081384508 12943
 sys/src/9/pc/nv_dma.h - 664 sys sys 1081384508 12943
-sys/src/9/pc/pc - 664 sys sys 1127411319 1408
-sys/src/9/pc/pcauth - 664 sys sys 1073851852 657
-sys/src/9/pc/pccd - 664 sys sys 1091458811 1408
-sys/src/9/pc/pccpu - 664 sys sys 1127411311 835
-sys/src/9/pc/pccpuf - 664 sys sys 1127411330 1467
-sys/src/9/pc/pcdisk - 664 sys sys 1073851851 1427
-sys/src/9/pc/pcf - 664 sys sys 1104430623 1485
+sys/src/9/pc/pc - 664 sys sys 1131290481 1427
+sys/src/9/pc/pcauth - 664 sys sys 1131290482 714
+sys/src/9/pc/pccd - 664 sys sys 1131290486 1418
+sys/src/9/pc/pccpu - 664 sys sys 1131290488 866
+sys/src/9/pc/pccpuf - 664 sys sys 1131299996 1486
+sys/src/9/pc/pcdisk - 664 sys sys 1131299995 1446
+sys/src/9/pc/pcf - 664 sys sys 1131299996 1504
 sys/src/9/pc/pcfl - 664 sys sys 1042004821 1563
 sys/src/9/pc/pcfl - 664 sys sys 1042004821 1563
-sys/src/9/pc/pcflop - 664 sys sys 1112361040 1454
-sys/src/9/pc/pci.c - 664 sys sys 1121260128 26418
+sys/src/9/pc/pcflop - 664 sys sys 1131299996 1473
+sys/src/9/pc/pci.c - 664 sys sys 1131290505 26817
 sys/src/9/pc/pcmciamodem.c - 664 sys sys 1099761153 1586
 sys/src/9/pc/pcmciamodem.c - 664 sys sys 1099761153 1586
 sys/src/9/pc/pcmkfile - 664 sys sys 1109303822 101
 sys/src/9/pc/pcmkfile - 664 sys sys 1109303822 101
 sys/src/9/pc/piix4smbus.c - 664 sys sys 1091129037 5230
 sys/src/9/pc/piix4smbus.c - 664 sys sys 1091129037 5230
@@ -7997,46 +7997,47 @@ sys/src/9/pc/plan9l.s - 664 sys sys 1015014521 910
 sys/src/9/pc/psaux.c - 664 sys sys 1026847650 915
 sys/src/9/pc/psaux.c - 664 sys sys 1026847650 915
 sys/src/9/pc/ptclbsum386.s - 664 sys sys 1015014521 1493
 sys/src/9/pc/ptclbsum386.s - 664 sys sys 1015014521 1493
 sys/src/9/pc/random.c - 664 sys sys 1036812832 2021
 sys/src/9/pc/random.c - 664 sys sys 1036812832 2021
-sys/src/9/pc/reboot.h - 664 sys sys 1015014522 334
+sys/src/9/pc/realmode.c - 664 sys sys 1131294602 2658
 sys/src/9/pc/rebootcode.s - 664 sys sys 1015014522 988
 sys/src/9/pc/rebootcode.s - 664 sys sys 1015014522 988
-sys/src/9/pc/screen.c - 664 sys sys 1039753497 7266
-sys/src/9/pc/screen.h - 664 sys sys 1060267144 3797
-sys/src/9/pc/sd53c8xx.c - 664 sys sys 1112461125 52220
-sys/src/9/pc/sd53c8xx.i - 664 sys sys 1045063730 27355
-sys/src/9/pc/sd53c8xx.n - 664 sys sys 1032059019 12455
-sys/src/9/pc/sdata.c - 664 sys sys 1127404875 51702
-sys/src/9/pc/sdmylex.c - 664 sys sys 1071245460 27812
-sys/src/9/pc/sdscsi.c - 664 sys sys 1077033661 7487
-sys/src/9/pc/trap.c - 664 sys sys 1123438642 20550
+sys/src/9/pc/screen.c - 664 sys sys 1131290512 13460
+sys/src/9/pc/screen.h - 664 sys sys 1131290516 4156
+sys/src/9/pc/sd53c8xx.c - 664 sys sys 1131290539 55206
+sys/src/9/pc/sd53c8xx.n - 664 sys sys 1131290556 12657
+sys/src/9/pc/sdata.c - 664 sys sys 1131290578 52168
+sys/src/9/pc/sdmv50xx.c - 664 sys sys 1131290638 25780
+sys/src/9/pc/sdmylex.c - 664 sys sys 1131290583 27737
+sys/src/9/pc/sdscsi.c - 664 sys sys 1131293342 7133
+sys/src/9/pc/trap.c - 664 sys sys 1131306249 21180
 sys/src/9/pc/uarti8250.c - 664 sys sys 1102820421 13958
 sys/src/9/pc/uarti8250.c - 664 sys sys 1102820421 13958
 sys/src/9/pc/uartisa.c - 664 sys sys 1127126907 1777
 sys/src/9/pc/uartisa.c - 664 sys sys 1127126907 1777
 sys/src/9/pc/uartpci.c - 664 sys sys 1096379063 2891
 sys/src/9/pc/uartpci.c - 664 sys sys 1096379063 2891
 sys/src/9/pc/usb.h - 664 sys sys 1099760881 3650
 sys/src/9/pc/usb.h - 664 sys sys 1099760881 3650
 sys/src/9/pc/usbuhci.c - 664 sys sys 1099760881 30955
 sys/src/9/pc/usbuhci.c - 664 sys sys 1099760881 30955
-sys/src/9/pc/vga.c - 664 sys sys 1039753497 4963
-sys/src/9/pc/vga3dfx.c - 664 sys sys 1071247360 4867
-sys/src/9/pc/vgaark2000pv.c - 664 sys sys 1015014524 3416
-sys/src/9/pc/vgabt485.c - 664 sys sys 1015014525 5041
-sys/src/9/pc/vgaclgd542x.c - 664 sys sys 1015014525 5068
-sys/src/9/pc/vgaclgd546x.c - 664 sys sys 1071245447 4770
-sys/src/9/pc/vgact65545.c - 664 sys sys 1015014525 2243
-sys/src/9/pc/vgacyber938x.c - 664 sys sys 1015014526 4192
-sys/src/9/pc/vgaet4000.c - 664 sys sys 1015014526 5105
-sys/src/9/pc/vgahiqvideo.c - 664 sys sys 1048635701 5033
-sys/src/9/pc/vgai81x.c - 664 sys sys 1032052924 4905
-sys/src/9/pc/vgamach64xx.c - 664 sys sys 1071245447 29146
-sys/src/9/pc/vgamga2164w.c - 664 sys sys 1015014527 5654
-sys/src/9/pc/vgamga4xx.c - 664 sys sys 1015014527 11122
-sys/src/9/pc/vganeomagic.c - 664 sys sys 1104430511 11327
-sys/src/9/pc/vganvidia.c - 664 sys sys 1120909910 12617
-sys/src/9/pc/vgargb524.c - 664 sys sys 1015014527 4235
-sys/src/9/pc/vgas3.c - 664 sys sys 1090439162 12189
+sys/src/9/pc/vga.c - 664 sys sys 1131290595 5148
+sys/src/9/pc/vga3dfx.c - 664 sys sys 1131290600 3833
+sys/src/9/pc/vgaark2000pv.c - 664 sys sys 1131290600 3422
+sys/src/9/pc/vgabt485.c - 664 sys sys 1131290600 5057
+sys/src/9/pc/vgaclgd542x.c - 664 sys sys 1131290600 4550
+sys/src/9/pc/vgaclgd546x.c - 664 sys sys 1131290600 3716
+sys/src/9/pc/vgact65545.c - 664 sys sys 1131290600 2249
+sys/src/9/pc/vgacyber938x.c - 664 sys sys 1131290601 3707
+sys/src/9/pc/vgaet4000.c - 664 sys sys 1131290601 5111
+sys/src/9/pc/vgahiqvideo.c - 664 sys sys 1131290601 4098
+sys/src/9/pc/vgai81x.c - 664 sys sys 1131290601 4030
+sys/src/9/pc/vgamach64xx.c - 664 sys sys 1131290601 28257
+sys/src/9/pc/vgamga2164w.c - 664 sys sys 1131290602 4637
+sys/src/9/pc/vgamga4xx.c - 664 sys sys 1131290602 10201
+sys/src/9/pc/vganeomagic.c - 664 sys sys 1131290602 10143
+sys/src/9/pc/vganvidia.c - 664 sys sys 1131290602 11783
+sys/src/9/pc/vgargb524.c - 664 sys sys 1131290602 4251
+sys/src/9/pc/vgas3.c - 664 sys sys 1131290603 10994
 sys/src/9/pc/vgasavage.c - 664 sys sys 1064679984 16251
 sys/src/9/pc/vgasavage.c - 664 sys sys 1064679984 16251
-sys/src/9/pc/vgat2r4.c - 664 sys sys 1015014528 10355
-sys/src/9/pc/vgatvp3020.c - 664 sys sys 1015014528 4491
-sys/src/9/pc/vgatvp3026.c - 664 sys sys 1015014528 3940
-sys/src/9/pc/vgavmware.c - 664 sys sys 1063858321 6398
-sys/src/9/pc/vgax.c - 664 sys sys 1015014528 1655
+sys/src/9/pc/vgat2r4.c - 664 sys sys 1131290603 9351
+sys/src/9/pc/vgatvp3020.c - 664 sys sys 1131290603 4507
+sys/src/9/pc/vgatvp3026.c - 664 sys sys 1131290603 3956
+sys/src/9/pc/vgavesa.c - 664 sys sys 1131290603 2369
+sys/src/9/pc/vgavmware.c - 664 sys sys 1131290604 5840
+sys/src/9/pc/vgax.c - 664 sys sys 1131290604 1671
 sys/src/9/pc/wavelan.c - 664 sys sys 1127743243 27879
 sys/src/9/pc/wavelan.c - 664 sys sys 1127743243 27879
 sys/src/9/pc/wavelan.h - 664 sys sys 1107448246 6169
 sys/src/9/pc/wavelan.h - 664 sys sys 1107448246 6169
 sys/src/9/port - 20000000775 sys sys 1018469625 0
 sys/src/9/port - 20000000775 sys sys 1018469625 0
@@ -8045,15 +8046,15 @@ sys/src/9/port/alloc.c - 664 sys sys 1130964595 5674
 sys/src/9/port/allocb.c - 664 sys sys 1123676437 3340
 sys/src/9/port/allocb.c - 664 sys sys 1123676437 3340
 sys/src/9/port/auth.c - 664 sys sys 1123647282 2392
 sys/src/9/port/auth.c - 664 sys sys 1123647282 2392
 sys/src/9/port/cache.c - 664 sys sys 1126586168 9241
 sys/src/9/port/cache.c - 664 sys sys 1126586168 9241
-sys/src/9/port/chan.c - 664 sys sys 1129373741 33642
+sys/src/9/port/chan.c - 664 sys sys 1131298713 33663
 sys/src/9/port/cis.c - 664 sys sys 1099761153 9248
 sys/src/9/port/cis.c - 664 sys sys 1099761153 9248
 sys/src/9/port/debugalloc.c - 664 sys sys 1014931171 10402
 sys/src/9/port/debugalloc.c - 664 sys sys 1014931171 10402
-sys/src/9/port/dev.c - 664 sys sys 1126586172 8246
+sys/src/9/port/dev.c - 664 sys sys 1131289870 8219
 sys/src/9/port/devaudio.c - 664 sys sys 1067722761 21130
 sys/src/9/port/devaudio.c - 664 sys sys 1067722761 21130
 sys/src/9/port/devbridge.c - 664 sys sys 1055688301 24308
 sys/src/9/port/devbridge.c - 664 sys sys 1055688301 24308
 sys/src/9/port/devcap.c - 664 sys sys 1048644215 4113
 sys/src/9/port/devcap.c - 664 sys sys 1048644215 4113
 sys/src/9/port/devcons.c - 664 sys sys 1130759309 22495
 sys/src/9/port/devcons.c - 664 sys sys 1130759309 22495
-sys/src/9/port/devdraw.c - 664 sys sys 1091733670 41996
+sys/src/9/port/devdraw.c - 664 sys sys 1131289870 43537
 sys/src/9/port/devdup.c - 664 sys sys 1014931172 2332
 sys/src/9/port/devdup.c - 664 sys sys 1014931172 2332
 sys/src/9/port/devenv.c - 664 sys sys 1048644225 6992
 sys/src/9/port/devenv.c - 664 sys sys 1048644225 6992
 sys/src/9/port/devfs.c - 664 sys sys 1105799131 10783
 sys/src/9/port/devfs.c - 664 sys sys 1105799131 10783
@@ -8065,11 +8066,11 @@ sys/src/9/port/devmntstats.c - 664 sys sys 1014931173 4039
 sys/src/9/port/devmouse.c - 664 sys sys 1130848303 13517
 sys/src/9/port/devmouse.c - 664 sys sys 1130848303 13517
 sys/src/9/port/devpipe.c - 664 sys sys 1077055016 5825
 sys/src/9/port/devpipe.c - 664 sys sys 1077055016 5825
 sys/src/9/port/devpnp.c - 664 sys sys 1088560907 13624
 sys/src/9/port/devpnp.c - 664 sys sys 1088560907 13624
-sys/src/9/port/devproc.c - 664 sys sys 1126586197 28465
+sys/src/9/port/devproc.c - 664 sys sys 1131289878 28233
 sys/src/9/port/devroot.c - 664 sys sys 1067722764 4254
 sys/src/9/port/devroot.c - 664 sys sys 1067722764 4254
-sys/src/9/port/devsd.c - 664 sys sys 1123255503 28564
+sys/src/9/port/devsd.c - 664 sys sys 1131289885 30798
 sys/src/9/port/devsdp.c - 664 sys sys 1057323393 44800
 sys/src/9/port/devsdp.c - 664 sys sys 1057323393 44800
-sys/src/9/port/devsegment.c - 664 sys sys 1017679394 9600
+sys/src/9/port/devsegment.c - 664 sys sys 1131289891 9610
 sys/src/9/port/devsrv.c - 664 sys sys 1107232208 5418
 sys/src/9/port/devsrv.c - 664 sys sys 1107232208 5418
 sys/src/9/port/devssl.c - 664 sys sys 1131107944 26133
 sys/src/9/port/devssl.c - 664 sys sys 1131107944 26133
 sys/src/9/port/devtinyfs.c - 664 sys sys 1015278339 15347
 sys/src/9/port/devtinyfs.c - 664 sys sys 1015278339 15347
@@ -8079,13 +8080,13 @@ sys/src/9/port/devwd.c - 664 sys sys 1126582325 2342
 sys/src/9/port/edf.c - 664 sys sys 1099760881 12742
 sys/src/9/port/edf.c - 664 sys sys 1099760881 12742
 sys/src/9/port/edf.h - 664 sys sys 1084475128 1156
 sys/src/9/port/edf.h - 664 sys sys 1084475128 1156
 sys/src/9/port/error.h - 664 sys sys 1117055493 2637
 sys/src/9/port/error.h - 664 sys sys 1117055493 2637
-sys/src/9/port/fault.c - 664 sys sys 1126586199 7282
+sys/src/9/port/fault.c - 664 sys sys 1131289901 7271
 sys/src/9/port/initcode.c - 664 sys sys 1055688491 574
 sys/src/9/port/initcode.c - 664 sys sys 1055688491 574
 sys/src/9/port/latin1.c - 664 sys sys 1015278339 1418
 sys/src/9/port/latin1.c - 664 sys sys 1015278339 1418
 sys/src/9/port/latin1.h - 664 sys sys 1103633666 3563
 sys/src/9/port/latin1.h - 664 sys sys 1103633666 3563
-sys/src/9/port/lib.h - 664 sys sys 1126103560 5770
+sys/src/9/port/lib.h - 664 sys sys 1131289913 6040
 sys/src/9/port/log.c - 664 sys sys 1014931175 2860
 sys/src/9/port/log.c - 664 sys sys 1014931175 2860
-sys/src/9/port/master - 664 sys sys 1104430269 505
+sys/src/9/port/master - 664 sys sys 1131289934 510
 sys/src/9/port/master.local - 664 sys sys 1063856961 130
 sys/src/9/port/master.local - 664 sys sys 1063856961 130
 sys/src/9/port/mkbootrules - 775 sys sys 1055700518 923
 sys/src/9/port/mkbootrules - 775 sys sys 1055700518 923
 sys/src/9/port/mkdevc - 775 sys sys 1109202243 3889
 sys/src/9/port/mkdevc - 775 sys sys 1109202243 3889
@@ -8101,41 +8102,41 @@ sys/src/9/port/mksystab - 664 sys sys 1014931176 783
 sys/src/9/port/mul64fract.c - 664 sys sys 1071671674 867
 sys/src/9/port/mul64fract.c - 664 sys sys 1071671674 867
 sys/src/9/port/netif.c - 664 sys sys 1066514951 13421
 sys/src/9/port/netif.c - 664 sys sys 1066514951 13421
 sys/src/9/port/netif.h - 664 sys sys 1066514947 2975
 sys/src/9/port/netif.h - 664 sys sys 1066514947 2975
-sys/src/9/port/page.c - 664 sys sys 1102133425 8281
+sys/src/9/port/page.c - 664 sys sys 1131289949 8449
 sys/src/9/port/parse.c - 664 sys sys 1014931177 2026
 sys/src/9/port/parse.c - 664 sys sys 1014931177 2026
 sys/src/9/port/pgrp.c - 664 sys sys 1072704671 3940
 sys/src/9/port/pgrp.c - 664 sys sys 1072704671 3940
 sys/src/9/port/portclock.c - 664 sys sys 1102093397 4556
 sys/src/9/port/portclock.c - 664 sys sys 1102093397 4556
-sys/src/9/port/portdat.h - 664 sys sys 1127215703 22586
-sys/src/9/port/portfns.h - 664 sys sys 1126586141 11002
+sys/src/9/port/portdat.h - 664 sys sys 1131289971 22628
+sys/src/9/port/portfns.h - 664 sys sys 1131289972 10925
 sys/src/9/port/portmkfile - 664 sys sys 1124708650 2052
 sys/src/9/port/portmkfile - 664 sys sys 1124708650 2052
 sys/src/9/port/print.c - 664 sys sys 1014931178 227
 sys/src/9/port/print.c - 664 sys sys 1014931178 227
-sys/src/9/port/proc.c - 664 sys sys 1099760501 28207
+sys/src/9/port/proc.c - 664 sys sys 1131289980 28264
 sys/src/9/port/qio.c - 664 sys sys 1070287837 23562
 sys/src/9/port/qio.c - 664 sys sys 1070287837 23562
 sys/src/9/port/qlock.c - 664 sys sys 1067722765 3196
 sys/src/9/port/qlock.c - 664 sys sys 1067722765 3196
 sys/src/9/port/rdb.c - 664 sys sys 1018721202 1698
 sys/src/9/port/rdb.c - 664 sys sys 1018721202 1698
 sys/src/9/port/rebootcmd.c - 664 sys sys 1015278340 1561
 sys/src/9/port/rebootcmd.c - 664 sys sys 1015278340 1561
-sys/src/9/port/sd.h - 664 sys sys 1098546338 2348
-sys/src/9/port/segment.c - 664 sys sys 1121259584 13761
+sys/src/9/port/sd.h - 664 sys sys 1131289990 2494
+sys/src/9/port/segment.c - 664 sys sys 1131298540 13722
 sys/src/9/port/swap.c - 664 sys sys 1055688551 6980
 sys/src/9/port/swap.c - 664 sys sys 1055688551 6980
 sys/src/9/port/sysfile.c - 664 sys sys 1126586199 22173
 sys/src/9/port/sysfile.c - 664 sys sys 1126586199 22173
-sys/src/9/port/sysproc.c - 664 sys sys 1130387080 15144
+sys/src/9/port/sysproc.c - 664 sys sys 1131298541 15159
 sys/src/9/port/systab.h - 664 sys sys 1062721698 3044
 sys/src/9/port/systab.h - 664 sys sys 1062721698 3044
-sys/src/9/port/taslock.c - 664 sys sys 1084475129 3658
+sys/src/9/port/taslock.c - 664 sys sys 1131290039 3928
 sys/src/9/port/thwack.c - 664 sys sys 1057323394 7253
 sys/src/9/port/thwack.c - 664 sys sys 1057323394 7253
 sys/src/9/port/thwack.h - 664 sys sys 1015278340 1792
 sys/src/9/port/thwack.h - 664 sys sys 1015278340 1792
 sys/src/9/port/tod.c - 664 sys sys 1067722762 4856
 sys/src/9/port/tod.c - 664 sys sys 1067722762 4856
 sys/src/9/port/unthwack.c - 664 sys sys 1057323394 5249
 sys/src/9/port/unthwack.c - 664 sys sys 1057323394 5249
-sys/src/9/port/xalloc.c - 664 sys sys 1097074047 4030
+sys/src/9/port/xalloc.c - 664 sys sys 1131290051 4063
 sys/src/9/ppc - 20000000775 sys sys 1059490838 0
 sys/src/9/ppc - 20000000775 sys sys 1059490838 0
 sys/src/9/ppc/blast - 664 sys sys 1107436310 670
 sys/src/9/ppc/blast - 664 sys sys 1107436310 670
 sys/src/9/ppc/blast.h - 664 sys sys 1059490750 3109
 sys/src/9/ppc/blast.h - 664 sys sys 1059490750 3109
-sys/src/9/ppc/clock.c - 664 sys sys 1100701675 1036
+sys/src/9/ppc/clock.c - 664 sys sys 1131290066 1076
 sys/src/9/ppc/dat.h - 664 sys sys 1127274100 4735
 sys/src/9/ppc/dat.h - 664 sys sys 1127274100 4735
-sys/src/9/ppc/devether.c - 664 sys sys 1116097817 9264
+sys/src/9/ppc/devether.c - 664 sys sys 1131290184 9327
 sys/src/9/ppc/devflash.c - 664 sys sys 1059490750 19885
 sys/src/9/ppc/devflash.c - 664 sys sys 1059490750 19885
 sys/src/9/ppc/devirq.c - 664 sys sys 1100701675 6314
 sys/src/9/ppc/devirq.c - 664 sys sys 1100701675 6314
 sys/src/9/ppc/devtls.c - 664 sys sys 1059490751 43721
 sys/src/9/ppc/devtls.c - 664 sys sys 1059490751 43721
-sys/src/9/ppc/etherfcc.c - 664 sys sys 1100701674 19690
+sys/src/9/ppc/etherfcc.c - 664 sys sys 1131290110 19599
 sys/src/9/ppc/etherif.h - 664 sys sys 1059490751 785
 sys/src/9/ppc/etherif.h - 664 sys sys 1059490751 785
 sys/src/9/ppc/ethersaturn.c - 664 sys sys 1059490751 4321
 sys/src/9/ppc/ethersaturn.c - 664 sys sys 1059490751 4321
 sys/src/9/ppc/fns.h - 664 sys sys 1111851554 3095
 sys/src/9/ppc/fns.h - 664 sys sys 1111851554 3095
@@ -8147,7 +8148,7 @@ sys/src/9/ppc/lblast.h - 664 sys sys 1059490752 1694
 sys/src/9/ppc/lucu.h - 664 sys sys 1059490752 935
 sys/src/9/ppc/lucu.h - 664 sys sys 1059490752 935
 sys/src/9/ppc/m8260.c - 664 sys sys 1123094594 14482
 sys/src/9/ppc/m8260.c - 664 sys sys 1123094594 14482
 sys/src/9/ppc/m8260.h - 664 sys sys 1100701674 20899
 sys/src/9/ppc/m8260.h - 664 sys sys 1100701674 20899
-sys/src/9/ppc/main.c - 664 sys sys 1126586256 9039
+sys/src/9/ppc/main.c - 664 sys sys 1131290117 9075
 sys/src/9/ppc/mcc.c - 664 sys sys 1059490752 9667
 sys/src/9/ppc/mcc.c - 664 sys sys 1059490752 9667
 sys/src/9/ppc/mem.h - 664 sys sys 1091021860 7002
 sys/src/9/ppc/mem.h - 664 sys sys 1091021860 7002
 sys/src/9/ppc/mkfile - 664 sys sys 1067722849 1813
 sys/src/9/ppc/mkfile - 664 sys sys 1067722849 1813
@@ -8157,9 +8158,9 @@ sys/src/9/ppc/msaturn.h - 664 sys sys 1059490753 99
 sys/src/9/ppc/mtx.c - 664 sys sys 1059490753 177
 sys/src/9/ppc/mtx.c - 664 sys sys 1059490753 177
 sys/src/9/ppc/random.c - 664 sys sys 1059490753 1983
 sys/src/9/ppc/random.c - 664 sys sys 1059490753 1983
 sys/src/9/ppc/saturntimer.c - 664 sys sys 1072705482 1737
 sys/src/9/ppc/saturntimer.c - 664 sys sys 1072705482 1737
-sys/src/9/ppc/trap.c - 664 sys sys 1105030152 18384
+sys/src/9/ppc/trap.c - 664 sys sys 1131290140 17067
 sys/src/9/ppc/uartsaturn.c - 664 sys sys 1059490754 7151
 sys/src/9/ppc/uartsaturn.c - 664 sys sys 1059490754 7151
-sys/src/9/ppc/uartsmc.c - 664 sys sys 1068135489 11462
+sys/src/9/ppc/uartsmc.c - 664 sys sys 1131290162 9764
 sys/src/9/ppc/ucu - 664 sys sys 1067722849 672
 sys/src/9/ppc/ucu - 664 sys sys 1067722849 672
 sys/src/9/ppc/ucu.h - 664 sys sys 1059490754 531
 sys/src/9/ppc/ucu.h - 664 sys sys 1059490754 531
 sys/src/NOTICE - 444 sys sys 1018803112 63
 sys/src/NOTICE - 444 sys sys 1018803112 63
@@ -9238,11 +9239,11 @@ sys/src/cmd/9nfs/authhostowner.c - 664 sys sys 1071498519 4190
 sys/src/cmd/9nfs/chat.c - 664 sys sys 1017337813 2096
 sys/src/cmd/9nfs/chat.c - 664 sys sys 1017337813 2096
 sys/src/cmd/9nfs/dat.h - 664 sys sys 1071498518 4406
 sys/src/cmd/9nfs/dat.h - 664 sys sys 1071498518 4406
 sys/src/cmd/9nfs/fns.h - 664 sys sys 1071498519 1908
 sys/src/cmd/9nfs/fns.h - 664 sys sys 1071498519 1908
-sys/src/cmd/9nfs/listalloc.c - 664 sys sys 1015090372 297
+sys/src/cmd/9nfs/listalloc.c - 664 sys sys 1131293679 275
 sys/src/cmd/9nfs/mkfile - 664 sys sys 1071498518 640
 sys/src/cmd/9nfs/mkfile - 664 sys sys 1071498518 640
 sys/src/cmd/9nfs/mport.c - 664 sys sys 1050715069 3779
 sys/src/cmd/9nfs/mport.c - 664 sys sys 1050715069 3779
 sys/src/cmd/9nfs/nametest.c - 664 sys sys 1015090372 1723
 sys/src/cmd/9nfs/nametest.c - 664 sys sys 1015090372 1723
-sys/src/cmd/9nfs/nfs.c - 664 sys sys 1130424013 9509
+sys/src/cmd/9nfs/nfs.c - 664 sys sys 1131293679 9526
 sys/src/cmd/9nfs/nfs.h - 664 sys sys 1015090372 642
 sys/src/cmd/9nfs/nfs.h - 664 sys sys 1015090372 642
 sys/src/cmd/9nfs/nfsmount.c - 664 sys sys 1071498520 6142
 sys/src/cmd/9nfs/nfsmount.c - 664 sys sys 1071498520 6142
 sys/src/cmd/9nfs/nfsserver.c - 664 sys sys 1040952455 15576
 sys/src/cmd/9nfs/nfsserver.c - 664 sys sys 1040952455 15576
@@ -9256,22 +9257,22 @@ sys/src/cmd/9nfs/strparse.c - 664 sys sys 1015090373 506
 sys/src/cmd/9nfs/system.c - 664 sys sys 1017337815 437
 sys/src/cmd/9nfs/system.c - 664 sys sys 1017337815 437
 sys/src/cmd/9nfs/testit - 775 sys sys 1017337816 251
 sys/src/cmd/9nfs/testit - 775 sys sys 1017337816 251
 sys/src/cmd/9nfs/unixnames.c - 664 sys sys 1065963574 6006
 sys/src/cmd/9nfs/unixnames.c - 664 sys sys 1065963574 6006
-sys/src/cmd/9nfs/xfile.c - 664 sys sys 1017337816 1847
+sys/src/cmd/9nfs/xfile.c - 664 sys sys 1131293680 1894
 sys/src/cmd/aan.c - 664 sys sys 1019856827 9758
 sys/src/cmd/aan.c - 664 sys sys 1019856827 9758
 sys/src/cmd/acid - 20000000775 sys sys 944960739 0
 sys/src/cmd/acid - 20000000775 sys sys 944960739 0
-sys/src/cmd/acid/acid.h - 664 sys sys 1127393275 4389
-sys/src/cmd/acid/builtin.c - 664 sys sys 1127214825 20156
-sys/src/cmd/acid/dbg.y - 664 sys sys 1081736447 5567
-sys/src/cmd/acid/dot.c - 664 sys sys 944960739 2161
-sys/src/cmd/acid/exec.c - 664 sys sys 1016833876 8187
-sys/src/cmd/acid/expr.c - 664 sys sys 1127393280 15220
-sys/src/cmd/acid/lex.c - 664 sys sys 1046198960 7861
-sys/src/cmd/acid/list.c - 664 sys sys 944960738 3671
-sys/src/cmd/acid/main.c - 664 sys sys 1046198959 8475
+sys/src/cmd/acid/acid.h - 664 sys sys 1131289460 4273
+sys/src/cmd/acid/builtin.c - 664 sys sys 1131289462 20193
+sys/src/cmd/acid/dbg.y - 664 sys sys 1131289463 5568
+sys/src/cmd/acid/dot.c - 664 sys sys 1131289462 2162
+sys/src/cmd/acid/exec.c - 664 sys sys 1131289461 8383
+sys/src/cmd/acid/expr.c - 664 sys sys 1131289461 15220
+sys/src/cmd/acid/lex.c - 664 sys sys 1131289460 7963
+sys/src/cmd/acid/list.c - 664 sys sys 1131289462 3680
+sys/src/cmd/acid/main.c - 664 sys sys 1131289460 8565
 sys/src/cmd/acid/mkfile - 664 sys sys 1046199006 366
 sys/src/cmd/acid/mkfile - 664 sys sys 1046199006 366
-sys/src/cmd/acid/print.c - 664 sys sys 984756705 6840
-sys/src/cmd/acid/proc.c - 664 sys sys 1119470118 4602
-sys/src/cmd/acid/util.c - 664 sys sys 1127393277 4616
+sys/src/cmd/acid/print.c - 664 sys sys 1131289462 6831
+sys/src/cmd/acid/proc.c - 664 sys sys 1131289462 4356
+sys/src/cmd/acid/util.c - 664 sys sys 1131289461 4609
 sys/src/cmd/acme - 20000000775 sys sys 969511023 0
 sys/src/cmd/acme - 20000000775 sys sys 969511023 0
 sys/src/cmd/acme/acme.c - 664 sys sys 1104430286 19613
 sys/src/cmd/acme/acme.c - 664 sys sys 1104430286 19613
 sys/src/cmd/acme/addr.c - 664 sys sys 1111171698 4805
 sys/src/cmd/acme/addr.c - 664 sys sys 1111171698 4805
@@ -9297,7 +9298,7 @@ sys/src/cmd/acme/time.c - 664 sys sys 1014926095 1783
 sys/src/cmd/acme/util.c - 664 sys sys 1107154483 7984
 sys/src/cmd/acme/util.c - 664 sys sys 1107154483 7984
 sys/src/cmd/acme/wind.c - 664 sys sys 1122526112 11233
 sys/src/cmd/acme/wind.c - 664 sys sys 1122526112 11233
 sys/src/cmd/acme/xfid.c - 664 sys sys 1125314186 19766
 sys/src/cmd/acme/xfid.c - 664 sys sys 1125314186 19766
-sys/src/cmd/ar.c - 664 sys sys 1046643027 23717
+sys/src/cmd/ar.c - 664 sys sys 1131293258 23778
 sys/src/cmd/archfs.c - 664 sys sys 1014925694 3871
 sys/src/cmd/archfs.c - 664 sys sys 1014925694 3871
 sys/src/cmd/ascii.c - 664 sys sys 964457138 3989
 sys/src/cmd/ascii.c - 664 sys sys 964457138 3989
 sys/src/cmd/astro - 20000000775 sys sys 964456342 0
 sys/src/cmd/astro - 20000000775 sys sys 964456342 0
@@ -9352,7 +9353,7 @@ sys/src/cmd/auth/factotum/chap.c - 664 sys sys 1107706103 8967
 sys/src/cmd/auth/factotum/confirm.c - 664 sys sys 1044829586 3103
 sys/src/cmd/auth/factotum/confirm.c - 664 sys sys 1044829586 3103
 sys/src/cmd/auth/factotum/dat.h - 664 sys sys 1121367028 4946
 sys/src/cmd/auth/factotum/dat.h - 664 sys sys 1121367028 4946
 sys/src/cmd/auth/factotum/fgui.c - 664 sys sys 1130425760 15984
 sys/src/cmd/auth/factotum/fgui.c - 664 sys sys 1130425760 15984
-sys/src/cmd/auth/factotum/fs.c - 664 sys sys 1107706104 10447
+sys/src/cmd/auth/factotum/fs.c - 664 sys sys 1131289797 10524
 sys/src/cmd/auth/factotum/log.c - 664 sys sys 1046655068 1781
 sys/src/cmd/auth/factotum/log.c - 664 sys sys 1046655068 1781
 sys/src/cmd/auth/factotum/mkfile - 664 sys sys 1107706102 481
 sys/src/cmd/auth/factotum/mkfile - 664 sys sys 1107706102 481
 sys/src/cmd/auth/factotum/p9any.c - 664 sys sys 1107706103 8484
 sys/src/cmd/auth/factotum/p9any.c - 664 sys sys 1107706103 8484
@@ -9363,7 +9364,7 @@ sys/src/cmd/auth/factotum/rpc.c - 664 sys sys 1107633794 11167
 sys/src/cmd/auth/factotum/rsa.c - 664 sys sys 1107706104 3416
 sys/src/cmd/auth/factotum/rsa.c - 664 sys sys 1107706104 3416
 sys/src/cmd/auth/factotum/secstore.c - 664 sys sys 1107633794 14935
 sys/src/cmd/auth/factotum/secstore.c - 664 sys sys 1107633794 14935
 sys/src/cmd/auth/factotum/sshrsa.c - 664 sys sys 1107633793 3416
 sys/src/cmd/auth/factotum/sshrsa.c - 664 sys sys 1107633793 3416
-sys/src/cmd/auth/factotum/util.c - 664 sys sys 1117193215 17915
+sys/src/cmd/auth/factotum/util.c - 664 sys sys 1131289797 18035
 sys/src/cmd/auth/factotum/wep.c - 664 sys sys 1107706104 2140
 sys/src/cmd/auth/factotum/wep.c - 664 sys sys 1107706104 2140
 sys/src/cmd/auth/guard.srv.c - 664 sys sys 1032497638 2334
 sys/src/cmd/auth/guard.srv.c - 664 sys sys 1032497638 2334
 sys/src/cmd/auth/iam.c - 664 sys sys 1015008430 841
 sys/src/cmd/auth/iam.c - 664 sys sys 1015008430 841
@@ -9728,8 +9729,8 @@ sys/src/cmd/cc/compat.c - 664 sys sys 1084472048 417
 sys/src/cmd/cc/dcl.c - 664 sys sys 1089299183 26723
 sys/src/cmd/cc/dcl.c - 664 sys sys 1089299183 26723
 sys/src/cmd/cc/dpchk.c - 664 sys sys 1107365037 7152
 sys/src/cmd/cc/dpchk.c - 664 sys sys 1107365037 7152
 sys/src/cmd/cc/funct.c - 664 sys sys 984718510 6167
 sys/src/cmd/cc/funct.c - 664 sys sys 984718510 6167
-sys/src/cmd/cc/lex.c - 664 sys sys 1127766297 23848
-sys/src/cmd/cc/lexbody - 664 sys sys 1127307403 9186
+sys/src/cmd/cc/lex.c - 664 sys sys 1131293446 23883
+sys/src/cmd/cc/lexbody - 664 sys sys 1131293457 9188
 sys/src/cmd/cc/mac.c - 664 sys sys 944960808 36
 sys/src/cmd/cc/mac.c - 664 sys sys 944960808 36
 sys/src/cmd/cc/macbody - 664 sys sys 1108281581 11703
 sys/src/cmd/cc/macbody - 664 sys sys 1108281581 11703
 sys/src/cmd/cc/machcap.c - 664 sys sys 1084472048 78
 sys/src/cmd/cc/machcap.c - 664 sys sys 1084472048 78
@@ -9796,21 +9797,21 @@ sys/src/cmd/cpu.c - 664 sys sys 1123676384 21128
 sys/src/cmd/crop.c - 664 sys sys 1039753034 4136
 sys/src/cmd/crop.c - 664 sys sys 1039753034 4136
 sys/src/cmd/date.c - 664 sys sys 944961351 449
 sys/src/cmd/date.c - 664 sys sys 944961351 449
 sys/src/cmd/db - 20000000775 sys sys 988249965 0
 sys/src/cmd/db - 20000000775 sys sys 988249965 0
-sys/src/cmd/db/command.c - 664 sys sys 1121977158 4362
-sys/src/cmd/db/defs.h - 664 sys sys 1016731555 1704
-sys/src/cmd/db/expr.c - 664 sys sys 1016731556 5450
-sys/src/cmd/db/fns.h - 664 sys sys 958696023 2011
-sys/src/cmd/db/format.c - 664 sys sys 1016731556 6873
+sys/src/cmd/db/command.c - 664 sys sys 1131297926 4377
+sys/src/cmd/db/defs.h - 664 sys sys 1131292957 1700
+sys/src/cmd/db/expr.c - 664 sys sys 1131292957 5441
+sys/src/cmd/db/fns.h - 664 sys sys 1131297926 2014
+sys/src/cmd/db/format.c - 664 sys sys 1131297926 6868
 sys/src/cmd/db/input.c - 664 sys sys 1016731556 2194
 sys/src/cmd/db/input.c - 664 sys sys 1016731556 2194
 sys/src/cmd/db/main.c - 664 sys sys 1016731556 3308
 sys/src/cmd/db/main.c - 664 sys sys 1016731556 3308
 sys/src/cmd/db/mkfile - 664 sys sys 944960880 233
 sys/src/cmd/db/mkfile - 664 sys sys 944960880 233
 sys/src/cmd/db/output.c - 664 sys sys 1014925293 2009
 sys/src/cmd/db/output.c - 664 sys sys 1014925293 2009
 sys/src/cmd/db/pcs.c - 664 sys sys 1016731557 2859
 sys/src/cmd/db/pcs.c - 664 sys sys 1016731557 2859
-sys/src/cmd/db/print.c - 664 sys sys 1046363143 5856
-sys/src/cmd/db/regs.c - 664 sys sys 1014925293 1998
+sys/src/cmd/db/print.c - 664 sys sys 1131297926 5949
+sys/src/cmd/db/regs.c - 664 sys sys 1131297926 1998
 sys/src/cmd/db/runpcs.c - 664 sys sys 1014925293 2929
 sys/src/cmd/db/runpcs.c - 664 sys sys 1014925293 2929
 sys/src/cmd/db/setup.c - 664 sys sys 1014925293 3581
 sys/src/cmd/db/setup.c - 664 sys sys 1014925293 3581
-sys/src/cmd/db/trcrun.c - 664 sys sys 1016731556 4432
+sys/src/cmd/db/trcrun.c - 664 sys sys 1131297926 4433
 sys/src/cmd/dc.c - 664 sys sys 1121977159 36572
 sys/src/cmd/dc.c - 664 sys sys 1121977159 36572
 sys/src/cmd/dd.c - 664 sys sys 1126360951 11753
 sys/src/cmd/dd.c - 664 sys sys 1126360951 11753
 sys/src/cmd/deroff.c - 664 sys sys 1017679319 14611
 sys/src/cmd/deroff.c - 664 sys sys 1017679319 14611
@@ -12131,7 +12132,7 @@ sys/src/cmd/kl/pass.c - 664 sys sys 1045503969 9348
 sys/src/cmd/kl/sched.c - 664 sys sys 1089299170 10796
 sys/src/cmd/kl/sched.c - 664 sys sys 1089299170 10796
 sys/src/cmd/kl/span.c - 664 sys sys 1045503970 10146
 sys/src/cmd/kl/span.c - 664 sys sys 1045503970 10146
 sys/src/cmd/kprof.c - 664 sys sys 1123244004 2550
 sys/src/cmd/kprof.c - 664 sys sys 1123244004 2550
-sys/src/cmd/ktrace.c - 664 sys sys 1119276523 5785
+sys/src/cmd/ktrace.c - 664 sys sys 1131293224 5885
 sys/src/cmd/lens.c - 664 sys sys 1130425803 5109
 sys/src/cmd/lens.c - 664 sys sys 1130425803 5109
 sys/src/cmd/lex - 20000000775 sys sys 944961017 0
 sys/src/cmd/lex - 20000000775 sys sys 944961017 0
 sys/src/cmd/lex/header.c - 664 sys sys 1032060383 3368
 sys/src/cmd/lex/header.c - 664 sys sys 1032060383 3368
@@ -12210,31 +12211,31 @@ sys/src/cmd/mc.c - 664 sys sys 1082924484 5520
 sys/src/cmd/md5sum.c - 664 sys sys 1014926238 1009
 sys/src/cmd/md5sum.c - 664 sys sys 1014926238 1009
 sys/src/cmd/mk - 20000000775 sys sys 988249988 0
 sys/src/cmd/mk - 20000000775 sys sys 988249988 0
 sys/src/cmd/mk/acid - 664 sys sys 1055698806 10395
 sys/src/cmd/mk/acid - 664 sys sys 1055698806 10395
-sys/src/cmd/mk/arc.c - 664 sys sys 944961024 835
-sys/src/cmd/mk/archive.c - 664 sys sys 964662348 2941
+sys/src/cmd/mk/arc.c - 664 sys sys 1131289508 826
+sys/src/cmd/mk/archive.c - 664 sys sys 1131289509 3071
 sys/src/cmd/mk/bufblock.c - 664 sys sys 944961024 1338
 sys/src/cmd/mk/bufblock.c - 664 sys sys 944961024 1338
-sys/src/cmd/mk/env.c - 664 sys sys 944961024 2290
-sys/src/cmd/mk/file.c - 664 sys sys 1055698807 1310
+sys/src/cmd/mk/env.c - 664 sys sys 1131289509 2281
+sys/src/cmd/mk/file.c - 664 sys sys 1131289509 1299
 sys/src/cmd/mk/fns.h - 664 sys sys 1055698809 2199
 sys/src/cmd/mk/fns.h - 664 sys sys 1055698809 2199
-sys/src/cmd/mk/graph.c - 664 sys sys 988225293 5842
+sys/src/cmd/mk/graph.c - 664 sys sys 1131289509 5822
 sys/src/cmd/mk/job.c - 664 sys sys 944961025 692
 sys/src/cmd/mk/job.c - 664 sys sys 944961025 692
 sys/src/cmd/mk/lex.c - 664 sys sys 944961025 2315
 sys/src/cmd/mk/lex.c - 664 sys sys 944961025 2315
 sys/src/cmd/mk/main.c - 664 sys sys 1123094366 4790
 sys/src/cmd/mk/main.c - 664 sys sys 1123094366 4790
 sys/src/cmd/mk/match.c - 664 sys sys 1014926073 856
 sys/src/cmd/mk/match.c - 664 sys sys 1014926073 856
-sys/src/cmd/mk/mk.c - 664 sys sys 1123676387 5348
-sys/src/cmd/mk/mk.h - 664 sys sys 1055698812 3735
+sys/src/cmd/mk/mk.c - 664 sys sys 1131289509 5330
+sys/src/cmd/mk/mk.h - 664 sys sys 1131289508 3765
 sys/src/cmd/mk/mkconv - 775 sys sys 944961025 555
 sys/src/cmd/mk/mkconv - 775 sys sys 944961025 555
 sys/src/cmd/mk/mkfile - 664 sys sys 1055698812 376
 sys/src/cmd/mk/mkfile - 664 sys sys 1055698812 376
 sys/src/cmd/mk/parse.c - 664 sys sys 944961025 5310
 sys/src/cmd/mk/parse.c - 664 sys sys 944961025 5310
-sys/src/cmd/mk/plan9.c - 664 sys sys 1121977161 6929
+sys/src/cmd/mk/plan9.c - 664 sys sys 1131289511 6941
 sys/src/cmd/mk/rc.c - 664 sys sys 944961025 3206
 sys/src/cmd/mk/rc.c - 664 sys sys 944961025 3206
-sys/src/cmd/mk/recipe.c - 664 sys sys 1014926074 2551
-sys/src/cmd/mk/rule.c - 664 sys sys 944961025 1970
-sys/src/cmd/mk/run.c - 664 sys sys 1014926074 5080
+sys/src/cmd/mk/recipe.c - 664 sys sys 1131289510 2543
+sys/src/cmd/mk/rule.c - 664 sys sys 1131289510 1946
+sys/src/cmd/mk/run.c - 664 sys sys 1131289510 5063
 sys/src/cmd/mk/shprint.c - 664 sys sys 952627588 1515
 sys/src/cmd/mk/shprint.c - 664 sys sys 952627588 1515
-sys/src/cmd/mk/symtab.c - 664 sys sys 944961025 1581
-sys/src/cmd/mk/var.c - 664 sys sys 944961025 539
-sys/src/cmd/mk/varsub.c - 664 sys sys 944961025 4438
+sys/src/cmd/mk/symtab.c - 664 sys sys 1131289510 1581
+sys/src/cmd/mk/var.c - 664 sys sys 1131289510 530
+sys/src/cmd/mk/varsub.c - 664 sys sys 1131289511 4425
 sys/src/cmd/mk/word.c - 664 sys sys 944961025 2595
 sys/src/cmd/mk/word.c - 664 sys sys 944961025 2595
 sys/src/cmd/mkdir.c - 664 sys sys 1082593106 1026
 sys/src/cmd/mkdir.c - 664 sys sys 1082593106 1026
 sys/src/cmd/mkfile - 664 sys sys 1108476348 2414
 sys/src/cmd/mkfile - 664 sys sys 1108476348 2414
@@ -12275,7 +12276,7 @@ sys/src/cmd/ndb/time.c - 664 sys sys 957402055 321
 sys/src/cmd/netstat.c - 664 sys sys 1128255434 4086
 sys/src/cmd/netstat.c - 664 sys sys 1128255434 4086
 sys/src/cmd/news.c - 664 sys sys 1014926614 3778
 sys/src/cmd/news.c - 664 sys sys 1014926614 3778
 sys/src/cmd/nfs.c - 664 sys sys 1050068720 31096
 sys/src/cmd/nfs.c - 664 sys sys 1050068720 31096
-sys/src/cmd/nm.c - 664 sys sys 1073313392 4912
+sys/src/cmd/nm.c - 664 sys sys 1131292928 4914
 sys/src/cmd/nntpfs.c - 664 sys sys 1100524486 18920
 sys/src/cmd/nntpfs.c - 664 sys sys 1100524486 18920
 sys/src/cmd/ns.c - 664 sys sys 984717934 3558
 sys/src/cmd/ns.c - 664 sys sys 984717934 3558
 sys/src/cmd/p.c - 664 sys sys 1121977162 1504
 sys/src/cmd/p.c - 664 sys sys 1121977162 1504
@@ -12719,7 +12720,7 @@ sys/src/cmd/rc/tree.c - 664 sys sys 1055698780 2071
 sys/src/cmd/rc/unix.c - 664 sys sys 1055698781 8726
 sys/src/cmd/rc/unix.c - 664 sys sys 1055698781 8726
 sys/src/cmd/rc/var.c - 664 sys sys 1055698781 1298
 sys/src/cmd/rc/var.c - 664 sys sys 1055698781 1298
 sys/src/cmd/rc/win32.c - 664 sys sys 1055698781 8699
 sys/src/cmd/rc/win32.c - 664 sys sys 1055698781 8699
-sys/src/cmd/rdbfs.c - 664 sys sys 1049426950 7952
+sys/src/cmd/rdbfs.c - 664 sys sys 1131289483 7964
 sys/src/cmd/read.c - 664 sys sys 1022047660 1278
 sys/src/cmd/read.c - 664 sys sys 1022047660 1278
 sys/src/cmd/replica - 20000000775 sys sys 1018321113 0
 sys/src/cmd/replica - 20000000775 sys sys 1018321113 0
 sys/src/cmd/replica/all.h - 664 sys sys 1091904421 1265
 sys/src/cmd/replica/all.h - 664 sys sys 1091904421 1265
@@ -12921,7 +12922,7 @@ sys/src/cmd/ssh/sshserve.c - 664 sys sys 1062091020 5786
 sys/src/cmd/ssh/util.c - 664 sys sys 1063858753 4478
 sys/src/cmd/ssh/util.c - 664 sys sys 1063858753 4478
 sys/src/cmd/stats.c - 664 sys sys 1127974208 28128
 sys/src/cmd/stats.c - 664 sys sys 1127974208 28128
 sys/src/cmd/strings.c - 664 sys sys 944961364 1216
 sys/src/cmd/strings.c - 664 sys sys 944961364 1216
-sys/src/cmd/strip.c - 664 sys sys 1108077276 3350
+sys/src/cmd/strip.c - 664 sys sys 1131293244 2502
 sys/src/cmd/sum.c - 664 sys sys 1014926615 5548
 sys/src/cmd/sum.c - 664 sys sys 1014926615 5548
 sys/src/cmd/swap.c - 664 sys sys 1014926662 1141
 sys/src/cmd/swap.c - 664 sys sys 1014926662 1141
 sys/src/cmd/syscall - 20000000775 sys sys 944961236 0
 sys/src/cmd/syscall - 20000000775 sys sys 944961236 0
@@ -12952,12 +12953,12 @@ sys/src/cmd/tbl/t2.c - 664 sys sys 944961244 298
 sys/src/cmd/tbl/t3.c - 664 sys sys 944961244 1836
 sys/src/cmd/tbl/t3.c - 664 sys sys 944961244 1836
 sys/src/cmd/tbl/t4.c - 664 sys sys 944961244 8360
 sys/src/cmd/tbl/t4.c - 664 sys sys 944961244 8360
 sys/src/cmd/tbl/t5.c - 664 sys sys 944961244 3723
 sys/src/cmd/tbl/t5.c - 664 sys sys 944961244 3723
-sys/src/cmd/tbl/t6.c - 664 sys sys 1014926400 7208
+sys/src/cmd/tbl/t6.c - 664 sys sys 1131293512 7295
 sys/src/cmd/tbl/t7.c - 664 sys sys 944961244 3422
 sys/src/cmd/tbl/t7.c - 664 sys sys 944961244 3422
-sys/src/cmd/tbl/t8.c - 664 sys sys 944961244 8959
+sys/src/cmd/tbl/t8.c - 664 sys sys 1131293517 9041
 sys/src/cmd/tbl/t9.c - 664 sys sys 944961244 1577
 sys/src/cmd/tbl/t9.c - 664 sys sys 944961244 1577
 sys/src/cmd/tbl/tb.c - 664 sys sys 944961244 1732
 sys/src/cmd/tbl/tb.c - 664 sys sys 944961244 1732
-sys/src/cmd/tbl/tc.c - 664 sys sys 944961244 1268
+sys/src/cmd/tbl/tc.c - 664 sys sys 1131293494 1274
 sys/src/cmd/tbl/te.c - 664 sys sys 944961244 1071
 sys/src/cmd/tbl/te.c - 664 sys sys 944961244 1071
 sys/src/cmd/tbl/tf.c - 664 sys sys 944961244 1283
 sys/src/cmd/tbl/tf.c - 664 sys sys 944961244 1283
 sys/src/cmd/tbl/tg.c - 664 sys sys 1128819351 2164
 sys/src/cmd/tbl/tg.c - 664 sys sys 1128819351 2164
@@ -13408,7 +13409,7 @@ sys/src/cmd/upas/send/tryit - 664 sys sys 944961322 584
 sys/src/cmd/upas/smtp - 20000000775 sys sys 988250017 0
 sys/src/cmd/upas/smtp - 20000000775 sys sys 988250017 0
 sys/src/cmd/upas/smtp/greylist.c - 664 sys sys 1091126808 6470
 sys/src/cmd/upas/smtp/greylist.c - 664 sys sys 1091126808 6470
 sys/src/cmd/upas/smtp/mkfile - 664 sys sys 1108910002 801
 sys/src/cmd/upas/smtp/mkfile - 664 sys sys 1108910002 801
-sys/src/cmd/upas/smtp/mxdial.c - 664 sys sys 1127394225 6422
+sys/src/cmd/upas/smtp/mxdial.c - 664 sys sys 1131293478 6420
 sys/src/cmd/upas/smtp/rfc822.y - 664 sys sys 1064589606 13417
 sys/src/cmd/upas/smtp/rfc822.y - 664 sys sys 1064589606 13417
 sys/src/cmd/upas/smtp/rmtdns.c - 664 sys sys 1015013150 1069
 sys/src/cmd/upas/smtp/rmtdns.c - 664 sys sys 1015013150 1069
 sys/src/cmd/upas/smtp/smtp.c - 664 sys sys 1127394218 20091
 sys/src/cmd/upas/smtp/smtp.c - 664 sys sys 1127394218 20091
@@ -13565,7 +13566,7 @@ sys/src/cmd/vi/cmd.c - 664 sys sys 944961342 9150
 sys/src/cmd/vi/float.c - 664 sys sys 944961341 12758
 sys/src/cmd/vi/float.c - 664 sys sys 944961341 12758
 sys/src/cmd/vi/icache.c - 664 sys sys 944961342 184
 sys/src/cmd/vi/icache.c - 664 sys sys 944961342 184
 sys/src/cmd/vi/mem.c - 664 sys sys 944961342 4234
 sys/src/cmd/vi/mem.c - 664 sys sys 944961342 4234
-sys/src/cmd/vi/mips.h - 664 sys sys 1124229127 4836
+sys/src/cmd/vi/mips.h - 664 sys sys 1131292943 4837
 sys/src/cmd/vi/mkfile - 664 sys sys 1124229127 289
 sys/src/cmd/vi/mkfile - 664 sys sys 1124229127 289
 sys/src/cmd/vi/run.c - 664 sys sys 1014926560 13214
 sys/src/cmd/vi/run.c - 664 sys sys 1014926560 13214
 sys/src/cmd/vi/special.c - 664 sys sys 944961342 6723
 sys/src/cmd/vi/special.c - 664 sys sys 944961342 6723
@@ -13837,7 +13838,7 @@ sys/src/games/music/missing - 775 sys sys 1103793915 72
 sys/src/games/music/mkfile - 664 sys sys 1103793915 723
 sys/src/games/music/mkfile - 664 sys sys 1103793915 723
 sys/src/games/music/mkinc - 664 sys sys 1103793915 92
 sys/src/games/music/mkinc - 664 sys sys 1103793915 92
 sys/src/games/music/playlistfs - 20000000775 sys sys 1103794221 0
 sys/src/games/music/playlistfs - 20000000775 sys sys 1103794221 0
-sys/src/games/music/playlistfs/boilerplate.c - 664 sys sys 1105531426 1362
+sys/src/games/music/playlistfs/boilerplate.c - 664 sys sys 1131293384 1547
 sys/src/games/music/playlistfs/fs.c - 664 sys sys 1111504109 17985
 sys/src/games/music/playlistfs/fs.c - 664 sys sys 1111504109 17985
 sys/src/games/music/playlistfs/main.c - 664 sys sys 1103793922 1636
 sys/src/games/music/playlistfs/main.c - 664 sys sys 1103793922 1636
 sys/src/games/music/playlistfs/mk.dep - 664 sys sys 1103793923 594
 sys/src/games/music/playlistfs/mk.dep - 664 sys sys 1103793923 594
@@ -14538,52 +14539,52 @@ sys/src/liblex/reject.c - 664 sys sys 944961728 1000
 sys/src/liblex/yyless.c - 664 sys sys 944961728 403
 sys/src/liblex/yyless.c - 664 sys sys 944961728 403
 sys/src/liblex/yywrap.c - 664 sys sys 944961728 85
 sys/src/liblex/yywrap.c - 664 sys sys 944961728 85
 sys/src/libmach - 20000000775 sys sys 969559166 0
 sys/src/libmach - 20000000775 sys sys 969559166 0
-sys/src/libmach/0.c - 664 sys sys 1114459829 4037
+sys/src/libmach/0.c - 664 sys sys 1131289379 4080
 sys/src/libmach/0c - 20000000775 sys sys 1114459438 0
 sys/src/libmach/0c - 20000000775 sys sys 1114459438 0
 sys/src/libmach/0c/README - 664 sys sys 1114459609 73
 sys/src/libmach/0c/README - 664 sys sys 1114459609 73
 sys/src/libmach/0c/ureg.h - 664 sys sys 1114459438 886
 sys/src/libmach/0c/ureg.h - 664 sys sys 1114459438 886
-sys/src/libmach/2.c - 664 sys sys 964540513 2034
-sys/src/libmach/2db.c - 664 sys sys 1014929543 61245
+sys/src/libmach/2.c - 664 sys sys 1131289379 2074
+sys/src/libmach/2db.c - 664 sys sys 1131289383 61298
 sys/src/libmach/2obj.c - 664 sys sys 1091732624 2335
 sys/src/libmach/2obj.c - 664 sys sys 1091732624 2335
-sys/src/libmach/5.c - 664 sys sys 984710422 1513
-sys/src/libmach/5db.c - 664 sys sys 1114218476 21530
+sys/src/libmach/5.c - 664 sys sys 1131289380 1553
+sys/src/libmach/5db.c - 664 sys sys 1131289383 21545
 sys/src/libmach/5obj.c - 664 sys sys 1091732625 2209
 sys/src/libmach/5obj.c - 664 sys sys 1091732625 2209
-sys/src/libmach/6.c - 664 sys sys 1119476887 3366
+sys/src/libmach/6.c - 664 sys sys 1131289380 3464
 sys/src/libmach/6c - 20000000775 sys sys 1123100867 0
 sys/src/libmach/6c - 20000000775 sys sys 1123100867 0
 sys/src/libmach/6c/6.out.h - 664 sys sys 1114459480 7984
 sys/src/libmach/6c/6.out.h - 664 sys sys 1114459480 7984
 sys/src/libmach/6obj.c - 664 sys sys 1114459831 2382
 sys/src/libmach/6obj.c - 664 sys sys 1114459831 2382
-sys/src/libmach/7.c - 664 sys sys 964540515 3267
-sys/src/libmach/7db.c - 664 sys sys 1014929543 17320
+sys/src/libmach/7.c - 664 sys sys 1131289380 3299
+sys/src/libmach/7db.c - 664 sys sys 1131289384 17330
 sys/src/libmach/7obj.c - 664 sys sys 1091732676 2367
 sys/src/libmach/7obj.c - 664 sys sys 1091732676 2367
-sys/src/libmach/8.c - 664 sys sys 964540515 2020
-sys/src/libmach/8db.c - 664 sys sys 1114459831 50189
+sys/src/libmach/8.c - 664 sys sys 1131289381 2060
+sys/src/libmach/8db.c - 664 sys sys 1131289384 50612
 sys/src/libmach/8obj.c - 664 sys sys 1091732625 2200
 sys/src/libmach/8obj.c - 664 sys sys 1091732625 2200
-sys/src/libmach/access.c - 664 sys sys 1068478065 4309
-sys/src/libmach/elf.h - 664 sys sys 1114459895 2323
-sys/src/libmach/executable.c - 664 sys sys 1119476886 15431
-sys/src/libmach/k.c - 664 sys sys 964540516 3330
-sys/src/libmach/kdb.c - 664 sys sys 1014929544 21143
+sys/src/libmach/access.c - 664 sys sys 1131289377 4588
+sys/src/libmach/elf.h - 664 sys sys 1131292881 2301
+sys/src/libmach/executable.c - 664 sys sys 1131289375 16128
+sys/src/libmach/k.c - 664 sys sys 1131289378 3370
+sys/src/libmach/kdb.c - 664 sys sys 1131289381 21161
 sys/src/libmach/kobj.c - 664 sys sys 1091732625 2217
 sys/src/libmach/kobj.c - 664 sys sys 1091732625 2217
-sys/src/libmach/machdata.c - 664 sys sys 964540516 8814
-sys/src/libmach/map.c - 664 sys sys 964540517 3053
+sys/src/libmach/machdata.c - 664 sys sys 1131289377 8799
+sys/src/libmach/map.c - 664 sys sys 1131289376 3056
 sys/src/libmach/mkfile - 664 sys sys 1114459827 467
 sys/src/libmach/mkfile - 664 sys sys 1114459827 467
-sys/src/libmach/obj.c - 664 sys sys 1121367249 5918
-sys/src/libmach/obj.h - 664 sys sys 964540517 603
-sys/src/libmach/q.c - 664 sys sys 1091732625 3590
-sys/src/libmach/qdb.c - 664 sys sys 1114459830 27490
+sys/src/libmach/obj.c - 664 sys sys 1131289376 5929
+sys/src/libmach/obj.h - 664 sys sys 1131292890 604
+sys/src/libmach/q.c - 664 sys sys 1131289379 3630
+sys/src/libmach/qdb.c - 664 sys sys 1131289382 27506
 sys/src/libmach/qobj.c - 664 sys sys 1091732625 2310
 sys/src/libmach/qobj.c - 664 sys sys 1091732625 2310
 sys/src/libmach/setmach.c - 664 sys sys 1119476886 2911
 sys/src/libmach/setmach.c - 664 sys sys 1119476886 2911
-sys/src/libmach/swap.c - 664 sys sys 964540518 1026
-sys/src/libmach/sym.c - 664 sys sys 1106409575 26581
-sys/src/libmach/u.c - 664 sys sys 1114459829 3396
+sys/src/libmach/swap.c - 664 sys sys 1131289376 1056
+sys/src/libmach/sym.c - 664 sys sys 1131289377 26729
+sys/src/libmach/u.c - 664 sys sys 1131289378 3436
 sys/src/libmach/uc - 20000000775 sys sys 1114459488 0
 sys/src/libmach/uc - 20000000775 sys sys 1114459488 0
 sys/src/libmach/uc/README - 664 sys sys 1114459488 73
 sys/src/libmach/uc/README - 664 sys sys 1114459488 73
 sys/src/libmach/uc/u.out.h - 664 sys sys 1114459488 3137
 sys/src/libmach/uc/u.out.h - 664 sys sys 1114459488 3137
-sys/src/libmach/udb.c - 664 sys sys 1114459830 21893
+sys/src/libmach/udb.c - 664 sys sys 1131289382 21910
 sys/src/libmach/uobj.c - 664 sys sys 1114459831 2219
 sys/src/libmach/uobj.c - 664 sys sys 1114459831 2219
-sys/src/libmach/v.c - 664 sys sys 964540518 3403
-sys/src/libmach/vcodas.c - 664 sys sys 1014929545 10253
-sys/src/libmach/vdb.c - 664 sys sys 1014929545 22248
+sys/src/libmach/v.c - 664 sys sys 1131289378 3446
+sys/src/libmach/vcodas.c - 664 sys sys 1131289385 10258
+sys/src/libmach/vdb.c - 664 sys sys 1131289381 22264
 sys/src/libmach/vobj.c - 664 sys sys 1091732625 2206
 sys/src/libmach/vobj.c - 664 sys sys 1091732625 2206
 sys/src/libmemdraw - 20000000775 sys sys 985020762 0
 sys/src/libmemdraw - 20000000775 sys sys 985020762 0
 sys/src/libmemdraw/alloc.c - 664 sys sys 1046640198 3234
 sys/src/libmemdraw/alloc.c - 664 sys sys 1046640198 3234

+ 273 - 0
dist/replica/plan9.log

@@ -22568,3 +22568,276 @@
 1131210084 0 a sys/man/8/statusbar - 664 sys sys 1131209276 1199
 1131210084 0 a sys/man/8/statusbar - 664 sys sys 1131209276 1199
 1131210084 1 c sys/src/cmd/aux/statusbar.c - 664 sys sys 1131209286 6025
 1131210084 1 c sys/src/cmd/aux/statusbar.c - 664 sys sys 1131209286 6025
 1131251494 0 c 386/bin/aux/statusbar - 775 sys sys 1131250131 151558
 1131251494 0 c 386/bin/aux/statusbar - 775 sys sys 1131250131 151558
+1131287502 0 c sys/src/9/pc/ether83815.c - 664 sys sys 1131287537 23542
+1131289302 0 c sys/include/mach.h - 664 sys sys 1131289126 8586
+1131289302 1 c sys/src/libmach/0.c - 664 sys sys 1131289379 4080
+1131289302 2 c sys/src/libmach/2.c - 664 sys sys 1131289379 2074
+1131289302 3 c sys/src/libmach/2db.c - 664 sys sys 1131289383 61298
+1131289302 4 c sys/src/libmach/5.c - 664 sys sys 1131289380 1553
+1131289302 5 c sys/src/libmach/5db.c - 664 sys sys 1131289383 21545
+1131289302 6 c sys/src/libmach/6.c - 664 sys sys 1131289380 3464
+1131289302 7 c sys/src/libmach/7.c - 664 sys sys 1131289380 3299
+1131289302 8 c sys/src/libmach/7db.c - 664 sys sys 1131289384 17330
+1131289302 9 c sys/src/libmach/8.c - 664 sys sys 1131289381 2060
+1131289302 10 c sys/src/libmach/8db.c - 664 sys sys 1131289384 50612
+1131289302 11 c sys/src/libmach/access.c - 664 sys sys 1131289377 4588
+1131289302 12 c sys/src/libmach/executable.c - 664 sys sys 1131289375 16128
+1131289302 13 c sys/src/libmach/k.c - 664 sys sys 1131289378 3370
+1131289302 14 c sys/src/libmach/kdb.c - 664 sys sys 1131289381 21161
+1131289302 15 c sys/src/libmach/machdata.c - 664 sys sys 1131289377 8799
+1131289302 16 c sys/src/libmach/map.c - 664 sys sys 1131289376 3056
+1131289302 17 c sys/src/libmach/obj.c - 664 sys sys 1131289376 5929
+1131289302 18 c sys/src/libmach/q.c - 664 sys sys 1131289379 3630
+1131289302 19 c sys/src/libmach/qdb.c - 664 sys sys 1131289382 27506
+1131289302 20 c sys/src/libmach/swap.c - 664 sys sys 1131289376 1056
+1131289302 21 c sys/src/libmach/sym.c - 664 sys sys 1131289377 26729
+1131289302 22 c sys/src/libmach/u.c - 664 sys sys 1131289378 3436
+1131289302 23 c sys/src/libmach/udb.c - 664 sys sys 1131289382 21910
+1131289302 24 c sys/src/libmach/v.c - 664 sys sys 1131289378 3446
+1131289302 25 c sys/src/libmach/vcodas.c - 664 sys sys 1131289385 10258
+1131289302 26 c sys/src/libmach/vdb.c - 664 sys sys 1131289381 22264
+1131291103 0 c 386/lib/libmach.a - 664 sys sys 1131289375 784878
+1131291103 1 c sys/lib/acid/leak - 664 sys sys 1131289472 2363
+1131291103 2 c sys/src/9/alphapc/apc - 664 sys sys 1131289706 630
+1131291103 3 c sys/src/9/alphapc/dat.h - 664 sys sys 1131289707 5196
+1131291103 4 c sys/src/9/alphapc/devvga.c - 664 sys sys 1131289707 7420
+1131291103 5 c sys/src/9/alphapc/fns.h - 664 sys sys 1131289707 3613
+1131291103 6 c sys/src/9/alphapc/main.c - 664 sys sys 1131289707 13672
+1131291103 7 c sys/src/9/alphapc/mmu.c - 664 sys sys 1131289708 4945
+1131291103 8 c sys/src/9/alphapc/screen.h - 664 sys sys 1131289708 3818
+1131291103 9 c sys/src/9/alphapc/sd53c8xx.c - 664 sys sys 1131289709 50963
+1131291103 10 c sys/src/9/bitsy/dat.h - 664 sys sys 1131289775 5829
+1131291103 11 c sys/src/9/bitsy/devpenmouse.c - 664 sys sys 1131289775 9589
+1131291103 12 c sys/src/9/bitsy/main.c - 664 sys sys 1131289775 8816
+1131291103 13 c sys/src/9/bitsy/mkfile - 664 sys sys 1131289775 2459
+1131291103 14 c sys/src/9/bitsy/sdata.c - 664 sys sys 1131289776 44404
+1131291103 15 c sys/src/9/boot/bootauth.c - 664 sys sys 1131289783 1160
+1131291103 16 c sys/src/9/mtx/dat.h - 664 sys sys 1131289814 3843
+1131291103 17 c sys/src/9/mtx/main.c - 664 sys sys 1131289814 8307
+1131291103 18 c sys/src/9/pc/apic.c - 664 sys sys 1131290206 8748
+1131291103 19 c sys/src/9/pc/apm.c - 664 sys sys 1131290210 3723
+1131291103 20 c sys/src/9/pc/archmp.c - 664 sys sys 1131290214 2357
+1131291103 21 c sys/src/9/pc/dat.h - 664 sys sys 1131290217 6462
+1131291103 22 c sys/src/9/pc/devarch.c - 664 sys sys 1131290259 18594
+1131291103 23 c sys/src/9/pc/devether.c - 664 sys sys 1131290265 10315
+1131291103 24 c sys/src/9/pc/devpccard.c - 664 sys sys 1131290281 40203
+1131291103 25 c sys/src/9/pc/devtv.c - 664 sys sys 1131290299 45676
+1131291103 26 c sys/src/9/pc/devvga.c - 664 sys sys 1131290315 9332
+1131291103 27 c sys/src/9/pc/dma.c - 664 sys sys 1131290319 4715
+1131291103 28 c sys/src/9/pc/ether79c970.c - 664 sys sys 1131290338 13953
+1131291103 29 c sys/src/9/pc/ether8139.c - 664 sys sys 1131290376 18400
+1131291103 30 c sys/src/9/pc/ether82543gc.c - 664 sys sys 1131290377 32294
+1131291103 31 c sys/src/9/pc/ether82557.c - 664 sys sys 1131290377 30107
+1131291103 32 c sys/src/9/pc/ether8390.c - 664 sys sys 1131290377 17702
+1131291103 33 c sys/src/9/pc/etherelnk3.c - 664 sys sys 1131290378 48733
+1131291103 34 c sys/src/9/pc/etherigbe.c - 664 sys sys 1131290379 44431
+1131291103 35 c sys/src/9/pc/etherwavelan.c - 664 sys sys 1131290380 3747
+1131291103 36 c sys/src/9/pc/fns.h - 664 sys sys 1131290383 4461
+1131291103 37 c sys/src/9/pc/i8259.c - 664 sys sys 1131290399 4586
+1131291103 38 c sys/src/9/pc/l.s - 664 sys sys 1131290403 28347
+1131291103 39 c sys/src/9/pc/main.c - 664 sys sys 1131290418 15224
+1131291103 40 c sys/src/9/pc/mem.h - 664 sys sys 1131290422 5209
+1131291103 41 c sys/src/9/pc/memory.c - 664 sys sys 1131290429 18222
+1131291103 42 c sys/src/9/pc/mmu.c - 664 sys sys 1131290443 19717
+1131291103 43 c sys/src/9/pc/mp.c - 664 sys sys 1131290473 17089
+1131291103 44 c sys/src/9/pc/mp.h - 664 sys sys 1131290475 6638
+1131291103 45 c sys/src/9/pc/pc - 664 sys sys 1131290481 1427
+1131291103 46 c sys/src/9/pc/pcauth - 664 sys sys 1131290482 714
+1131291103 47 c sys/src/9/pc/pccpu - 664 sys sys 1131290488 866
+1131291103 48 c sys/src/9/pc/pcdisk - 664 sys sys 1131290495 1437
+1131291103 49 c sys/src/9/pc/pcf - 664 sys sys 1131290500 1495
+1131291103 50 c sys/src/9/pc/pci.c - 664 sys sys 1131290505 26817
+1131291103 51 c sys/src/9/pc/screen.c - 664 sys sys 1131290512 13460
+1131291103 52 c sys/src/9/pc/screen.h - 664 sys sys 1131290516 4156
+1131291103 53 c sys/src/9/pc/sd53c8xx.c - 664 sys sys 1131290539 55206
+1131291103 54 c sys/src/9/pc/sd53c8xx.n - 664 sys sys 1131290556 12657
+1131291103 55 c sys/src/9/pc/sdata.c - 664 sys sys 1131290578 52168
+1131291103 56 c sys/src/9/pc/sdmylex.c - 664 sys sys 1131290583 27737
+1131291103 57 c sys/src/9/pc/trap.c - 664 sys sys 1131290591 21164
+1131291103 58 c sys/src/9/pc/vgai81x.c - 664 sys sys 1131290601 4030
+1131291103 59 a sys/src/9/pc/vgavesa.c - 664 sys sys 1131290603 2369
+1131291103 60 c sys/src/9/pc/devlml.c - 664 sys sys 1131290276 7505
+1131291103 61 c sys/src/9/pc/ether8169.c - 664 sys sys 1131290377 22723
+1131291103 62 c sys/src/9/pc/etherdp83820.c - 664 sys sys 1131290378 29128
+1131291103 63 c sys/src/9/pc/etherga620.c - 664 sys sys 1131290379 28748
+1131291103 64 c sys/src/9/pc/ethervt6102.c - 664 sys sys 1131290379 22572
+1131291103 65 c sys/src/9/pc/pccd - 664 sys sys 1131290486 1418
+1131291103 66 c sys/src/9/pc/pccpuf - 664 sys sys 1131290495 1477
+1131291103 67 c sys/src/9/pc/pcflop - 664 sys sys 1131290502 1464
+1131291103 68 a sys/src/9/pc/sdmv50xx.c - 664 sys sys 1131290638 25780
+1131291103 69 c sys/src/9/pc/vga.c - 664 sys sys 1131290595 5148
+1131291103 70 c sys/src/9/pc/vga3dfx.c - 664 sys sys 1131290600 3833
+1131291103 71 c sys/src/9/pc/vgaark2000pv.c - 664 sys sys 1131290600 3422
+1131291103 72 c sys/src/9/pc/vgabt485.c - 664 sys sys 1131290600 5057
+1131291103 73 c sys/src/9/pc/vgaclgd542x.c - 664 sys sys 1131290600 4550
+1131291103 74 c sys/src/9/pc/vgaclgd546x.c - 664 sys sys 1131290600 3716
+1131291103 75 c sys/src/9/pc/vgact65545.c - 664 sys sys 1131290600 2249
+1131291103 76 c sys/src/9/pc/vgacyber938x.c - 664 sys sys 1131290601 3707
+1131291103 77 c sys/src/9/pc/vgaet4000.c - 664 sys sys 1131290601 5111
+1131291103 78 c sys/src/9/pc/vgahiqvideo.c - 664 sys sys 1131290601 4098
+1131291103 79 c sys/src/9/pc/vgamach64xx.c - 664 sys sys 1131290601 28257
+1131291103 80 c sys/src/9/pc/vgamga2164w.c - 664 sys sys 1131290602 4637
+1131291103 81 c sys/src/9/pc/vgamga4xx.c - 664 sys sys 1131290602 10201
+1131291103 82 c sys/src/9/pc/vganeomagic.c - 664 sys sys 1131290602 10143
+1131291103 83 c sys/src/9/pc/vganvidia.c - 664 sys sys 1131290602 11783
+1131291103 84 c sys/src/9/pc/vgargb524.c - 664 sys sys 1131290602 4251
+1131291103 85 c sys/src/9/pc/vgas3.c - 664 sys sys 1131290603 10994
+1131291103 86 c sys/src/9/pc/vgat2r4.c - 664 sys sys 1131290603 9351
+1131291103 87 c sys/src/9/pc/vgatvp3020.c - 664 sys sys 1131290603 4507
+1131291103 88 c sys/src/9/pc/vgatvp3026.c - 664 sys sys 1131290603 3956
+1131291103 89 c sys/src/9/pc/vgavmware.c - 664 sys sys 1131290604 5840
+1131291103 90 c sys/src/9/pc/vgax.c - 664 sys sys 1131290604 1671
+1131291103 91 c sys/src/9/port/dev.c - 664 sys sys 1131289870 8219
+1131291103 92 c sys/src/9/port/devdraw.c - 664 sys sys 1131289870 43537
+1131291103 93 c sys/src/9/port/devproc.c - 664 sys sys 1131289878 28233
+1131291103 94 c sys/src/9/port/devsd.c - 664 sys sys 1131289885 30798
+1131291103 95 c sys/src/9/port/devsegment.c - 664 sys sys 1131289891 9610
+1131291103 96 c sys/src/9/port/fault.c - 664 sys sys 1131289901 7271
+1131291103 97 c sys/src/9/port/lib.h - 664 sys sys 1131289913 6040
+1131291103 98 c sys/src/9/port/master - 664 sys sys 1131289934 510
+1131291103 99 c sys/src/9/port/page.c - 664 sys sys 1131289949 8449
+1131291103 100 c sys/src/9/port/portdat.h - 664 sys sys 1131289971 22628
+1131291103 101 c sys/src/9/port/portfns.h - 664 sys sys 1131289972 10925
+1131291103 102 c sys/src/9/port/proc.c - 664 sys sys 1131289980 28264
+1131291103 103 c sys/src/9/port/sd.h - 664 sys sys 1131289990 2494
+1131291103 104 c sys/src/9/port/segment.c - 664 sys sys 1131290022 13720
+1131291103 105 c sys/src/9/port/taslock.c - 664 sys sys 1131290039 3928
+1131291103 106 c sys/src/9/port/xalloc.c - 664 sys sys 1131290051 4063
+1131291103 107 c sys/src/9/ppc/clock.c - 664 sys sys 1131290066 1076
+1131291103 108 c sys/src/9/ppc/devether.c - 664 sys sys 1131290184 9327
+1131291103 109 c sys/src/9/ppc/etherfcc.c - 664 sys sys 1131290110 19599
+1131291103 110 c sys/src/9/ppc/main.c - 664 sys sys 1131290117 9075
+1131291103 111 c sys/src/9/ppc/trap.c - 664 sys sys 1131290140 17067
+1131291103 112 c sys/src/9/ppc/uartsmc.c - 664 sys sys 1131290162 9764
+1131291103 113 c sys/src/cmd/acid/acid.h - 664 sys sys 1131289460 4273
+1131291103 114 c sys/src/cmd/acid/builtin.c - 664 sys sys 1131289462 20193
+1131291103 115 c sys/src/cmd/acid/dbg.y - 664 sys sys 1131289463 5568
+1131291103 116 c sys/src/cmd/acid/dot.c - 664 sys sys 1131289462 2162
+1131291103 117 c sys/src/cmd/acid/exec.c - 664 sys sys 1131289461 8383
+1131291103 118 c sys/src/cmd/acid/expr.c - 664 sys sys 1131289461 15220
+1131291103 119 c sys/src/cmd/acid/lex.c - 664 sys sys 1131289460 7963
+1131291103 120 c sys/src/cmd/acid/list.c - 664 sys sys 1131289462 3680
+1131291103 121 c sys/src/cmd/acid/main.c - 664 sys sys 1131289460 8565
+1131291103 122 c sys/src/cmd/acid/print.c - 664 sys sys 1131289462 6831
+1131291103 123 c sys/src/cmd/acid/proc.c - 664 sys sys 1131289462 4356
+1131291103 124 c sys/src/cmd/acid/util.c - 664 sys sys 1131289461 4609
+1131291103 125 c sys/src/cmd/auth/factotum/fs.c - 664 sys sys 1131289797 10524
+1131291103 126 c sys/src/cmd/auth/factotum/util.c - 664 sys sys 1131289797 18035
+1131291103 127 c sys/src/cmd/mk/arc.c - 664 sys sys 1131289508 826
+1131291103 128 c sys/src/cmd/mk/archive.c - 664 sys sys 1131289509 3071
+1131291103 129 c sys/src/cmd/mk/env.c - 664 sys sys 1131289509 2281
+1131291103 130 c sys/src/cmd/mk/file.c - 664 sys sys 1131289509 1299
+1131291103 131 c sys/src/cmd/mk/graph.c - 664 sys sys 1131289509 5822
+1131291103 132 c sys/src/cmd/mk/mk.c - 664 sys sys 1131289509 5330
+1131291103 133 c sys/src/cmd/mk/mk.h - 664 sys sys 1131289508 3765
+1131291103 134 c sys/src/cmd/mk/plan9.c - 664 sys sys 1131289511 6941
+1131291103 135 c sys/src/cmd/mk/recipe.c - 664 sys sys 1131289510 2543
+1131291103 136 c sys/src/cmd/mk/rule.c - 664 sys sys 1131289510 1946
+1131291103 137 c sys/src/cmd/mk/run.c - 664 sys sys 1131289510 5063
+1131291103 138 c sys/src/cmd/mk/symtab.c - 664 sys sys 1131289510 1581
+1131291103 139 c sys/src/cmd/mk/var.c - 664 sys sys 1131289510 530
+1131291103 140 c sys/src/cmd/mk/varsub.c - 664 sys sys 1131289511 4425
+1131291103 141 c sys/src/cmd/rdbfs.c - 664 sys sys 1131289483 7964
+1131291103 142 d sys/src/9/pc/sd53c8xx.i - 664 sys sys 1045063730 0
+1131291103 143 d sys/src/9/pc/reboot.h - 664 sys sys 1015014522 0
+1131292903 0 c sys/src/cmd/db/command.c - 664 sys sys 1131292957 4376
+1131292903 1 c sys/src/cmd/db/defs.h - 664 sys sys 1131292957 1700
+1131292903 2 c sys/src/cmd/db/expr.c - 664 sys sys 1131292957 5441
+1131292903 3 c sys/src/cmd/db/fns.h - 664 sys sys 1131292957 2078
+1131292903 4 c sys/src/cmd/db/format.c - 664 sys sys 1131292958 6874
+1131292903 5 c sys/src/cmd/db/print.c - 664 sys sys 1131292958 5959
+1131292903 6 c sys/src/cmd/db/regs.c - 664 sys sys 1131292958 1993
+1131292903 7 c sys/src/cmd/db/trcrun.c - 664 sys sys 1131292958 4434
+1131292903 8 c sys/src/cmd/vi/mips.h - 664 sys sys 1131292943 4837
+1131292903 9 c sys/src/cmd/nm.c - 664 sys sys 1131292928 4914
+1131292903 10 c sys/src/libmach/elf.h - 664 sys sys 1131292881 2301
+1131292903 11 c sys/src/libmach/obj.h - 664 sys sys 1131292890 604
+1131294703 0 c sys/include/a.out.h - 664 sys sys 1131293220 1407
+1131294703 1 c sys/man/1/strip - 664 sys sys 1131293239 523
+1131294703 2 c sys/man/4/factotum - 664 sys sys 1131294573 14841
+1131294703 3 c sys/man/8/plan9.ini - 664 sys sys 1131294569 22077
+1131294703 4 c sys/src/9/pc/apbootstrap.s - 664 sys sys 1131293655 3037
+1131294703 5 c sys/src/9/pc/sdscsi.c - 664 sys sys 1131293342 7133
+1131294703 6 a sys/src/9/pc/realmode.c - 664 sys sys 1131294602 2658
+1131294703 7 c sys/src/9/port/sysproc.c - 664 sys sys 1131293739 15150
+1131294703 8 c sys/src/cmd/9nfs/listalloc.c - 664 sys sys 1131293679 275
+1131294703 9 c sys/src/cmd/9nfs/nfs.c - 664 sys sys 1131293679 9526
+1131294703 10 c sys/src/cmd/9nfs/xfile.c - 664 sys sys 1131293680 1894
+1131294703 11 c sys/src/cmd/cc/lex.c - 664 sys sys 1131293446 23883
+1131294703 12 c sys/src/cmd/cc/lexbody - 664 sys sys 1131293457 9188
+1131294703 13 c sys/src/cmd/ktrace.c - 664 sys sys 1131293224 5885
+1131294703 14 c sys/src/cmd/tbl/t6.c - 664 sys sys 1131293512 7295
+1131294703 15 c sys/src/cmd/tbl/t8.c - 664 sys sys 1131293517 9041
+1131294703 16 c sys/src/cmd/tbl/tc.c - 664 sys sys 1131293494 1274
+1131294703 17 c sys/src/cmd/upas/smtp/mxdial.c - 664 sys sys 1131293478 6420
+1131294703 18 c sys/src/cmd/ar.c - 664 sys sys 1131293258 23778
+1131294703 19 c sys/src/cmd/strip.c - 664 sys sys 1131293244 2502
+1131294703 20 c sys/src/games/music/playlistfs/boilerplate.c - 664 sys sys 1131293384 1547
+1131296504 0 c sys/src/9/pc/mkfile - 664 sys sys 1131294850 3580
+1131298304 0 c 386/bin/8c - 775 sys sys 1131296671 358395
+1131298304 1 c 386/bin/acid - 775 sys sys 1131296672 400034
+1131298304 2 c 386/bin/ar - 775 sys sys 1131296672 111983
+1131298304 3 c 386/bin/file - 775 sys sys 1131296674 121021
+1131298304 4 c 386/bin/kprof - 775 sys sys 1131296675 105507
+1131298304 5 c 386/bin/ktrace - 775 sys sys 1131296675 121949
+1131298304 6 c 386/bin/nm - 775 sys sys 1131296675 125784
+1131298304 7 c 386/bin/prof - 775 sys sys 1131296676 110924
+1131298304 8 c 386/bin/size - 775 sys sys 1131296676 78794
+1131298304 9 c 386/bin/strip - 775 sys sys 1131296676 80766
+1131298304 10 c 386/bin/auth/factotum - 775 sys sys 1131296673 313125
+1131298304 11 c 386/bin/aux/ms2 - 775 sys sys 1131296673 87464
+1131298304 12 c 386/bin/aux/nfsserver - 775 sys sys 1131296673 185439
+1131298304 13 c 386/bin/aux/pcnfsd - 775 sys sys 1131296674 129365
+1131298304 14 c 386/bin/aux/portmapper - 775 sys sys 1131296674 128251
+1131298304 15 c 386/bin/tprof - 775 sys sys 1131296677 297344
+1131298304 16 c 386/lib/libmach.a - 664 sys sys 1131296679 782950
+1131298304 17 c sys/src/cmd/db/command.c - 664 sys sys 1131297926 4377
+1131298304 18 c sys/src/cmd/db/fns.h - 664 sys sys 1131297926 2014
+1131298304 19 c sys/src/cmd/db/format.c - 664 sys sys 1131297926 6868
+1131298304 20 c sys/src/cmd/db/print.c - 664 sys sys 1131297926 5949
+1131298304 21 c sys/src/cmd/db/regs.c - 664 sys sys 1131297926 1998
+1131298304 22 c sys/src/cmd/db/trcrun.c - 664 sys sys 1131297926 4433
+1131298818 0 c sys/src/9/port/chan.c - 664 sys sys 1131298713 33663
+1131298818 1 c sys/src/9/port/segment.c - 664 sys sys 1131298540 13722
+1131298818 2 c sys/src/9/port/sysproc.c - 664 sys sys 1131298541 15159
+1131300105 0 c sys/src/9/pc/pcdisk - 664 sys sys 1131299995 1446
+1131300105 1 c sys/src/9/pc/pcf - 664 sys sys 1131299996 1504
+1131300105 2 c sys/src/9/pc/pccpuf - 664 sys sys 1131299996 1486
+1131300105 3 c sys/src/9/pc/pcflop - 664 sys sys 1131299996 1473
+1131301905 0 c sys/man/3/vga - 664 sys sys 1131301005 4957
+1131301905 1 c sys/man/8/vga - 664 sys sys 1131301001 3864
+1131303706 0 c 386/bin/db - 775 sys sys 1131302428 345503
+1131303706 1 c 386/bin/snap - 775 sys sys 1131302429 310917
+1131303706 2 c 386/bin/snapfs - 775 sys sys 1131302430 380175
+1131303706 3 c 386/bin/mk - 775 sys sys 1131302428 144690
+1131303706 4 c 386/bin/tbl - 775 sys sys 1131302431 113308
+1131307305 0 c sys/src/9/pc/trap.c - 664 sys sys 1131306249 21180
+1131318109 0 c 386/9load - 775 sys sys 1131317303 216948
+1131318109 1 c 386/9loaddebug - 775 sys sys 1131317308 311884
+1131318109 2 c 386/9loadlite - 775 sys sys 1131317306 135668
+1131318109 3 c 386/9loadlitedebug - 775 sys sys 1131317312 200131
+1131318109 4 c 386/9pc - 775 sys sys 1131317330 1881476
+1131318109 5 c 386/9pc.gz - 664 sys sys 1131317332 658770
+1131318109 6 c 386/9pccpu - 775 sys sys 1131317349 1555752
+1131318109 7 c 386/9pccpu.gz - 664 sys sys 1131317351 552557
+1131318109 8 c 386/9pcdisk - 775 sys sys 1131317356 2072467
+1131318109 9 c 386/9pcdisk.gz - 664 sys sys 1131317358 746873
+1131318109 10 c 386/9pcf - 775 sys sys 1131317362 2415556
+1131318109 11 c 386/9pcf.gz - 664 sys sys 1131317364 900937
+1131318109 12 c 386/9pxeload - 775 sys sys 1131317321 216948
+1131318109 13 c 386/init - 775 sys sys 1131317332 101212
+1131318109 14 c 386/ld.com - 775 sys sys 1131317344 72524
+1131318109 15 c 386/mbr - 775 sys sys 1131317338 407
+1131318109 16 c 386/pbs - 775 sys sys 1131317339 494
+1131318109 17 c 386/pbslba - 775 sys sys 1131317342 507
+1131318109 18 c sys/man/8/statusbar - 664 sys sys 1131317865 1251
+1131326298 0 c sys/src/9/pc/mmu.c - 664 sys sys 1131326224 19739
+1131326298 1 c sys/src/9/pc/mp.c - 664 sys sys 1131326235 17157
+1131327235 0 c 386/9pc - 775 sys sys 1131327135 1881573
+1131327235 1 c 386/9pc.gz - 664 sys sys 1131327137 658788
+1131327235 2 c 386/9pccpu - 775 sys sys 1131327140 1555849
+1131327235 3 c 386/9pccpu.gz - 664 sys sys 1131327141 552578
+1131327235 4 c 386/9pcdisk - 775 sys sys 1131327146 2072564
+1131327235 5 c 386/9pcdisk.gz - 664 sys sys 1131327148 746868
+1131327235 6 c 386/9pcf - 775 sys sys 1131327153 2415653
+1131327235 7 c 386/9pcf.gz - 664 sys sys 1131327156 900998

+ 22 - 19
sys/include/a.out.h

@@ -11,31 +11,34 @@ struct	Exec
 	long	pcsz;		/* size of pc/line number table */
 	long	pcsz;		/* size of pc/line number table */
 };
 };
 
 
-#define	_MAGIC(b)	((((4*b)+0)*b)+7)
-#define	A_MAGIC		_MAGIC(8)	/* 68020 */
-#define	I_MAGIC		_MAGIC(11)	/* intel 386 */
-#define	J_MAGIC		_MAGIC(12)	/* intel 960 (retired) */
-#define	K_MAGIC		_MAGIC(13)	/* sparc */
-#define	V_MAGIC		_MAGIC(16)	/* mips 3000 BE */
-#define	X_MAGIC		_MAGIC(17)	/* att dsp 3210 (retired) */
-#define	M_MAGIC		_MAGIC(18)	/* mips 4000 BE */
-#define	D_MAGIC		_MAGIC(19)	/* amd 29000 (retired) */
-#define	E_MAGIC		_MAGIC(20)	/* arm */
-#define	Q_MAGIC		_MAGIC(21)	/* powerpc */
-#define	N_MAGIC		_MAGIC(22)	/* mips 4000 LE */
-#define	L_MAGIC		_MAGIC(23)	/* dec alpha */
-#define	P_MAGIC		_MAGIC(24)	/* mips 3000 LE */
-#define	U_MAGIC		_MAGIC(25)	/* sparc64 */
-#define	S_MAGIC		_MAGIC(26)	/* amd64 */
+#define HDR_MAGIC	0x00008000		/* header expansion */
+
+#define	_MAGIC(f, b)	((f)|((((4*(b))+0)*(b))+7))
+#define	A_MAGIC		_MAGIC(0, 8)		/* 68020 */
+#define	I_MAGIC		_MAGIC(0, 11)		/* intel 386 */
+#define	J_MAGIC		_MAGIC(0, 12)		/* intel 960 (retired) */
+#define	K_MAGIC		_MAGIC(0, 13)		/* sparc */
+#define	V_MAGIC		_MAGIC(0, 16)		/* mips 3000 BE */
+#define	X_MAGIC		_MAGIC(0, 17)		/* att dsp 3210 (retired) */
+#define	M_MAGIC		_MAGIC(0, 18)		/* mips 4000 BE */
+#define	D_MAGIC		_MAGIC(0, 19)		/* amd 29000 (retired) */
+#define	E_MAGIC		_MAGIC(0, 20)		/* arm */
+#define	Q_MAGIC		_MAGIC(0, 21)		/* powerpc */
+#define	N_MAGIC		_MAGIC(0, 22)		/* mips 4000 LE */
+#define	L_MAGIC		_MAGIC(0, 23)		/* dec alpha */
+#define	P_MAGIC		_MAGIC(0, 24)		/* mips 3000 LE */
+#define	U_MAGIC		_MAGIC(0, 25)		/* sparc64 */
+#define	S_MAGIC		_MAGIC(HDR_MAGIC, 26)	/* amd64 */
+
 #define	MIN_MAGIC	8
 #define	MIN_MAGIC	8
-#define	MAX_MAGIC	26
+#define	MAX_MAGIC	26			/* <= 90 */
 
 
-#define	DYN_MAGIC	0x80000000	/* or'd in for dynamically loaded modules */
+#define	DYN_MAGIC	0x80000000		/* dlm */
 
 
 typedef	struct	Sym	Sym;
 typedef	struct	Sym	Sym;
 struct	Sym
 struct	Sym
 {
 {
-	long	value;
+	vlong	value;
 	char	type;
 	char	type;
 	char	*name;
 	char	*name;
 };
 };

+ 59 - 55
sys/include/mach.h

@@ -119,9 +119,9 @@ struct Map {
 		int	fd;		/* file descriptor */
 		int	fd;		/* file descriptor */
 		int	inuse;		/* in use - not in use */
 		int	inuse;		/* in use - not in use */
 		int	cache;		/* should cache reads? */
 		int	cache;		/* should cache reads? */
-		ulong	b;		/* base */
-		ulong	e;		/* end */
-		ulong	f;		/* offset within file */
+		uvlong	b;		/* base */
+		uvlong	e;		/* end */
+		vlong	f;		/* offset within file */
 	} seg[1];			/* actually n of these */
 	} seg[1];			/* actually n of these */
 };
 };
 
 
@@ -169,8 +169,8 @@ struct Mach{
 	char	*name;
 	char	*name;
 	int	mtype;			/* machine type code */
 	int	mtype;			/* machine type code */
 	Reglist *reglist;		/* register set */
 	Reglist *reglist;		/* register set */
-	ulong	regsize;		/* sizeof registers in bytes*/
-	ulong	fpregsize;		/* sizeof fp registers in bytes*/
+	long	regsize;		/* sizeof registers in bytes */
+	long	fpregsize;		/* sizeof fp registers in bytes */
 	char	*pc;			/* pc name */
 	char	*pc;			/* pc name */
 	char	*sp;			/* sp name */
 	char	*sp;			/* sp name */
 	char	*link;			/* link register name */
 	char	*link;			/* link register name */
@@ -179,6 +179,7 @@ struct Mach{
 	int	pgsize;			/* page size */
 	int	pgsize;			/* page size */
 	uvlong	kbase;			/* kernel base address */
 	uvlong	kbase;			/* kernel base address */
 	uvlong	ktmask;			/* ktzero = kbase & ~ktmask */
 	uvlong	ktmask;			/* ktzero = kbase & ~ktmask */
+	uvlong	utop;			/* user stack top */
 	int	pcquant;		/* quantization of pc */
 	int	pcquant;		/* quantization of pc */
 	int	szaddr;			/* sizeof(void*) */
 	int	szaddr;			/* sizeof(void*) */
 	int	szreg;			/* sizeof(register) */
 	int	szreg;			/* sizeof(register) */
@@ -188,26 +189,26 @@ struct Mach{
 
 
 extern	Mach	*mach;			/* Current machine */
 extern	Mach	*mach;			/* Current machine */
 
 
-typedef vlong	(*Rgetter)(Map*, char*);
-typedef	void	(*Tracer)(Map*, ulong, ulong, Symbol*);
+typedef uvlong	(*Rgetter)(Map*, char*);
+typedef	void	(*Tracer)(Map*, uvlong, uvlong, Symbol*);
 
 
 struct	Machdata {		/* Machine-dependent debugger support */
 struct	Machdata {		/* Machine-dependent debugger support */
 	uchar	bpinst[4];			/* break point instr. */
 	uchar	bpinst[4];			/* break point instr. */
 	short	bpsize;				/* size of break point instr. */
 	short	bpsize;				/* size of break point instr. */
 
 
-	ushort	(*swab)(ushort);		/* short to local byte order */
-	long	(*swal)(long);			/* long to local byte order */
-	vlong	(*swav)(vlong);			/* vlong to local byte order */
-	int	(*ctrace)(Map*, ulong, ulong, ulong, Tracer); /* C traceback */
-	ulong	(*findframe)(Map*, ulong, ulong, ulong, ulong);/* frame finder */
+	ushort	(*swab)(ushort);		/* ushort to local byte order */
+	ulong	(*swal)(ulong);			/* ulong to local byte order */
+	uvlong	(*swav)(uvlong);		/* uvlong to local byte order */
+	int	(*ctrace)(Map*, uvlong, uvlong, uvlong, Tracer); /* C traceback */
+	uvlong	(*findframe)(Map*, uvlong, uvlong, uvlong, uvlong);/* frame finder */
 	char*	(*excep)(Map*, Rgetter);	/* last exception */
 	char*	(*excep)(Map*, Rgetter);	/* last exception */
-	ulong	(*bpfix)(ulong);		/* breakpoint fixup */
+	ulong	(*bpfix)(uvlong);		/* breakpoint fixup */
 	int	(*sftos)(char*, int, void*);	/* single precision float */
 	int	(*sftos)(char*, int, void*);	/* single precision float */
 	int	(*dftos)(char*, int, void*);	/* double precision float */
 	int	(*dftos)(char*, int, void*);	/* double precision float */
-	int	(*foll)(Map*, ulong, Rgetter, ulong*);	/* follow set */
-	int	(*das)(Map*, ulong, char, char*, int);	/* symbolic disassembly */
-	int	(*hexinst)(Map*, ulong, char*, int); 	/* hex disassembly */
-	int	(*instsize)(Map*, ulong);	/* instruction size */
+	int	(*foll)(Map*, uvlong, Rgetter, uvlong*);/* follow set */
+	int	(*das)(Map*, uvlong, char, char*, int);	/* symbolic disassembly */
+	int	(*hexinst)(Map*, uvlong, char*, int); 	/* hex disassembly */
+	int	(*instsize)(Map*, uvlong);	/* instruction size */
 };
 };
 
 
 /*
 /*
@@ -216,23 +217,24 @@ struct	Machdata {		/* Machine-dependent debugger support */
 typedef struct Fhdr
 typedef struct Fhdr
 {
 {
 	char	*name;		/* identifier of executable */
 	char	*name;		/* identifier of executable */
-	short	type;		/* file type - see codes above*/
-	short	hdrsz;		/* size of this header */
+	uchar	type;		/* file type - see codes above*/
+	uchar	hdrsz;		/* header size */
+	uchar	spare[2];
 	long	magic;		/* magic number */
 	long	magic;		/* magic number */
-	long	txtaddr;	/* text address */
-	long	entry;		/* entry point */
+	uvlong	txtaddr;	/* text address */
+	vlong	txtoff;		/* start of text in file */
+	uvlong	dataddr;	/* start of data segment */
+	vlong	datoff;		/* offset to data seg in file */
+	vlong	symoff;		/* offset of symbol table in file */
+	uvlong	entry;		/* entry point */
+	vlong	sppcoff;	/* offset of sp-pc table in file */
+	vlong	lnpcoff;	/* offset of line number-pc table in file */
 	long	txtsz;		/* text size */
 	long	txtsz;		/* text size */
-	long	txtoff;		/* start of text in file */
-	long	dataddr;	/* start of data segment */
 	long	datsz;		/* size of data seg */
 	long	datsz;		/* size of data seg */
-	long	datoff;		/* offset to data seg in file */
 	long	bsssz;		/* size of bss */
 	long	bsssz;		/* size of bss */
 	long	symsz;		/* size of symbol table */
 	long	symsz;		/* size of symbol table */
-	long	symoff;		/* offset of symbol table in file */
 	long	sppcsz;		/* size of sp-pc table */
 	long	sppcsz;		/* size of sp-pc table */
-	long	sppcoff;	/* offset of sp-pc table in file */
 	long	lnpcsz;		/* size of line number-pc table */
 	long	lnpcsz;		/* size of line number-pc table */
-	long	lnpcoff;	/* size of line number-pc table */
 } Fhdr;
 } Fhdr;
 
 
 extern	int	asstype;	/* dissembler type - machdata.c */
 extern	int	asstype;	/* dissembler type - machdata.c */
@@ -243,24 +245,25 @@ int		beieee80ftos(char*, int, void*);
 int		beieeesftos(char*, int, void*);
 int		beieeesftos(char*, int, void*);
 int		beieeedftos(char*, int, void*);
 int		beieeedftos(char*, int, void*);
 ushort		beswab(ushort);
 ushort		beswab(ushort);
-long		beswal(long);
-vlong		beswav(vlong);
-int		cisctrace(Map*, ulong, ulong, ulong, Tracer);
-ulong		ciscframe(Map*, ulong, ulong, ulong, ulong);
+ulong		beswal(ulong);
+uvlong		beswav(uvlong);
+uvlong		ciscframe(Map*, uvlong, uvlong, uvlong, uvlong);
+int		cisctrace(Map*, uvlong, uvlong, uvlong, Tracer);
 int		crackhdr(int fd, Fhdr*);
 int		crackhdr(int fd, Fhdr*);
-long		file2pc(char*, ulong);
+uvlong		file2pc(char*, long);
 int		fileelem(Sym**, uchar *, char*, int);
 int		fileelem(Sym**, uchar *, char*, int);
-int		fileline(char*, int, ulong);
+long		fileline(char*, int, uvlong);
 int		filesym(int, char*, int);
 int		filesym(int, char*, int);
 int		findlocal(Symbol*, char*, Symbol*);
 int		findlocal(Symbol*, char*, Symbol*);
 int		findseg(Map*, char*);
 int		findseg(Map*, char*);
-int		findsym(long, int, Symbol *);
-int		fnbound(long, ulong*);
+int		findsym(uvlong, int, Symbol *);
+int		fnbound(uvlong, uvlong*);
 int		fpformat(Map*, Reglist*, char*, int, int);
 int		fpformat(Map*, Reglist*, char*, int, int);
-int		get1(Map*, ulong, uchar*, int);
-int		get2(Map*, ulong, ushort*);
-int		get4(Map*, ulong, long*);
-int		get8(Map*, ulong, vlong*);
+int		get1(Map*, uvlong, uchar*, int);
+int		get2(Map*, uvlong, ushort*);
+int		get4(Map*, uvlong, ulong*);
+int		get8(Map*, uvlong, uvlong*);
+int		geta(Map*, uvlong, uvlong*);
 int		getauto(Symbol*, int, int, Symbol*);
 int		getauto(Symbol*, int, int, Symbol*);
 Sym*		getsym(int);
 Sym*		getsym(int);
 int		globalsym(Symbol *, int);
 int		globalsym(Symbol *, int);
@@ -272,11 +275,11 @@ int		leieee80ftos(char*, int, void*);
 int		leieeesftos(char*, int, void*);
 int		leieeesftos(char*, int, void*);
 int		leieeedftos(char*, int, void*);
 int		leieeedftos(char*, int, void*);
 ushort		leswab(ushort);
 ushort		leswab(ushort);
-long		leswal(long);
-vlong		leswav(vlong);
-long		line2addr(ulong, ulong, ulong);
+ulong		leswal(ulong);
+uvlong		leswav(uvlong);
+uvlong		line2addr(long, uvlong, uvlong);
 Map*		loadmap(Map*, int, Fhdr*);
 Map*		loadmap(Map*, int, Fhdr*);
-int		localaddr(Map*, char*, char*, long*, Rgetter);
+int		localaddr(Map*, char*, char*, uvlong*, Rgetter);
 int		localsym(Symbol*, int);
 int		localsym(Symbol*, int);
 int		lookup(char*, char*, Symbol*);
 int		lookup(char*, char*, Symbol*);
 void		machbytype(int);
 void		machbytype(int);
@@ -285,20 +288,21 @@ int		nextar(Biobuf*, int, char*);
 Map*		newmap(Map*, int);
 Map*		newmap(Map*, int);
 void		objtraverse(void(*)(Sym*, void*), void*);
 void		objtraverse(void(*)(Sym*, void*), void*);
 int		objtype(Biobuf*, char**);
 int		objtype(Biobuf*, char**);
-long		pc2sp(ulong);
-long		pc2line(ulong);
-int		put1(Map*, ulong, uchar*, int);
-int		put2(Map*, ulong, ushort);
-int		put4(Map*, ulong, long);
-int		put8(Map*, ulong, vlong);
-int		readar(Biobuf*, int, int, int);
+uvlong		pc2sp(uvlong);
+long		pc2line(uvlong);
+int		put1(Map*, uvlong, uchar*, int);
+int		put2(Map*, uvlong, ushort);
+int		put4(Map*, uvlong, ulong);
+int		put8(Map*, uvlong, uvlong);
+int		puta(Map*, uvlong, uvlong);
+int		readar(Biobuf*, int, vlong, int);
 int		readobj(Biobuf*, int);
 int		readobj(Biobuf*, int);
-ulong		riscframe(Map*, ulong, ulong, ulong, ulong);
-int		risctrace(Map*, ulong, ulong, ulong, Tracer);
-int		setmap(Map*, int, ulong, ulong, ulong, char*);
+uvlong		riscframe(Map*, uvlong, uvlong, uvlong, uvlong);
+int		risctrace(Map*, uvlong, uvlong, uvlong, Tracer);
+int		setmap(Map*, int, uvlong, uvlong, vlong, char*);
 Sym*		symbase(long*);
 Sym*		symbase(long*);
 int		syminit(int, Fhdr*);
 int		syminit(int, Fhdr*);
-int		symoff(char*, int, long, int);
-void		textseg(ulong, Fhdr*);
+int		symoff(char*, int, uvlong, int);
+void		textseg(uvlong, Fhdr*);
 int		textsym(Symbol*, int);
 int		textsym(Symbol*, int);
 void		unusemap(Map*, int);
 void		unusemap(Map*, int);

+ 21 - 5
sys/lib/acid/leak

@@ -83,28 +83,44 @@ dumprange(s, e, type)
 	print("range ", type, " ", s\X, " ", e\X, "\n");
 	print("range ", type, " ", s\X, " ", e\X, "\n");
 	x = s;
 	x = s;
 	while x < e do {
 	while x < e do {
-		y = *x;
+		y = *(x\X);
 		if isptr(y) then print("data ", x\X, " ", y\X, " ", type, "\n");
 		if isptr(y) then print("data ", x\X, " ", y\X, " ", type, "\n");
 		x = x + 4;
 		x = x + 4;
 	}
 	}
 }
 }
 
 
+defn
+stacktop()
+{
+	local e, m;
+	
+	m = map();
+	while m != {} do {
+		e = head m;
+		if e[0] == "*data" then
+			return e[2];
+		m = tail m;
+	}
+	return 0x7ffff000;
+}
+			
 defn
 defn
 dumpmem()
 dumpmem()
 {
 {
-	local s;
+	local s, top;
 
 
 	xbloc = *bloc;
 	xbloc = *bloc;
 	// assume map()[1] is "data" 
 	// assume map()[1] is "data" 
 	dumprange(map()[1][1], end, "bss");	// bss
 	dumprange(map()[1][1], end, "bss");	// bss
 	dumprange(end, xbloc, "alloc");	// allocated
 	dumprange(end, xbloc, "alloc");	// allocated
 
 
-	if 0x7efff000 < *SP && *SP < 0x7ffff000 then 
+	top = stacktop() - 8;
+	if top-0x01000000 < *SP && *SP < top then
 		s = *SP;
 		s = *SP;
 	else
 	else
-		s = 0x7fff7000;	// 32 k
+		s = top-32*1024;
 
 
-	dumprange(s, 0x7ffff000, "stack");
+	dumprange(s, top, "stack");
 }
 }
 
 
 defn
 defn

+ 17 - 5
sys/man/1/strip

@@ -3,16 +3,28 @@
 strip \- remove symbols from binary files
 strip \- remove symbols from binary files
 .SH SYNOPSIS
 .SH SYNOPSIS
 .B strip
 .B strip
-[
 .I file ...
 .I file ...
-]
+.PP
+.B strip
+.B -o
+.I ofile
+.I file
 .SH DESCRIPTION
 .SH DESCRIPTION
 .I Strip
 .I Strip
-removes symbol table segments from executable files, rewriting the files in place.
+removes symbol table segments from executable files,
+rewriting the files in place.
 Stripping a file requires write permission of the file
 Stripping a file requires write permission of the file
 and the directory it is in.
 and the directory it is in.
-If no file is given, 
-standard input is stripped and the result written to standard output.
+.PP
+If the
+.B -o
+flag is given, 
+the single input file
+.I file
+is stripped and the result written to
+.IR ofile .
+.I File
+is unchanged.
 .SH SOURCE
 .SH SOURCE
 .B /sys/src/cmd/strip.c
 .B /sys/src/cmd/strip.c
 .SH "SEE ALSO"
 .SH "SEE ALSO"

+ 6 - 3
sys/man/3/vga

@@ -5,11 +5,10 @@ vga \- VGA controller device
 .nf
 .nf
 .B bind #v /dev
 .B bind #v /dev
 
 
+.B /dev/vgabios
 .B /dev/vgactl
 .B /dev/vgactl
-
-.B /dev/vgaovlctl
-
 .B /dev/vgaovl
 .B /dev/vgaovl
+.B /dev/vgaovlctl
 .fi
 .fi
 .SH DESCRIPTION
 .SH DESCRIPTION
 The VGA device allows configuration of a graphics controller
 The VGA device allows configuration of a graphics controller
@@ -24,6 +23,10 @@ it is used to implement configuration and setup of VGA controller cards.
 This is usually performed by
 This is usually performed by
 .IR vga (8).
 .IR vga (8).
 .PP
 .PP
+.B Vgabios
+provides read-only access to the low 640kB of memory,
+where the VGA and other BIOS ROMs are located.
+.PP
 Writing strings to 
 Writing strings to 
 .B vgactl
 .B vgactl
 configures the VGA device.
 configures the VGA device.

+ 9 - 1
sys/man/4/factotum

@@ -4,7 +4,7 @@ factotum, fgui \- authentication agent
 .SH SYNOPSIS
 .SH SYNOPSIS
 .B auth/factotum
 .B auth/factotum
 [
 [
-.B -DdkSun
+.B -DdknpuS
 ] [
 ] [
 .B -a asaddr
 .B -a asaddr
 ] [
 ] [
@@ -211,6 +211,14 @@ and
 .BR \-S .
 .BR \-S .
 This option is typically used by
 This option is typically used by
 the kernel at boot time.
 the kernel at boot time.
+.TP
+.B \-p
+causes the agent not to mark itself `private'
+via 
+.IR proc (3),
+so that it can be debugged.
+It is implied by
+.BR \-d .
 .PD
 .PD
 .PP
 .PP
 .I Fgui
 .I Fgui

+ 14 - 0
sys/man/8/plan9.ini

@@ -515,6 +515,12 @@ partition, the definition might read
 See
 See
 .IR boot (8)
 .IR boot (8)
 for more.
 for more.
+.SS \fLdebugfactotum=\fP
+Causes
+.IR boot (8)
+to start factotum with the
+.B -p
+flag, so that it can be debugged.
 .SS \fLventi=value\fP
 .SS \fLventi=value\fP
 When booting from a local fossil server backed by a local
 When booting from a local fossil server backed by a local
 or remote venti server,
 or remote venti server,
@@ -551,6 +557,13 @@ A value of
 consults only the first table,
 consults only the first table,
 .B old
 .B old
 only the second.
 only the second.
+.SS \fL*norealmode=\fP
+The kernel switches the processor to 16-bit real mode 
+to run BIOS interrupts, for example to find the memory map or to enable VESA. 
+This variable disables such switches.
+.SS \fL*noe820scan=\fP
+When available, the kernel uses the BIOS E820 memory map
+to size memory.  This variable disables the scan.
 .SS \fL*maxmem=value\fP
 .SS \fL*maxmem=value\fP
 This defines the maximum physical address that the system will scan when sizing memory.
 This defines the maximum physical address that the system will scan when sizing memory.
 By default the operating system will scan up to 768 megabytes, but setting
 By default the operating system will scan up to 768 megabytes, but setting
@@ -561,6 +574,7 @@ If the system has more than 768 megabytes, you must set
 for the kernel to find it.
 for the kernel to find it.
 .B *maxmem
 .B *maxmem
 must be less than 1.75 gigabytes.
 must be less than 1.75 gigabytes.
+This variable is not consulted if using the E820 memory map.
 .SS \fL*kernelpercent=value\fP
 .SS \fL*kernelpercent=value\fP
 This defines what percentage of available memory is reserved for the kernel allocation pool.
 This defines what percentage of available memory is reserved for the kernel allocation pool.
 The remainder is left for user processes.  The default
 The remainder is left for user processes.  The default

+ 13 - 10
sys/man/8/statusbar

@@ -46,22 +46,25 @@ set the coordinates of the statusbar window created
 .PD
 .PD
 .SH EXAMPLE
 .SH EXAMPLE
 The
 The
-.B -d
-options to
-.IR hget(1),
-.IR venti/fmtarenas ,
-and
-.I venti/fmtisect
-(see
-.IR ventiaux (8))
-cause them to print status lines suitable for
+.B -v
+option to
+.IR hget(1)
+.\" and the 
+.\" .B -d
+.\" option to
+.\" .IR venti/fmtarenas
+.\" and
+.\" .I venti/fmtisect
+.\" (see
+,\" .IR ventiaux (8))
+causes it to print status lines suitable for
 input to
 input to
 .IR statusbar .
 .IR statusbar .
 .PP
 .PP
 Monitor a long download:
 Monitor a long download:
 .IP
 .IP
 .EX
 .EX
-hget -d -o bigfile http://server.com/bigfile | 
+hget -v -o bigfile http://server.com/bigfile | 
   aux/statusbar 'big file download'
   aux/statusbar 'big file download'
 .EE
 .EE
 .SH SOURCE
 .SH SOURCE

+ 0 - 1
sys/man/8/vga

@@ -59,7 +59,6 @@ dump the BIOS memory (in hex) to standard output and exit.
 .TP
 .TP
 .B -c
 .B -c
 disable the use of the hardware graphics cursor.
 disable the use of the hardware graphics cursor.
-(Since there is no software cursor, this disables the cursor entirely.)
 .TP
 .TP
 .B -d
 .B -d
 include the color palette in whatever actions are performed,
 include the color palette in whatever actions are performed,

+ 1 - 1
sys/src/9/alphapc/apc

@@ -36,7 +36,7 @@ misc
 	arch164
 	arch164
 
 
 	sdata		pci sdscsi
 	sdata		pci sdscsi
-	sd53c8xx	pci sdscsi
+#	sd53c8xx	pci sdscsi
 
 
 	uarti8250
 	uarti8250
 
 

+ 11 - 4
sys/src/9/alphapc/dat.h

@@ -1,4 +1,5 @@
 typedef struct Conf	Conf;
 typedef struct Conf	Conf;
+typedef struct Confmem	Confmem;
 typedef struct FPsave	FPsave;
 typedef struct FPsave	FPsave;
 typedef struct ISAConf	ISAConf;
 typedef struct ISAConf	ISAConf;
 typedef struct Label	Label;
 typedef struct Label	Label;
@@ -32,6 +33,7 @@ struct Lock
 	ulong	sr;
 	ulong	sr;
 	ulong	pc;
 	ulong	pc;
 	Proc	*p;
 	Proc	*p;
+	Mach	*m;
 	ulong	pid;
 	ulong	pid;
 	ushort	isilock;
 	ushort	isilock;
 };
 };
@@ -63,15 +65,20 @@ struct	FPsave
 	long	fpstatus;
 	long	fpstatus;
 };
 };
 
 
+struct Confmem
+{
+	ulong	base;
+	ulong	npage;
+	ulong	kbase;
+	ulong	klimit;
+};
+
 struct Conf
 struct Conf
 {
 {
 	ulong	nmach;		/* processors */
 	ulong	nmach;		/* processors */
 	ulong	nproc;		/* processes */
 	ulong	nproc;		/* processes */
-	ulong	npage0;		/* total physical pages of memory */
-	ulong	npage1;		/* total physical pages of memory */
+	Confmem	mem[2];
 	ulong	npage;		/* total physical pages of memory */
 	ulong	npage;		/* total physical pages of memory */
-	ulong	base0;		/* base of bank 0 */
-	ulong	base1;		/* base of bank 1 */
 	ulong	upages;		/* user page pool */
 	ulong	upages;		/* user page pool */
 	ulong	nimage;		/* number of page cache image headers */
 	ulong	nimage;		/* number of page cache image headers */
 	ulong	nswap;		/* number of swap pages */
 	ulong	nswap;		/* number of swap pages */

+ 1 - 4
sys/src/9/alphapc/devvga.c

@@ -130,10 +130,7 @@ vgaread(Chan* c, void* a, long n, vlong off)
 		len += snprint(p+len, READSTR-len, "blanktime %lud\n", blanktime);
 		len += snprint(p+len, READSTR-len, "blanktime %lud\n", blanktime);
 		len += snprint(p+len, READSTR-len, "hwaccel %s\n", hwaccel ? "on" : "off");
 		len += snprint(p+len, READSTR-len, "hwaccel %s\n", hwaccel ? "on" : "off");
 		len += snprint(p+len, READSTR-len, "hwblank %s\n", hwblank ? "on" : "off");
 		len += snprint(p+len, READSTR-len, "hwblank %s\n", hwblank ? "on" : "off");
-		if(scr->pciaddr)
-			snprint(p+len, READSTR-len, "addr 0x%lux\n", scr->pciaddr);
-		else
-			snprint(p+len, READSTR-len, "addr 0x%lux\n", scr->aperture);
+		snprint(p+len, READSTR-len, "addr 0x%lux\n", scr->paddr);
 		n = readstr(offset, a, n, p);
 		n = readstr(offset, a, n, p);
 		poperror();
 		poperror();
 		free(p);
 		free(p);

+ 3 - 1
sys/src/9/alphapc/fns.h

@@ -98,11 +98,13 @@ void	tlbflush(int, ulong);
 void	touser(void*);
 void	touser(void*);
 void	trapinit(void);
 void	trapinit(void);
 void	unaligned(void);
 void	unaligned(void);
-ulong	upamalloc(ulong, int, int);
+ulong	upaalloc(int, int);
 void	upafree(ulong, int);
 void	upafree(ulong, int);
 #define	userureg(ur) ((ur)->status & UMODE)
 #define	userureg(ur) ((ur)->status & UMODE)
+void*	vmap(ulong, int);
 void	wrent(int, void*);
 void	wrent(int, void*);
 void	wrvptptr(uvlong);
 void	wrvptptr(uvlong);
+void	vunmap(void*, int);
 
 
 #define	waserror()	(up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
 #define	waserror()	(up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
 #define KADDR(a)	((void*)((ulong)(a)|KZERO))
 #define KADDR(a)	((void*)((ulong)(a)|KZERO))

+ 7 - 7
sys/src/9/alphapc/main.c

@@ -454,17 +454,17 @@ confinit(void)
 	 * allocating low memory pages from bank 0 for any peripherals
 	 * allocating low memory pages from bank 0 for any peripherals
 	 * which only have a 24bit address counter.
 	 * which only have a 24bit address counter.
 	 */
 	 */
-	conf.npage0 = (8*1024*1024)/BY2PG;
-	conf.base0 = 0;
+	conf.mem[0].npage = (8*1024*1024)/BY2PG;
+	conf.mem[0].base = 0;
 
 
-	conf.npage1 = (b->max-8*1024*1024)/BY2PG;
-	conf.base1 = 8*1024*1024;
+	conf.mem[1].npage = (b->max-8*1024*1024)/BY2PG;
+	conf.mem[1].base = 8*1024*1024;
 
 
-	conf.npage = conf.npage0+conf.npage1;
+	conf.npage = conf.mem[0].npage+conf.mem[1].npage;
 	conf.upages = (conf.npage*70)/100;
 	conf.upages = (conf.npage*70)/100;
 
 
-	conf.npage0 -= ktop/BY2PG;
-	conf.base0 += ktop;
+	conf.mem[0].npage -= ktop/BY2PG;
+	conf.mem[0].base += ktop;
 	conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG;
 	conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG;
 
 
 	/*
 	/*

+ 21 - 7
sys/src/9/alphapc/mmu.c

@@ -224,8 +224,8 @@ flushmmu(void)
 
 
 }
 }
 
 
-ulong
-upamalloc(ulong pa, int size, int align)
+void*
+vmap(ulong pa, int size)
 {
 {
 	void *va;
 	void *va;
 
 
@@ -234,17 +234,16 @@ upamalloc(ulong pa, int size, int align)
 	 */
 	 */
 	if(pa == 0)
 	if(pa == 0)
 		return 0;
 		return 0;
-	USED(align);
 	va = kmapv(((uvlong)0x88<<32LL)|pa, size);
 	va = kmapv(((uvlong)0x88<<32LL)|pa, size);
 	if(va == nil)
 	if(va == nil)
 		return 0;
 		return 0;
-	return PADDR(va);
+	return (void*)va;
 }
 }
 
 
 void
 void
-upafree(ulong, int)
+vunmap(void*, int)
 {
 {
-	print("upafree: virtual mapping not freed\n");
+	print("vunmap: virtual mapping not freed\n");
 }
 }
 
 
 void
 void
@@ -263,4 +262,19 @@ mmudump(void)
 	}
 	}
 }
 }
 
 
-void checkmmu(ulong, ulong) { }
+ulong
+upaalloc(int, int)
+{
+	return 0;
+}
+
+void
+upafree(ulong, int)
+{
+}
+
+void
+checkmmu(ulong, ulong)
+{
+}
+

+ 20 - 7
sys/src/9/alphapc/screen.h

@@ -68,7 +68,7 @@ struct VGAdev {
 	void	(*enable)(VGAscr*);
 	void	(*enable)(VGAscr*);
 	void	(*disable)(VGAscr*);
 	void	(*disable)(VGAscr*);
 	void	(*page)(VGAscr*, int);
 	void	(*page)(VGAscr*, int);
-	ulong	(*linear)(VGAscr*, int*, int*);
+	void	(*linear)(VGAscr*, int, int);
 	void	(*drawinit)(VGAscr*);
 	void	(*drawinit)(VGAscr*);
 	int	(*fill)(VGAscr*, Rectangle, ulong);
 	int	(*fill)(VGAscr*, Rectangle, ulong);
 	void (*flush)(VGAscr*, Rectangle);
 	void (*flush)(VGAscr*, Rectangle);
@@ -91,6 +91,7 @@ struct VGAcur {
 struct VGAscr {
 struct VGAscr {
 	Lock	devlock;
 	Lock	devlock;
 	VGAdev*	dev;
 	VGAdev*	dev;
+	Pcidev*	pci;
 
 
 	VGAcur*	cur;
 	VGAcur*	cur;
 	ulong	storage;
 	ulong	storage;
@@ -98,17 +99,16 @@ struct VGAscr {
 
 
 	int	useflush;
 	int	useflush;
 
 
-	ulong	aperture;			/* physical address, kernel */
-	ulong	pciaddr;			/* physical address, user */
-	int	isupamem;
+	ulong	paddr;		/* frame buffer */
+	void*	vaddr;
 	int	apsize;
 	int	apsize;
 
 
 	ulong	io;				/* device specific registers */
 	ulong	io;				/* device specific registers */
-
+	ulong	*mmio;
+	
 	ulong	colormap[Pcolours][3];
 	ulong	colormap[Pcolours][3];
 	int	palettedepth;
 	int	palettedepth;
 
 
-	ulong	*mmio;
 	Memimage* gscreen;
 	Memimage* gscreen;
 	Memdata* gscreendata;
 	Memdata* gscreendata;
 	Memsubfont* memdefont;
 	Memsubfont* memdefont;
@@ -142,14 +142,27 @@ extern int	screenaperture(int, int);
 extern Rectangle physgscreenr;	/* actual monitor size */
 extern Rectangle physgscreenr;	/* actual monitor size */
 extern void	blankscreen(int);
 extern void	blankscreen(int);
 
 
+extern VGAcur swcursor;
+extern void swcursorinit(void);
+extern void swcursorhide(void);
+extern void swcursoravoid(Rectangle);
+extern void swcursorunhide(void);
+
 /* devdraw.c */
 /* devdraw.c */
 extern void	deletescreenimage(void);
 extern void	deletescreenimage(void);
 extern int	drawhasclients(void);
 extern int	drawhasclients(void);
 extern ulong	blanktime;
 extern ulong	blanktime;
+extern QLock	drawlock;
+
 /* vga.c */
 /* vga.c */
 extern void	vgascreenwin(VGAscr*);
 extern void	vgascreenwin(VGAscr*);
 extern void	vgaimageinit(ulong);
 extern void	vgaimageinit(ulong);
-extern ulong	vgapcilinear(VGAscr*, int*, int*, int, int);
+extern void	vgalinearpciid(VGAscr*, int, int);
+extern void	vgalinearpci(VGAscr*);
+extern void	vgalinearaddr(VGAscr*, ulong, int);
 
 
 extern void	drawblankscreen(int);
 extern void	drawblankscreen(int);
 extern void	vgablank(VGAscr*, int);
 extern void	vgablank(VGAscr*, int);
+
+extern Lock	vgascreenlock;
+

+ 0 - 2
sys/src/9/alphapc/sd53c8xx.c

@@ -1817,8 +1817,6 @@ static Variant variant[] = {
 { SYM_1010_DID,  0xff, "SYM53C1010",	Burst128, 16, 64, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 },
 { SYM_1010_DID,  0xff, "SYM53C1010",	Burst128, 16, 64, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 },
 };
 };
 
 
-#define offsetof(s, t) ((ulong)&((s *)0)->t)
-
 static int
 static int
 xfunc(Controller *c, enum na_external x, unsigned long *v)
 xfunc(Controller *c, enum na_external x, unsigned long *v)
 {
 {

+ 12 - 4
sys/src/9/bitsy/dat.h

@@ -1,5 +1,6 @@
 typedef struct Cisdat 		Cisdat;
 typedef struct Cisdat 		Cisdat;
 typedef struct Conf		Conf;
 typedef struct Conf		Conf;
+typedef struct Confmem	Confmem;
 typedef struct FPU		FPU;
 typedef struct FPU		FPU;
 typedef struct FPenv		FPenv;
 typedef struct FPenv		FPenv;
 typedef struct FPsave		FPsave;
 typedef struct FPsave		FPsave;
@@ -37,6 +38,7 @@ struct Lock
 	ulong	sr;
 	ulong	sr;
 	ulong	pc;
 	ulong	pc;
 	Proc	*p;
 	Proc	*p;
+	Mach	*m;
 	ushort	isilock;
 	ushort	isilock;
 };
 };
 
 
@@ -62,19 +64,25 @@ struct	FPsave
 	ulong	regs[8][3];	/* emulated fp */	
 	ulong	regs[8][3];	/* emulated fp */	
 };
 };
 
 
+struct Confmem
+{
+	ulong	base;
+	ulong	npage;
+	ulong	limit;
+	ulong	kbase;
+	ulong	klimit;
+};
+
 struct Conf
 struct Conf
 {
 {
 	ulong	nmach;		/* processors */
 	ulong	nmach;		/* processors */
 	ulong	nproc;		/* processes */
 	ulong	nproc;		/* processes */
-	ulong	npage0;		/* total physical pages of memory */
-	ulong	npage1;		/* total physical pages of memory */
+	Confmem	mem[2];
 	ulong	npage;		/* total physical pages of memory */
 	ulong	npage;		/* total physical pages of memory */
 	ulong	upages;		/* user page pool */
 	ulong	upages;		/* user page pool */
 	ulong	nimage;		/* number of page cache image headers */
 	ulong	nimage;		/* number of page cache image headers */
 	ulong	nswap;		/* number of swap pages */
 	ulong	nswap;		/* number of swap pages */
 	int	nswppo;		/* max # of pageouts per segment pass */
 	int	nswppo;		/* max # of pageouts per segment pass */
-	ulong	base0;		/* base of bank 0 */
-	ulong	base1;		/* base of bank 1 */
 	ulong	copymode;	/* 0 is copy on write, 1 is copy on reference */
 	ulong	copymode;	/* 0 is copy on write, 1 is copy on reference */
 	int	monitor;
 	int	monitor;
 	ulong	ialloc;		/* bytes available for interrupt time allocation */
 	ulong	ialloc;		/* bytes available for interrupt time allocation */

+ 19 - 1
sys/src/9/bitsy/devpenmouse.c

@@ -53,6 +53,8 @@ struct Mouseinfo
 	Lock;
 	Lock;
 	Mousestate;
 	Mousestate;
 	ulong	lastcounter;	/* value when /dev/mouse read */
 	ulong	lastcounter;	/* value when /dev/mouse read */
+	ulong	resize;
+	ulong	lastresize;
 	Rendez	r;
 	Rendez	r;
 	Ref;
 	Ref;
 	QLock;
 	QLock;
@@ -285,6 +287,10 @@ penmouseread(Chan *c, void *va, long n, vlong)
 		mouse.lastcounter = m.counter;
 		mouse.lastcounter = m.counter;
 		if(n > 1+4*12)
 		if(n > 1+4*12)
 			n = 1+4*12;
 			n = 1+4*12;
+		if(mouse.lastresize != mouse.resize){
+			mouse.lastresize = mouse.resize;
+			buf[0] = 'r';
+		}
 		memmove(va, buf, n);
 		memmove(va, buf, n);
 		return n;
 		return n;
 	}
 	}
@@ -481,7 +487,8 @@ penmousetrack(int b, int x, int y)
 int
 int
 penmousechanged(void*)
 penmousechanged(void*)
 {
 {
-	return mouse.lastcounter != mouse.counter;
+	return mouse.lastcounter != mouse.counter ||
+		mouse.lastresize != mouse.resize;
 }
 }
 
 
 Point
 Point
@@ -489,3 +496,14 @@ penmousexy(void)
 {
 {
 	return mouse.xy;
 	return mouse.xy;
 }
 }
+
+/*
+ * notify reader that screen has been resized (ha!)
+ */
+void
+mouseresize(void)
+{
+	mouse.resize++;
+	wakeup(&mouse.r);
+}
+

+ 38 - 49
sys/src/9/bitsy/main.c

@@ -268,19 +268,18 @@ rdb(void)
 int
 int
 probemem(ulong addr)
 probemem(ulong addr)
 {
 {
+	int i;
 	ulong *p;
 	ulong *p;
 	ulong a;
 	ulong a;
 
 
 	addr += OneMeg - sizeof(ulong);
 	addr += OneMeg - sizeof(ulong);
 	p = (ulong*)addr;
 	p = (ulong*)addr;
 	*p = addr;
 	*p = addr;
-	for(a = conf.base0+OneMeg-sizeof(ulong); a < conf.npage0; a += OneMeg){
-		p = (ulong*)a;
-		*p = 0;
-	}
-	for(a = conf.base1+OneMeg-sizeof(ulong); a < conf.npage1; a += OneMeg){
-		p = (ulong*)a;
-		*p = 0;
+	for(i=0; i<nelem(conf.mem); i++){
+		for(a = conf.mem[i].base+OneMeg-sizeof(ulong); a < conf.mem[i].limit; a += OneMeg){
+			p = (ulong*)a;
+			*p = 0;
+		}
 	}
 	}
 	p = (ulong*)addr;
 	p = (ulong*)addr;
 	if(*p != addr)
 	if(*p != addr)
@@ -295,57 +294,47 @@ probemem(ulong addr)
 void
 void
 confinit(void)
 confinit(void)
 {
 {
-	int i;
+	int i, j;
 	ulong addr;
 	ulong addr;
 	ulong ktop;
 	ulong ktop;
 
 
 	/* find first two contiguous sections of available memory */
 	/* find first two contiguous sections of available memory */
 	addr = PHYSDRAM0;
 	addr = PHYSDRAM0;
-	conf.base0 = conf.npage0 = addr;
-	conf.base1 = conf.npage1 = addr;
-	for(i = 0; i < 512; i++){
-		if(probemem(addr) == 0)
-			break;
-		addr += OneMeg;
+	for(i=0; i<nelem(conf.mem); i++){
+		conf.mem[i].base = addr;
+		conf.mem[i].limit = addr;
 	}
 	}
-	for(; i < 512; i++){
-		if(probemem(addr) < 0)
-			break;
-		addr += OneMeg;
-		conf.npage0 = addr;
-	}
-
-	conf.base1 = conf.npage1 = addr;
-	for(; i < 512; i++){
-		if(probemem(addr) == 0)
-			break;
-		addr += OneMeg;
+	for(j=0; j<nelem(conf.mem); j++){
+		conf.mem[j].base = addr;
+		conf.mem[j].limit = addr;
+		
+		for(i = 0; i < 512; i++){
+			if(probemem(addr) == 0)
+				break;
+			addr += OneMeg;
+		}
+		for(; i < 512; i++){
+			if(probemem(addr) < 0)
+				break;
+			addr += OneMeg;
+			conf.mem[j].limit = addr;
+		}
 	}
 	}
-	for(; i < 512; i++){
-		if(probemem(addr) < 0)
-			break;
-		addr += OneMeg;
-		conf.npage1 = addr;
+	
+	conf.npage = 0;
+	for(i=0; i<nelem(conf.mem); i++){
+		/* take kernel out of allocatable space */
+		ktop = PGROUND((ulong)end);
+		if(ktop >= conf.mem[i].base && ktop <= conf.mem[i].limit)
+			conf.mem[i].base = ktop;
+		
+		/* zero memory */
+		memset((void*)conf.mem[i].base, 0, conf.mem[i].limit - conf.mem[i].base);
+
+		conf.mem[i].npage = (conf.mem[i].limit - conf.mem[i].base)/BY2PG;
+		conf.npage += conf.mem[i].npage;
 	}
 	}
 
 
-	/* take kernel out of allocatable space */
-	ktop = PGROUND((ulong)end);
-	if(ktop >= conf.base0 && ktop <= conf.npage0)
-		conf.base0 = ktop;
-	else if(ktop >= conf.base1 && ktop <= conf.npage1)
-		conf.base1 = ktop;
-	else
-		iprint("kernel not in allocatable space\n");
-
-	/* zero memory */
-	memset((void*)conf.base0, 0, conf.npage0 - conf.base0);
-	memset((void*)conf.base1, 0, conf.npage1 - conf.base1);
-
-	/* make npage the right thing */
-	conf.npage0 = (conf.npage0 - conf.base0)/BY2PG;
-	conf.npage1 = (conf.npage1 - conf.base1)/BY2PG;
-	conf.npage = conf.npage0+conf.npage1;
-
 	if(conf.npage > 16*MB/BY2PG){
 	if(conf.npage > 16*MB/BY2PG){
 		conf.upages = (conf.npage*60)/100;
 		conf.upages = (conf.npage*60)/100;
 		imagmem->minarena = 4*1024*1024;
 		imagmem->minarena = 4*1024*1024;

+ 1 - 1
sys/src/9/bitsy/mkfile

@@ -104,7 +104,7 @@ init.h:	../port/initcode.c init9.s
 	$AS init9.s
 	$AS init9.s
 	$LD -l -R1 -o init.out init9.$O initcode.$O /arm/lib/libc.a
 	$LD -l -R1 -o init.out init9.$O initcode.$O /arm/lib/libc.a
 	{echo 'uchar initcode[]={'
 	{echo 'uchar initcode[]={'
-	 strip < init.out | xd -1x |
+	 strip -o /fd/1 init.out | xd -1x |
 		sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
 		sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
 	 echo '};'} > init.h
 	 echo '};'} > init.h
 
 

+ 1 - 21
sys/src/9/bitsy/sdata.c

@@ -742,6 +742,7 @@ tryedd1:
 
 
 	sdev->ifc = &sdataifc;
 	sdev->ifc = &sdataifc;
 	sdev->ctlr = ctlr;
 	sdev->ctlr = ctlr;
+	sdev->idno = 'C';
 	sdev->nunit = 1;
 	sdev->nunit = 1;
 	ctlr->sdev = sdev;
 	ctlr->sdev = sdev;
 
 
@@ -1571,26 +1572,6 @@ atalegacy(int port, int irq)
 	return ataprobe(port, port+0x204, irq);
 	return ataprobe(port, port+0x204, irq);
 }
 }
 
 
-static SDev*
-ataid(SDev* sdev)
-{
-	int i;
-
-	if(sdev == nil)
-		return nil;
-	i = 0;
-	while(sdev){
-		if(sdev->ifc == &sdataifc){
-			sdev->idno = 'C'+i;
-			i++;
-			snprint(sdev->name, KNAMELEN, "sd%c", sdev->idno);
-		}
-		sdev = sdev->next;
-	}
-
-	return nil;
-}
-
 static int ataitype;
 static int ataitype;
 static int atairq;
 static int atairq;
 static int
 static int
@@ -2089,7 +2070,6 @@ SDifc sdataifc = {
 
 
 	nil,				/* pnp */
 	nil,				/* pnp */
 	atalegacy,			/* legacy */
 	atalegacy,			/* legacy */
-	ataid,				/* id */
 	ataenable,			/* enable */
 	ataenable,			/* enable */
 	nil,				/* disable */
 	nil,				/* disable */
 
 

+ 3 - 1
sys/src/9/boot/bootauth.c

@@ -22,7 +22,9 @@ authentication(int cpuflag)
 	ac = 0;
 	ac = 0;
 	av = argv;
 	av = argv;
 	av[ac++] = "factotum";
 	av[ac++] = "factotum";
-//av[ac++] = "-d";
+	if(getenv("debugfactotum"))
+		av[ac++] = "-p";
+//av[ac++] = "-d";	//debug traces
 //av[ac++] = "-D";	//9p messages
 //av[ac++] = "-D";	//9p messages
 	if(cpuflag)
 	if(cpuflag)
 		av[ac++] = "-S";
 		av[ac++] = "-S";

+ 11 - 5
sys/src/9/mtx/dat.h

@@ -1,4 +1,5 @@
 typedef struct Conf	Conf;
 typedef struct Conf	Conf;
+typedef struct Confmem	Confmem;
 typedef struct FPsave	FPsave;
 typedef struct FPsave	FPsave;
 typedef struct ISAConf	ISAConf;
 typedef struct ISAConf	ISAConf;
 typedef struct Label	Label;
 typedef struct Label	Label;
@@ -33,7 +34,7 @@ struct Lock
 	ulong	sr;
 	ulong	sr;
 	ulong	pc;
 	ulong	pc;
 	Proc	*p;
 	Proc	*p;
-	ulong	pid;
+	Mach	*m;
 	ushort	isilock;
 	ushort	isilock;
 };
 };
 
 
@@ -68,15 +69,20 @@ struct	FPsave
 	};
 	};
 };
 };
 
 
+struct Confmem
+{
+	ulong	base;
+	ulong	npage;
+	ulong	kbase;
+	ulong	klimit;
+};
+
 struct Conf
 struct Conf
 {
 {
 	ulong	nmach;		/* processors */
 	ulong	nmach;		/* processors */
 	ulong	nproc;		/* processes */
 	ulong	nproc;		/* processes */
-	ulong	npage0;		/* total physical pages of memory */
-	ulong	npage1;		/* total physical pages of memory */
+	Confmem	mem[1];
 	ulong	npage;		/* total physical pages of memory */
 	ulong	npage;		/* total physical pages of memory */
-	ulong	base0;		/* base of bank 0 */
-	ulong	base1;		/* base of bank 1 */
 	ulong	upages;		/* user page pool */
 	ulong	upages;		/* user page pool */
 	ulong	nimage;		/* number of page cache image headers */
 	ulong	nimage;		/* number of page cache image headers */
 	ulong	nswap;		/* number of swap pages */
 	ulong	nswap;		/* number of swap pages */

+ 3 - 7
sys/src/9/mtx/main.c

@@ -288,13 +288,9 @@ confinit(void)
 
 
 	pa = PGROUND(PADDR(end));
 	pa = PGROUND(PADDR(end));
 
 
-	conf.npage0 = memsize/BY2PG;
-	conf.base0 = pa;
-	
-	conf.npage1 = 0;
-	conf.base1 = pa;
-
-	conf.npage = conf.npage0 + conf.npage1;
+	conf.mem[0].npage = memsize/BY2PG;
+	conf.mem[0].base = pa;
+	conf.npage = conf.mem[0].npage;
 
 
 	conf.nmach = 1;
 	conf.nmach = 1;
 	conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
 	conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;

+ 10 - 10
sys/src/9/pc/apbootstrap.s

@@ -1,3 +1,13 @@
+/*
+ * Start an Application Processor. This must be placed on a 4KB boundary
+ * somewhere in the 1st MB of conventional memory (APBOOTSTRAP). However,
+ * due to some shortcuts below it's restricted further to within the 1st
+ * 64KB. The AP starts in real-mode, with
+ *   CS selector set to the startup memory address/16;
+ *   CS base set to startup memory address;
+ *   CS limit set to 64KB;
+ *   CPL and IP set to 0.
+ */
 #include "mem.h"
 #include "mem.h"
 
 
 #define NOP		BYTE $0x90		/* NOP */
 #define NOP		BYTE $0x90		/* NOP */
@@ -23,16 +33,6 @@
 #define PDO(a)		(((((a))>>22) & 0x03FF)<<2)
 #define PDO(a)		(((((a))>>22) & 0x03FF)<<2)
 #define PTO(a)		(((((a))>>12) & 0x03FF)<<2)
 #define PTO(a)		(((((a))>>12) & 0x03FF)<<2)
 
 
-/*
- * Start an Application Processor. This must be placed on a 4KB boundary
- * somewhere in the 1st MB of conventional memory (APBOOTSTRAP). However,
- * due to some shortcuts below it's restricted further to within the 1st
- * 64KB. The AP starts in real-mode, with
- *   CS selector set to the startup memory address/16;
- *   CS base set to startup memory address;
- *   CS limit set to 64KB;
- *   CPL and IP set to 0.
- */
 TEXT apbootstrap(SB), $0
 TEXT apbootstrap(SB), $0
 	FARJUMP16(0, _apbootstrap(SB))
 	FARJUMP16(0, _apbootstrap(SB))
 TEXT _apvector(SB), $0				/* address APBOOTSTRAP+0x08 */
 TEXT _apvector(SB), $0				/* address APBOOTSTRAP+0x08 */

+ 13 - 0
sys/src/9/pc/apic.c

@@ -376,3 +376,16 @@ lapicclock(Ureg *u, void*)
 {
 {
 	timerintr(u, 0);
 	timerintr(u, 0);
 }
 }
+
+void
+lapicintron(void)
+{
+	lapicw(LapicTPR, 0);
+}
+
+void
+lapicintroff(void)
+{
+	lapicw(LapicTPR, 0xFF);
+}
+

+ 2 - 0
sys/src/9/pc/apm.c

@@ -103,6 +103,8 @@ apmlink(void)
 	if(isaconfig("apm", 0, &isa) == 0)
 	if(isaconfig("apm", 0, &isa) == 0)
 		return;
 		return;
 
 
+/* XXX use realmode() */
+
 	/*
 	/*
 	 * APM info passed from boot loader.
 	 * APM info passed from boot loader.
 	 * Now we need to set up the GDT entries for APM.
 	 * Now we need to set up the GDT entries for APM.

+ 2 - 0
sys/src/9/pc/archmp.c

@@ -62,6 +62,8 @@ PCArch archmp = {
 .reset=		mpshutdown,
 .reset=		mpshutdown,
 .intrinit=	mpinit,
 .intrinit=	mpinit,
 .intrenable=	mpintrenable,
 .intrenable=	mpintrenable,
+.intron=	lapicintron,
+.introff=	lapicintroff,
 .fastclock=	i8253read,
 .fastclock=	i8253read,
 .timerset=	lapictimerset,
 .timerset=	lapictimerset,
 };
 };

+ 19 - 7
sys/src/9/pc/dat.h

@@ -1,4 +1,5 @@
 typedef struct Conf	Conf;
 typedef struct Conf	Conf;
+typedef struct Confmem	Confmem;
 typedef struct FPsave	FPsave;
 typedef struct FPsave	FPsave;
 typedef struct ISAConf	ISAConf;
 typedef struct ISAConf	ISAConf;
 typedef struct Label	Label;
 typedef struct Label	Label;
@@ -32,6 +33,7 @@ struct Lock
 	ulong	sr;
 	ulong	sr;
 	ulong	pc;
 	ulong	pc;
 	Proc	*p;
 	Proc	*p;
+	Mach	*m;
 	ushort	isilock;
 	ushort	isilock;
 };
 };
 
 
@@ -73,13 +75,20 @@ struct	FPsave
 	uchar	regs[80];	/* floating point registers */
 	uchar	regs[80];	/* floating point registers */
 };
 };
 
 
+struct Confmem
+{
+	ulong	base;
+	ulong	npage;
+	ulong	kbase;
+	ulong	klimit;
+};
+
 struct Conf
 struct Conf
 {
 {
 	ulong	nmach;		/* processors */
 	ulong	nmach;		/* processors */
 	ulong	nproc;		/* processes */
 	ulong	nproc;		/* processes */
 	ulong	monitor;	/* has monitor? */
 	ulong	monitor;	/* has monitor? */
-	ulong	npage0;		/* total physical pages of memory */
-	ulong	npage1;		/* total physical pages of memory */
+	Confmem	mem[4];		/* physical memory */
 	ulong	npage;		/* total physical pages of memory */
 	ulong	npage;		/* total physical pages of memory */
 	ulong	upages;		/* user page pool */
 	ulong	upages;		/* user page pool */
 	ulong	nimage;		/* number of page cache image headers */
 	ulong	nimage;		/* number of page cache image headers */
@@ -102,6 +111,7 @@ struct PMMU
 	Page*	mmupdb;			/* page directory base */
 	Page*	mmupdb;			/* page directory base */
 	Page*	mmufree;		/* unused page table pages */
 	Page*	mmufree;		/* unused page table pages */
 	Page*	mmuused;		/* used page table pages */
 	Page*	mmuused;		/* used page table pages */
+	uint	lastkmap;		/* last entry used by kmap */
 };
 };
 
 
 /*
 /*
@@ -212,12 +222,12 @@ struct Mach
 };
 };
 
 
 /*
 /*
- * Fake kmap
+ * KMap the structure doesn't exist, but the functions do.
  */
  */
-typedef void		KMap;
-#define	VA(k)		((ulong)(k))
-#define	kmap(p)		(KMap*)((p)->pa|KZERO)
-#define	kunmap(k)
+typedef struct KMap		KMap;
+#define	VA(k)		((void*)(k))
+KMap*	kmap(Page*);
+void	kunmap(KMap*);
 
 
 struct
 struct
 {
 {
@@ -243,6 +253,8 @@ struct PCArch
 	int	(*intrenable)(Vctl*);
 	int	(*intrenable)(Vctl*);
 	int	(*intrvecno)(int);
 	int	(*intrvecno)(int);
 	int	(*intrdisable)(int);
 	int	(*intrdisable)(int);
+	void	(*introff)(void);
+	void	(*intron)(void);
 
 
 	void	(*clockenable)(void);
 	void	(*clockenable)(void);
 	uvlong	(*fastclock)(uvlong*);
 	uvlong	(*fastclock)(uvlong*);

+ 2 - 0
sys/src/9/pc/devarch.c

@@ -520,6 +520,8 @@ PCArch archgeneric = {
 .intrenable=	i8259enable,
 .intrenable=	i8259enable,
 .intrvecno=	i8259vecno,
 .intrvecno=	i8259vecno,
 .intrdisable=	i8259disable,
 .intrdisable=	i8259disable,
+.intron=		i8259on,
+.introff=		i8259off,
 
 
 .clockenable=	i8253enable,
 .clockenable=	i8253enable,
 .fastclock=	i8253read,
 .fastclock=	i8253read,

+ 4 - 5
sys/src/9/pc/devether.c

@@ -416,7 +416,7 @@ etherprobe(int cardno, int ctlrno)
 	i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %d",
 	i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %d",
 		ctlrno, cards[cardno].type, ether->mbps, ether->port, ether->irq);
 		ctlrno, cards[cardno].type, ether->mbps, ether->port, ether->irq);
 	if(ether->mem)
 	if(ether->mem)
-		i += sprint(buf+i, " addr 0x%luX", PADDR(ether->mem));
+		i += sprint(buf+i, " addr 0x%luX", ether->mem);
 	if(ether->size)
 	if(ether->size)
 		i += sprint(buf+i, " size 0x%luX", ether->size);
 		i += sprint(buf+i, " size 0x%luX", ether->size);
 	i += sprint(buf+i, ": %2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux",
 	i += sprint(buf+i, ": %2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux",
@@ -425,16 +425,15 @@ etherprobe(int cardno, int ctlrno)
 	sprint(buf+i, "\n");
 	sprint(buf+i, "\n");
 	print(buf);
 	print(buf);
 
 
-	if (ether->mbps >= 1000) {
+	if(ether->mbps >= 1000){
 		netifinit(ether, name, Ntypes, 512*1024);
 		netifinit(ether, name, Ntypes, 512*1024);
 		if(ether->oq == 0)
 		if(ether->oq == 0)
 			ether->oq = qopen(512*1024, Qmsg, 0, 0);
 			ether->oq = qopen(512*1024, Qmsg, 0, 0);
-	} else if(ether->mbps >= 100){
+	}else if(ether->mbps >= 100){
 		netifinit(ether, name, Ntypes, 256*1024);
 		netifinit(ether, name, Ntypes, 256*1024);
 		if(ether->oq == 0)
 		if(ether->oq == 0)
 			ether->oq = qopen(256*1024, Qmsg, 0, 0);
 			ether->oq = qopen(256*1024, Qmsg, 0, 0);
-	}
-	else{
+	}else{
 		netifinit(ether, name, Ntypes, 128*1024);
 		netifinit(ether, name, Ntypes, 128*1024);
 		if(ether->oq == 0)
 		if(ether->oq == 0)
 			ether->oq = qopen(128*1024, Qmsg, 0, 0);
 			ether->oq = qopen(128*1024, Qmsg, 0, 0);

+ 5 - 3
sys/src/9/pc/devlml.c

@@ -127,6 +127,7 @@ lmlreset(void)
 {
 {
 	Physseg segbuf;
 	Physseg segbuf;
 	ulong regpa;
 	ulong regpa;
+	void *regva;
 	ISAConf isa;
 	ISAConf isa;
 	char name[32];
 	char name[32];
 	Pcidev *pcidev;
 	Pcidev *pcidev;
@@ -157,12 +158,13 @@ lmlreset(void)
 
 
 		print("zr36067 found at 0x%.8lux", pcidev->mem[0].bar & ~0x0F);
 		print("zr36067 found at 0x%.8lux", pcidev->mem[0].bar & ~0x0F);
 
 
-		regpa = upamalloc(pcidev->mem[0].bar & ~0x0F, pcidev->mem[0].size, 0);
-		if (regpa == 0) {
+		regpa = pcidev->mem[0].bar & ~0x0F;
+		regva = vmap(regpa, pcidev->mem[0].size, 0);
+		if (regva == 0) {
 			print("lml: failed to map registers\n");
 			print("lml: failed to map registers\n");
 			return;
 			return;
 		}
 		}
-		lml->pciBaseAddr = (ulong)KADDR(regpa);
+		lml->pciBaseAddr = (ulong)regva;
 		print(", mapped at 0x%.8lux\n", lml->pciBaseAddr);
 		print(", mapped at 0x%.8lux\n", lml->pciBaseAddr);
 
 
 		memset(&segbuf, 0, sizeof(segbuf));
 		memset(&segbuf, 0, sizeof(segbuf));

+ 8 - 6
sys/src/9/pc/devpccard.c

@@ -515,6 +515,7 @@ devpccardlink(void)
 	int i;
 	int i;
 	uchar intl;
 	uchar intl;
 	char *p;
 	char *p;
+	void *baddrva;
 
 
 	if (initialized) 
 	if (initialized) 
 		return;
 		return;
@@ -623,14 +624,15 @@ devpccardlink(void)
 		intl = pci->intl;
 		intl = pci->intl;
 
 
 		if ((baddr = pcicfgr32(cb->pci, PciBAR0)) == 0) {
 		if ((baddr = pcicfgr32(cb->pci, PciBAR0)) == 0) {
-			int align = (pci->did == Ricoh_478_did)? 0x10000: 0x1000;
+			int size = (pci->did == Ricoh_478_did)? 0x10000: 0x1000;
 
 
-			baddr = upamalloc(baddr, align, align);
+			baddr = upaalloc(size, size);
+			baddrva = vmap(baddr, size);
 			pcicfgw32(cb->pci, PciBAR0, baddr);
 			pcicfgw32(cb->pci, PciBAR0, baddr);
-			cb->regs = (ulong *)KADDR(baddr);
+			cb->regs = (ulong *)baddrva;
 		}
 		}
 		else
 		else
-			cb->regs = (ulong *)KADDR(upamalloc(baddr, 4096, 0));
+			cb->regs = (ulong *)vmap(baddr, 4096);
 		cb->state = SlotEmpty;
 		cb->state = SlotEmpty;
 
 
 		/* Don't really know what to do with this... */
 		/* Don't really know what to do with this... */
@@ -810,7 +812,7 @@ configure(Cardbus *cb)
 				continue;
 				continue;
 			}
 			}
 
 
-			bar = upamalloc(0, pci->mem[i].size, BY2PG);
+			bar = upaalloc(pci->mem[i].size, BY2PG);
 			pci->mem[i].bar = bar | (pci->mem[i].bar & 0x80);
 			pci->mem[i].bar = bar | (pci->mem[i].bar & 0x80);
 			pcicfgw32(pci, PciBAR0 + i * sizeof(ulong), pci->mem[i].bar);
 			pcicfgw32(pci, PciBAR0 + i * sizeof(ulong), pci->mem[i].bar);
 			pcicfgw32(cb->pci, PciCBMBR0 + memindex * 8, bar);
 			pcicfgw32(cb->pci, PciCBMBR0 + memindex * 8, bar);
@@ -834,7 +836,7 @@ configure(Cardbus *cb)
 				print("#Y%ld: WARNING: Too many memory spaces, not mapping ROM space\n",
 				print("#Y%ld: WARNING: Too many memory spaces, not mapping ROM space\n",
 					cb - cbslots);
 					cb - cbslots);
 			else {
 			else {
-				pci->rom.bar = upamalloc(0, size, BY2PG);
+				pci->rom.bar = upaalloc(size, BY2PG);
 				pci->rom.size = size;
 				pci->rom.size = size;
 
 
 				pcicfgw32(pci, PciEBAR0, pci->rom.bar);
 				pcicfgw32(pci, PciEBAR0, pci->rom.bar);

+ 13 - 13
sys/src/9/pc/devtv.c

@@ -557,7 +557,7 @@ tvinit(void)
 		tv = &tvs[ntvs++];
 		tv = &tvs[ntvs++];
 		tv->variant = &variant[i];
 		tv->variant = &variant[i];
 		tv->pci = pci;
 		tv->pci = pci;
-		tv->bt848 = (Bt848 *)upamalloc(pci->mem[0].bar & ~0x0F, 4 * K, K);
+		tv->bt848 = (Bt848 *)vmap(pci->mem[0].bar & ~0x0F, 4 * K);
 		if (tv->bt848 == nil)
 		if (tv->bt848 == nil)
 			panic("#V: Cannot allocate memory for Bt848");
 			panic("#V: Cannot allocate memory for Bt848");
 		bt848 = tv->bt848;
 		bt848 = tv->bt848;
@@ -591,7 +591,7 @@ tvinit(void)
 				panic("#V: Unsupported Hauppage board");
 				panic("#V: Unsupported Hauppage board");
 
 
 			tv->bt878 = bt878 = 
 			tv->bt878 = bt878 = 
-				(Bt848 *)upamalloc(pci878->mem[0].bar & ~0x0F, 4 * K, K);
+				(Bt848 *)vmap(pci878->mem[0].bar & ~0x0F, 4 * K);
 			if (bt878 == nil)
 			if (bt878 == nil)
 				panic("#V: Cannot allocate memory for the Bt878");
 				panic("#V: Cannot allocate memory for the Bt878");
 
 
@@ -1206,7 +1206,7 @@ i2cwrite(Tv *tv, uchar addr, uchar sub, uchar data, int both)
 }
 }
 
 
 static ulong *
 static ulong *
-riscpacked(ulong paddr, int fnum, int w, int h, int stride, ulong **lastjmp)
+riscpacked(ulong pa, int fnum, int w, int h, int stride, ulong **lastjmp)
 {
 {
 	ulong *p, *pbase;
 	ulong *p, *pbase;
 	int i;
 	int i;
@@ -1224,7 +1224,7 @@ riscpacked(ulong paddr, int fnum, int w, int h, int stride, ulong **lastjmp)
 
 
 	for (i = 0; i != h / 2; i++) {
 	for (i = 0; i != h / 2; i++) {
 		*p++ = riscwrite | w | riscwrite_sol | riscwrite_eol;
 		*p++ = riscwrite | w | riscwrite_sol | riscwrite_eol;
-		*p++ = paddr + i * 2 * stride;
+		*p++ = pa + i * 2 * stride;
 	}
 	}
 
 
 	*p++ = riscsync | riscsync_resync | riscsync_vro;
 	*p++ = riscsync | riscsync_resync | riscsync_vro;
@@ -1235,7 +1235,7 @@ riscpacked(ulong paddr, int fnum, int w, int h, int stride, ulong **lastjmp)
 
 
 	for (i = 0; i != h / 2; i++) {
 	for (i = 0; i != h / 2; i++) {
 		*p++ = riscwrite | w | riscwrite_sol | riscwrite_eol;
 		*p++ = riscwrite | w | riscwrite_sol | riscwrite_eol;
-		*p++ = paddr + (i * 2 + 1) * stride;
+		*p++ = pa + (i * 2 + 1) * stride;
 	}
 	}
 
 
 	// reset status.  you really need two instructions ;-(.
 	// reset status.  you really need two instructions ;-(.
@@ -1248,7 +1248,7 @@ riscpacked(ulong paddr, int fnum, int w, int h, int stride, ulong **lastjmp)
 }
 }
 
 
 static ulong *
 static ulong *
-riscplanar411(ulong paddr, int fnum, int w, int h, ulong **lastjmp)
+riscplanar411(ulong pa, int fnum, int w, int h, ulong **lastjmp)
 {
 {
 	ulong *p, *pbase, Cw, Yw, Ch;
 	ulong *p, *pbase, Cw, Yw, Ch;
 	uchar *Ybase, *Cbbase, *Crbase;
 	uchar *Ybase, *Cbbase, *Crbase;
@@ -1260,7 +1260,7 @@ riscplanar411(ulong paddr, int fnum, int w, int h, ulong **lastjmp)
 	assert(p);
 	assert(p);
 
 
 	Yw = w;
 	Yw = w;
-	Ybase = (uchar *)paddr;
+	Ybase = (uchar *)pa;
 	Cw = w >> 1;
 	Cw = w >> 1;
 	Ch = h >> 1;
 	Ch = h >> 1;
 	Cbbase = Ybase + Yw * h;
 	Cbbase = Ybase + Yw * h;
@@ -1302,7 +1302,7 @@ riscplanar411(ulong paddr, int fnum, int w, int h, ulong **lastjmp)
 }
 }
 
 
 static ulong *
 static ulong *
-riscplanar422(ulong paddr, int fnum, int w, int h, ulong **lastjmp)
+riscplanar422(ulong pa, int fnum, int w, int h, ulong **lastjmp)
 {
 {
 	ulong *p, *pbase, Cw, Yw;
 	ulong *p, *pbase, Cw, Yw;
 	uchar *Ybase, *Cbbase, *Crbase;
 	uchar *Ybase, *Cbbase, *Crbase;
@@ -1314,7 +1314,7 @@ riscplanar422(ulong paddr, int fnum, int w, int h, ulong **lastjmp)
 	assert(p);
 	assert(p);
 
 
 	Yw = w;
 	Yw = w;
-	Ybase = (uchar *)paddr;
+	Ybase = (uchar *)pa;
 	Cw = w >> 1;
 	Cw = w >> 1;
 	Cbbase = Ybase + Yw * h;
 	Cbbase = Ybase + Yw * h;
 	Crbase = Cbbase + Cw * h;
 	Crbase = Cbbase + Cw * h;
@@ -1357,7 +1357,7 @@ riscplanar422(ulong paddr, int fnum, int w, int h, ulong **lastjmp)
 }
 }
 
 
 static ulong *
 static ulong *
-riscaudio(ulong paddr, int nblocks, int bsize)
+riscaudio(ulong pa, int nblocks, int bsize)
 {
 {
 	ulong *p, *pbase;
 	ulong *p, *pbase;
 	int i;
 	int i;
@@ -1372,7 +1372,7 @@ riscaudio(ulong paddr, int nblocks, int bsize)
 		*p++ = riscwrite | riscwrite_sol | riscwrite_eol | bsize | riscirq |
 		*p++ = riscwrite | riscwrite_sol | riscwrite_eol | bsize | riscirq |
 				((i & 0xf) << risclabelshift_set) | 
 				((i & 0xf) << risclabelshift_set) | 
 				((~i & 0xf) << risclabelshift_reset);
 				((~i & 0xf) << risclabelshift_reset);
-		*p++ = paddr + i * bsize;
+		*p++ = pa + i * bsize;
 	}
 	}
 
 
 	*p++ = riscsync | riscsync_vro;
 	*p++ = riscsync | riscsync_vro;
@@ -1556,7 +1556,7 @@ astop(Tv *tv)
 }
 }
 
 
 static void
 static void
-vgastart(Tv *tv, ulong paddr, int stride)
+vgastart(Tv *tv, ulong pa, int stride)
 {
 {
 	Frame *frame;
 	Frame *frame;
 
 
@@ -1568,7 +1568,7 @@ vgastart(Tv *tv, ulong paddr, int stride)
 	}
 	}
 
 
 	frame->fbase = nil;
 	frame->fbase = nil;
-	frame->fstart = riscpacked(paddr, 0, ntsc_hactive * getbitspp(tv) / 8, 
+	frame->fstart = riscpacked(pa, 0, ntsc_hactive * getbitspp(tv) / 8, 
 						   ntsc_vactive, stride * getbitspp(tv) / 8, 
 						   ntsc_vactive, stride * getbitspp(tv) / 8, 
 						   &frame->fjmp);
 						   &frame->fjmp);
 	*frame->fjmp = PADDR(frame->fstart);
 	*frame->fjmp = PADDR(frame->fstart);

+ 33 - 5
sys/src/9/pc/devvga.c

@@ -6,6 +6,7 @@
 #include "mem.h"
 #include "mem.h"
 #include "dat.h"
 #include "dat.h"
 #include "fns.h"
 #include "fns.h"
+#include "io.h"
 #include "../port/error.h"
 #include "../port/error.h"
 
 
 #define	Image	IMAGE
 #define	Image	IMAGE
@@ -16,6 +17,7 @@
 
 
 enum {
 enum {
 	Qdir,
 	Qdir,
+	Qvgabios,
 	Qvgactl,
 	Qvgactl,
 	Qvgaovl,
 	Qvgaovl,
 	Qvgaovlctl,
 	Qvgaovlctl,
@@ -23,6 +25,7 @@ enum {
 
 
 static Dirtab vgadir[] = {
 static Dirtab vgadir[] = {
 	".",	{ Qdir, 0, QTDIR },		0,	0550,
 	".",	{ Qdir, 0, QTDIR },		0,	0550,
+	"vgabios",	{ Qvgabios, 0 },	0x100000, 0440,
 	"vgactl",		{ Qvgactl, 0 },		0,	0660,
 	"vgactl",		{ Qvgactl, 0 },		0,	0660,
 	"vgaovl",		{ Qvgaovl, 0 },		0,	0660,
 	"vgaovl",		{ Qvgaovl, 0 },		0,	0660,
 	"vgaovlctl",	{ Qvgaovlctl, 0 },	0, 	0660,
 	"vgaovlctl",	{ Qvgaovlctl, 0 },	0, 	0660,
@@ -40,6 +43,7 @@ enum {
 	CMpalettedepth,
 	CMpalettedepth,
 	CMpanning,
 	CMpanning,
 	CMsize,
 	CMsize,
+	CMtextmode,
 	CMtype,
 	CMtype,
 	CMunblank,
 	CMunblank,
 };
 };
@@ -56,6 +60,7 @@ static Cmdtab vgactlmsg[] = {
 	CMpalettedepth,	"palettedepth",	2,
 	CMpalettedepth,	"palettedepth",	2,
 	CMpanning,	"panning",	2,
 	CMpanning,	"panning",	2,
 	CMsize,		"size",		3,
 	CMsize,		"size",		3,
+	CMtextmode,	"textmode",	1,
 	CMtype,		"type",		2,
 	CMtype,		"type",		2,
 	CMunblank,	"unblank",	1,
 	CMunblank,	"unblank",	1,
 };
 };
@@ -153,6 +158,14 @@ vgaread(Chan* c, void* a, long n, vlong off)
 	case Qdir:
 	case Qdir:
 		return devdirread(c, a, n, vgadir, nelem(vgadir), devgen);
 		return devdirread(c, a, n, vgadir, nelem(vgadir), devgen);
 
 
+	case Qvgabios:
+		if(offset >= 0x100000)
+			return 0;
+		if(offset+n >= 0x100000)
+			n = 0x100000 - offset;
+		memmove(a, (uchar*)kaddr(0)+offset, n);
+		return n;
+
 	case Qvgactl:
 	case Qvgactl:
 		scr = &vgascreen[0];
 		scr = &vgascreen[0];
 
 
@@ -186,7 +199,9 @@ vgaread(Chan* c, void* a, long n, vlong off)
 		len += snprint(p+len, READSTR-len, "hwaccel %s\n", hwaccel ? "on" : "off");
 		len += snprint(p+len, READSTR-len, "hwaccel %s\n", hwaccel ? "on" : "off");
 		len += snprint(p+len, READSTR-len, "hwblank %s\n", hwblank ? "on" : "off");
 		len += snprint(p+len, READSTR-len, "hwblank %s\n", hwblank ? "on" : "off");
 		len += snprint(p+len, READSTR-len, "panning %s\n", panning ? "on" : "off");
 		len += snprint(p+len, READSTR-len, "panning %s\n", panning ? "on" : "off");
-		snprint(p+len, READSTR-len, "addr 0x%lux\n", scr->aperture);
+		len += snprint(p+len, READSTR-len, "addr p 0x%lux v 0x%p size 0x%ux\n", scr->paddr, scr->vaddr, scr->apsize);
+		USED(len);
+
 		n = readstr(offset, a, n, p);
 		n = readstr(offset, a, n, p);
 		poperror();
 		poperror();
 		free(p);
 		free(p);
@@ -233,7 +248,17 @@ vgactl(Cmdbuf *cb)
 			unlock(&cursor);
 			unlock(&cursor);
 			return;
 			return;
 		}
 		}
-
+		if(strcmp(cb->f[1], "soft") == 0){
+			lock(&cursor);
+			swcursorinit();
+			if(scr->cur && scr->cur->disable)
+				scr->cur->disable(scr);
+			scr->cur = &swcursor;
+			if(scr->cur->enable)
+				scr->cur->enable(scr);
+			unlock(&cursor);
+			return;
+		}
 		for(i = 0; vgacur[i]; i++){
 		for(i = 0; vgacur[i]; i++){
 			if(strcmp(cb->f[1], vgacur[i]->name))
 			if(strcmp(cb->f[1], vgacur[i]->name))
 				continue;
 				continue;
@@ -261,9 +286,11 @@ vgactl(Cmdbuf *cb)
 		}
 		}
 		break;
 		break;
 
 
+	case CMtextmode:
+		screeninit();
+		return;
+
 	case CMsize:
 	case CMsize:
-		if(drawhasclients())
-			error(Ebusy);
 
 
 		x = strtoul(cb->f[1], &p, 0);
 		x = strtoul(cb->f[1], &p, 0);
 		if(x == 0 || x > 2048)
 		if(x == 0 || x > 2048)
@@ -291,6 +318,7 @@ vgactl(Cmdbuf *cb)
 		if(screensize(x, y, z, chan))
 		if(screensize(x, y, z, chan))
 			error(Egreg);
 			error(Egreg);
 		vgascreenwin(scr);
 		vgascreenwin(scr);
+		resetscreenimage();
 		cursoron(1);
 		cursoron(1);
 		return;
 		return;
 
 
@@ -337,7 +365,7 @@ vgactl(Cmdbuf *cb)
 			align = 0;
 			align = 0;
 		else
 		else
 			align = strtoul(cb->f[2], 0, 0);
 			align = strtoul(cb->f[2], 0, 0);
-		if(screenaperture(size, align))
+		if(screenaperture(size, align) < 0)
 			error("not enough free address space");
 			error("not enough free address space");
 		return;
 		return;
 /*	
 /*	

+ 3 - 4
sys/src/9/pc/dma.c

@@ -140,10 +140,9 @@ dmasetup(int chan, void *va, long len, int isread)
 	 *  if this isn't kernel memory or crossing 64k boundary or above 16 meg
 	 *  if this isn't kernel memory or crossing 64k boundary or above 16 meg
 	 *  use the bounce buffer.
 	 *  use the bounce buffer.
 	 */
 	 */
-	pa = PADDR(va);
-	if((((ulong)va)&0xF0000000) != KZERO
-	|| (pa&0xFFFF0000) != ((pa+len)&0xFFFF0000)
-	|| pa >= 16*MB) {
+	if((ulong)va < KZERO 
+	|| ((pa=PADDR(va))&0xFFFF0000) != ((pa+len)&0xFFFF0000)
+	|| pa >= 16*MB){
 		if(xp->bva == nil)
 		if(xp->bva == nil)
 			return -1;
 			return -1;
 		if(len > xp->blen)
 		if(len > xp->blen)

+ 0 - 3
sys/src/9/pc/ether79c970.c

@@ -522,7 +522,6 @@ reset(Ether* ether)
 		ctlr->iow = io32w;
 		ctlr->iow = io32w;
 	}else{
 	}else{
 		print("#l%d: card doesn't talk right\n", ether->ctlrno);
 		print("#l%d: card doesn't talk right\n", ether->ctlrno);
-iprint("#l%d: card doesn't talk right\n", ether->ctlrno);
 		iunlock(ctlr);
 		iunlock(ctlr);
 		return -1;
 		return -1;
 	}
 	}
@@ -539,8 +538,6 @@ iprint("#l%d: card doesn't talk right\n", ether->ctlrno);
 	default:
 	default:
 		print("#l%d: unknown PCnet card version %.7ux\n",
 		print("#l%d: unknown PCnet card version %.7ux\n",
 			ether->ctlrno, x&0xFFFFFFF);
 			ether->ctlrno, x&0xFFFFFFF);
-iprint("#l%d: unknown PCnet card version %.7ux\n",
-			ether->ctlrno, x&0xFFFFFFF);
 		iunlock(ctlr);
 		iunlock(ctlr);
 		return -1;
 		return -1;
 	}
 	}

+ 17 - 17
sys/src/9/pc/ether8139.c

@@ -243,7 +243,7 @@ rtl8139ifstat(Ether* edev, void* a, long n, ulong offset)
 
 
 	ctlr = edev->ctlr;
 	ctlr = edev->ctlr;
 	p = malloc(READSTR);
 	p = malloc(READSTR);
-	l = snprint(p, READSTR, "rcr %8.8uX\n", ctlr->rcr);
+	l = snprint(p, READSTR, "rcr %#8.8ux\n", ctlr->rcr);
 	l += snprint(p+l, READSTR-l, "ierrs %d\n", ctlr->ierrs);
 	l += snprint(p+l, READSTR-l, "ierrs %d\n", ctlr->ierrs);
 	l += snprint(p+l, READSTR-l, "etxth %d\n", ctlr->etxth);
 	l += snprint(p+l, READSTR-l, "etxth %d\n", ctlr->etxth);
 	l += snprint(p+l, READSTR-l, "taligned %d\n", ctlr->taligned);
 	l += snprint(p+l, READSTR-l, "taligned %d\n", ctlr->taligned);
@@ -255,20 +255,20 @@ rtl8139ifstat(Ether* edev, void* a, long n, ulong offset)
 	ctlr->rec += csr16r(ctlr, Rec);
 	ctlr->rec += csr16r(ctlr, Rec);
 	l += snprint(p+l, READSTR-l, "rec %d\n", ctlr->rec);
 	l += snprint(p+l, READSTR-l, "rec %d\n", ctlr->rec);
 
 
-	l += snprint(p+l, READSTR-l, "Tcr %8.8luX\n", csr32r(ctlr, Tcr));
-	l += snprint(p+l, READSTR-l, "Config0 %2.2uX\n", csr8r(ctlr, Config0));
-	l += snprint(p+l, READSTR-l, "Config1 %2.2uX\n", csr8r(ctlr, Config1));
-	l += snprint(p+l, READSTR-l, "Msr %2.2uX\n", csr8r(ctlr, Msr));
-	l += snprint(p+l, READSTR-l, "Config3 %2.2uX\n", csr8r(ctlr, Config3));
-	l += snprint(p+l, READSTR-l, "Config4 %2.2uX\n", csr8r(ctlr, Config4));
-
-	l += snprint(p+l, READSTR-l, "Bmcr %4.4uX\n", csr16r(ctlr, Bmcr));
-	l += snprint(p+l, READSTR-l, "Bmsr %4.4uX\n", csr16r(ctlr, Bmsr));
-	l += snprint(p+l, READSTR-l, "Anar %4.4uX\n", csr16r(ctlr, Anar));
-	l += snprint(p+l, READSTR-l, "Anlpar %4.4uX\n", csr16r(ctlr, Anlpar));
-	l += snprint(p+l, READSTR-l, "Aner %4.4uX\n", csr16r(ctlr, Aner));
-	l += snprint(p+l, READSTR-l, "Nwaytr %4.4uX\n", csr16r(ctlr, Nwaytr));
-	snprint(p+l, READSTR-l, "Cscr %4.4uX\n", csr16r(ctlr, Cscr));
+	l += snprint(p+l, READSTR-l, "Tcr %#8.8lux\n", csr32r(ctlr, Tcr));
+	l += snprint(p+l, READSTR-l, "Config0 %#2.2ux\n", csr8r(ctlr, Config0));
+	l += snprint(p+l, READSTR-l, "Config1 %#2.2ux\n", csr8r(ctlr, Config1));
+	l += snprint(p+l, READSTR-l, "Msr %#2.2ux\n", csr8r(ctlr, Msr));
+	l += snprint(p+l, READSTR-l, "Config3 %#2.2ux\n", csr8r(ctlr, Config3));
+	l += snprint(p+l, READSTR-l, "Config4 %#2.2ux\n", csr8r(ctlr, Config4));
+
+	l += snprint(p+l, READSTR-l, "Bmcr %#4.4ux\n", csr16r(ctlr, Bmcr));
+	l += snprint(p+l, READSTR-l, "Bmsr %#4.4ux\n", csr16r(ctlr, Bmsr));
+	l += snprint(p+l, READSTR-l, "Anar %#4.4ux\n", csr16r(ctlr, Anar));
+	l += snprint(p+l, READSTR-l, "Anlpar %#4.4ux\n", csr16r(ctlr, Anlpar));
+	l += snprint(p+l, READSTR-l, "Aner %#4.4ux\n", csr16r(ctlr, Aner));
+	l += snprint(p+l, READSTR-l, "Nwaytr %#4.4ux\n", csr16r(ctlr, Nwaytr));
+	snprint(p+l, READSTR-l, "Cscr %#4.4ux\n", csr16r(ctlr, Cscr));
 	n = readstr(offset, a, n, p);
 	n = readstr(offset, a, n, p);
 	free(p);
 	free(p);
 
 
@@ -589,7 +589,7 @@ rtl8139interrupt(Ureg*, void* arg)
 		 * other than try to reinitialise the chip?
 		 * other than try to reinitialise the chip?
 		 */
 		 */
 		if((isr & (Serr|Timerbit)) != 0){
 		if((isr & (Serr|Timerbit)) != 0){
-			iprint("rtl8139interrupt: imr %4.4uX isr %4.4uX\n",
+			iprint("rtl8139interrupt: imr %#4.4ux isr %#4.4ux\n",
 				csr16r(ctlr, Imr), isr);
 				csr16r(ctlr, Imr), isr);
 			if(isr & Timerbit)
 			if(isr & Timerbit)
 				csr32w(ctlr, TimerInt, 0);
 				csr32w(ctlr, TimerInt, 0);
@@ -621,7 +621,7 @@ rtl8139match(Ether* edev, int id)
 			continue;
 			continue;
 
 
 		if(ioalloc(port, p->mem[0].size, 0, "rtl8139") < 0){
 		if(ioalloc(port, p->mem[0].size, 0, "rtl8139") < 0){
-			print("rtl8139: port 0x%uX in use\n", port);
+			print("rtl8139: port %#ux in use\n", port);
 			continue;
 			continue;
 		}
 		}
 
 

+ 8 - 7
sys/src/9/pc/ether8169.c

@@ -357,7 +357,8 @@ rtl8169mii(Ctlr* ctlr)
 		ctlr->mii = nil;
 		ctlr->mii = nil;
 		return -1;
 		return -1;
 	}
 	}
-	print("oui %X phyno %d\n", phy->oui, phy->phyno);
+	USED(phy);
+	// print("oui %X phyno %d\n", phy->oui, phy->phyno);
 
 
 	miiane(ctlr->mii, ~0, ~0, ~0);
 	miiane(ctlr->mii, ~0, ~0, ~0);
 
 
@@ -451,8 +452,8 @@ rtl8169ifstat(Ether* edev, void* a, long n, ulong offset)
 	l += snprint(p+l, READSTR-l, "punlc: %ud\n", ctlr->punlc);
 	l += snprint(p+l, READSTR-l, "punlc: %ud\n", ctlr->punlc);
 	l += snprint(p+l, READSTR-l, "fovw: %ud\n", ctlr->fovw);
 	l += snprint(p+l, READSTR-l, "fovw: %ud\n", ctlr->fovw);
 
 
-	l += snprint(p+l, READSTR-l, "tcr: %8.8uX\n", ctlr->tcr);
-	l += snprint(p+l, READSTR-l, "rcr: %8.8uX\n", ctlr->rcr);
+	l += snprint(p+l, READSTR-l, "tcr: %#8.8ux\n", ctlr->tcr);
+	l += snprint(p+l, READSTR-l, "rcr: %#8.8ux\n", ctlr->rcr);
 
 
 	if(ctlr->mii != nil && ctlr->mii->curphy != nil){
 	if(ctlr->mii != nil && ctlr->mii->curphy != nil){
 		l += snprint(p+l, READSTR, "phy:   ");
 		l += snprint(p+l, READSTR, "phy:   ");
@@ -460,7 +461,7 @@ rtl8169ifstat(Ether* edev, void* a, long n, ulong offset)
 			if(i && ((i & 0x07) == 0))
 			if(i && ((i & 0x07) == 0))
 				l += snprint(p+l, READSTR-l, "\n       ");
 				l += snprint(p+l, READSTR-l, "\n       ");
 			r = miimir(ctlr->mii, i);
 			r = miimir(ctlr->mii, i);
-			l += snprint(p+l, READSTR-l, " %4.4uX", r);
+			l += snprint(p+l, READSTR-l, " %4.4ux", r);
 		}
 		}
 		snprint(p+l, READSTR-l, "\n");
 		snprint(p+l, READSTR-l, "\n");
 	}
 	}
@@ -811,7 +812,7 @@ rtl8169receive(Ether* edev)
 		else{
 		else{
 			/*
 			/*
 			 * Error stuff here.
 			 * Error stuff here.
-			print("control %8.8uX\n", control);
+			print("control %#8.8ux\n", control);
 			 */
 			 */
 		}
 		}
 		d->control &= Eor;
 		d->control &= Eor;
@@ -865,7 +866,7 @@ rtl8169interrupt(Ureg*, void* arg)
 		 * Some of the reserved bits get set sometimes...
 		 * Some of the reserved bits get set sometimes...
 		 */
 		 */
 		if(isr & (Serr|Timeout|Tdu|Fovw|Punlc|Rdu|Ter|Tok|Rer|Rok))
 		if(isr & (Serr|Timeout|Tdu|Fovw|Punlc|Rdu|Ter|Tok|Rer|Rok))
-			panic("rtl8169interrupt: imr %4.4uX isr %4.4uX\n",
+			panic("rtl8169interrupt: imr %#4.4ux isr %#4.4ux\n",
 				csr16r(ctlr, Imr), isr);
 				csr16r(ctlr, Imr), isr);
 	}
 	}
 }
 }
@@ -892,7 +893,7 @@ rtl8169match(Ether* edev, int id)
 			continue;
 			continue;
 
 
 		if(ioalloc(port, p->mem[0].size, 0, "rtl8169") < 0){
 		if(ioalloc(port, p->mem[0].size, 0, "rtl8169") < 0){
-			print("rtl8169: port 0x%uX in use\n", port);
+			print("rtl8169: port %#ux in use\n", port);
 			continue;
 			continue;
 		}
 		}
 
 

+ 6 - 6
sys/src/9/pc/ether82543gc.c

@@ -1243,7 +1243,8 @@ gc82543watchdog(void* arg)
 static void
 static void
 gc82543pci(void)
 gc82543pci(void)
 {
 {
-	int port, cls;
+	int cls;
+	void *mem;
 	Pcidev *p;
 	Pcidev *p;
 	Ctlr *ctlr;
 	Ctlr *ctlr;
 
 
@@ -1262,8 +1263,8 @@ gc82543pci(void)
 			break;
 			break;
 		}
 		}
 
 
-		port = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
-		if(port == 0){
+		mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
+		if(mem == 0){
 			print("gc82543: can't map %8.8luX\n", p->mem[0].bar);
 			print("gc82543: can't map %8.8luX\n", p->mem[0].bar);
 			continue;
 			continue;
 		}
 		}
@@ -1280,11 +1281,10 @@ gc82543pci(void)
 					cls*4);
 					cls*4);
 		}
 		}
 		ctlr = malloc(sizeof(Ctlr));
 		ctlr = malloc(sizeof(Ctlr));
-		ctlr->port = port;
+		ctlr->port = p->mem[0].bar & ~0x0F;
 		ctlr->pcidev = p;
 		ctlr->pcidev = p;
 		ctlr->id = (p->did<<16)|p->vid;
 		ctlr->id = (p->did<<16)|p->vid;
-
-		ctlr->nic = KADDR(ctlr->port);
+		ctlr->nic = mem;
 
 
 		if(gc82543reset(ctlr)){
 		if(gc82543reset(ctlr)){
 			free(ctlr);
 			free(ctlr);

+ 10 - 10
sys/src/9/pc/ether82557.c

@@ -290,7 +290,7 @@ command(Ctlr* ctlr, int c, int v)
 	if(timeo >= 100){
 	if(timeo >= 100){
 		ctlr->command = -1;
 		ctlr->command = -1;
 		iunlock(&ctlr->rlock);
 		iunlock(&ctlr->rlock);
-		iprint("i82557: command 0x%uX %uX timeout\n", c, v);
+		iprint("i82557: command %#ux %#ux timeout\n", c, v);
 		return;
 		return;
 	}
 	}
 
 
@@ -462,7 +462,7 @@ ifstat(Ether* ether, void* a, long n, ulong offset)
 	for(i = 0; i < (1<<ctlr->eepromsz); i++){
 	for(i = 0; i < (1<<ctlr->eepromsz); i++){
 		if(i && ((i & 0x07) == 0))
 		if(i && ((i & 0x07) == 0))
 			len += snprint(p+len, READSTR-len, "\n       ");
 			len += snprint(p+len, READSTR-len, "\n       ");
-		len += snprint(p+len, READSTR-len, " %4.4uX", ctlr->eeprom[i]);
+		len += snprint(p+len, READSTR-len, " %4.4ux", ctlr->eeprom[i]);
 	}
 	}
 
 
 	if((ctlr->eeprom[6] & 0x1F00) && !(ctlr->eeprom[6] & 0x8000)){
 	if((ctlr->eeprom[6] & 0x1F00) && !(ctlr->eeprom[6] & 0x8000)){
@@ -471,7 +471,7 @@ ifstat(Ether* ether, void* a, long n, ulong offset)
 		for(i = 0; i < 6; i++){
 		for(i = 0; i < 6; i++){
 			static int miir(Ctlr*, int, int);
 			static int miir(Ctlr*, int, int);
 
 
-			len += snprint(p+len, READSTR-len, " %4.4uX",
+			len += snprint(p+len, READSTR-len, " %4.4ux",
 				miir(ctlr, phyaddr, i));
 				miir(ctlr, phyaddr, i));
 		}
 		}
 	}
 	}
@@ -523,7 +523,7 @@ txstart(Ether* ether)
 			ctlr->action = 0;
 			ctlr->action = 0;
 		}
 		}
 		else{
 		else{
-			print("#l%d: action 0x%uX\n", ether->ctlrno, ctlr->action);
+			print("#l%d: action %#ux\n", ether->ctlrno, ctlr->action);
 			ctlr->action = 0;
 			ctlr->action = 0;
 			break;
 			break;
 		}
 		}
@@ -630,14 +630,14 @@ receive(Ether* ether)
 			pbp = nil;
 			pbp = nil;
 			count = rfd->count & 0x3FFF;
 			count = rfd->count & 0x3FFF;
 			if((count < ETHERMAXTU/4) && (pbp = iallocb(count))){
 			if((count < ETHERMAXTU/4) && (pbp = iallocb(count))){
-				memmove(pbp->rp, bp->rp+sizeof(Rfd)-sizeof(rfd->data), count);
+				memmove(pbp->rp, bp->rp+offsetof(Rfd, data[0]), count);
 				pbp->wp = pbp->rp + count;
 				pbp->wp = pbp->rp + count;
 
 
 				rfd->count = 0;
 				rfd->count = 0;
 				rfd->field = 0;
 				rfd->field = 0;
 			}
 			}
 			else if(xbp = rfdalloc(rfd->link)){
 			else if(xbp = rfdalloc(rfd->link)){
-				bp->rp += sizeof(Rfd)-sizeof(rfd->data);
+				bp->rp += offsetof(Rfd, data[0]);
 				bp->wp = bp->rp + count;
 				bp->wp = bp->rp + count;
 
 
 				xbp->next = bp->next;
 				xbp->next = bp->next;
@@ -748,7 +748,7 @@ interrupt(Ureg*, void* arg)
 		}
 		}
 
 
 		if(status & (StatCX|StatFR|StatCNA|StatRNR|StatMDI|StatSWI))
 		if(status & (StatCX|StatFR|StatCNA|StatRNR|StatMDI|StatSWI))
-			panic("#l%d: status %uX\n", ether->ctlrno, status);
+			panic("#l%d: status %#ux\n", ether->ctlrno, status);
 	}
 	}
 }
 }
 
 
@@ -955,7 +955,7 @@ i82557pci(void)
 		 */
 		 */
 		port = p->mem[1].bar & ~0x01;
 		port = p->mem[1].bar & ~0x01;
 		if(ioalloc(port, p->mem[1].size, 0, "i82557") < 0){
 		if(ioalloc(port, p->mem[1].size, 0, "i82557") < 0){
-			print("i82557: port 0x%uX in use\n", port);
+			print("i82557: port %#ux in use\n", port);
 			continue;
 			continue;
 		}
 		}
 
 
@@ -997,7 +997,7 @@ scanphy(Ctlr* ctlr)
 		oui <<= 6;
 		oui <<= 6;
 		x = miir(ctlr, i, 3);
 		x = miir(ctlr, i, 3);
 		oui |= x>>10;
 		oui |= x>>10;
-		//print("phy%d: oui %uX reg1 %uX\n", i, oui, miir(ctlr, i, 1));
+		//print("phy%d: oui %#ux reg1 %#ux\n", i, oui, miir(ctlr, i, 1));
 
 
 		ctlr->eeprom[6] = i;
 		ctlr->eeprom[6] = i;
 		if(oui == 0xAA00)
 		if(oui == 0xAA00)
@@ -1093,7 +1093,7 @@ reset(Ether* ether)
 		sum += x;
 		sum += x;
 	}
 	}
 	if(sum != 0xBABA)
 	if(sum != 0xBABA)
-		print("#l%d: EEPROM checksum - 0x%4.4uX\n", ether->ctlrno, sum);
+		print("#l%d: EEPROM checksum - %#4.4ux\n", ether->ctlrno, sum);
 
 
 	/*
 	/*
 	 * Eeprom[6] indicates whether there is a PHY and whether
 	 * Eeprom[6] indicates whether there is a PHY and whether

+ 2 - 0
sys/src/9/pc/ether83815.c

@@ -81,6 +81,7 @@ enum {	/* cmdsts */
 
 
 enum {				/* Variants */
 enum {				/* Variants */
 	Nat83815	= (0x0020<<16)|0x100B,
 	Nat83815	= (0x0020<<16)|0x100B,
+	Sis900 = (0x0630<<16)|0x1039,	/* untested */
 };
 };
 
 
 typedef struct Ctlr Ctlr;
 typedef struct Ctlr Ctlr;
@@ -841,6 +842,7 @@ scanpci83815(void)
 			continue;
 			continue;
 
 
 		case Nat83815:
 		case Nat83815:
+		case Sis900:
 			break;
 			break;
 		}
 		}
 
 

+ 3 - 3
sys/src/9/pc/ether8390.c

@@ -400,7 +400,7 @@ receive(Ether* ether)
 		 */
 		 */
 		if(hdr.next < ctlr->pstart || hdr.next >= ctlr->pstop
 		if(hdr.next < ctlr->pstart || hdr.next >= ctlr->pstop
 		  || len < 60 || len > sizeof(Etherpkt)){
 		  || len < 60 || len > sizeof(Etherpkt)){
-			print("dp8390: H#%2.2ux#%2.2ux#%2.2ux#%2.2ux,%lud\n",
+			print("dp8390: H%2.2ux+%2.2ux+%2.2ux+%2.2ux,%lud\n",
 				hdr.status, hdr.next, hdr.len0, hdr.len1, len);
 				hdr.status, hdr.next, hdr.len0, hdr.len1, len);
 			regw(ctlr, Cr, Page0|RdABORT|Stp);
 			regw(ctlr, Cr, Page0|RdABORT|Stp);
 			ringinit(ctlr);
 			ringinit(ctlr);
@@ -588,7 +588,7 @@ interrupt(Ureg*, void* arg)
 		if(isr & (Txe|Ptx)){
 		if(isr & (Txe|Ptx)){
 			r = regr(ctlr, Tsr);
 			r = regr(ctlr, Tsr);
 			if((isr & Txe) && (r & (Cdh|Fu|Crs|Abt))){
 			if((isr & Txe) && (r & (Cdh|Fu|Crs|Abt))){
-				print("dp8390: Tsr#%2.2ux|", r);
+				print("dp8390: Tsr %#2.2ux", r);
 				ether->oerrs++;
 				ether->oerrs++;
 			}
 			}
 
 
@@ -686,7 +686,7 @@ multicast(void* arg, uchar *addr, int on)
 	if(reverse[1] == 0){
 	if(reverse[1] == 0){
 		for(i = 0; i < 64; i++)
 		for(i = 0; i < 64; i++)
 			reverse[i] = ((i&1)<<5) | ((i&2)<<3) | ((i&4)<<1)
 			reverse[i] = ((i&1)<<5) | ((i&2)<<3) | ((i&4)<<1)
-					| ((i&8)>>1) | ((i&16)>>3) | ((i&32)>>5);
+				   | ((i&8)>>1) | ((i&16)>>3) | ((i&32)>>5);
 	}
 	}
 
 
 	/*
 	/*

+ 5 - 5
sys/src/9/pc/etherdp83820.c

@@ -1114,7 +1114,7 @@ print("cfg %8.8uX pcicfg %8.8uX\n", ctlr->cfg, pcicfgr32(ctlr->pcidev, PciPCR));
 static void
 static void
 dp83820pci(void)
 dp83820pci(void)
 {
 {
-	int port;
+	void *mem;
 	Pcidev *p;
 	Pcidev *p;
 	Ctlr *ctlr;
 	Ctlr *ctlr;
 
 
@@ -1130,18 +1130,18 @@ dp83820pci(void)
 			break;
 			break;
 		}
 		}
 
 
-		port = upamalloc(p->mem[1].bar & ~0x0F, p->mem[1].size, 0);
-		if(port == 0){
+		mem = vmap(p->mem[1].bar & ~0x0F, p->mem[1].size);
+		if(mem == 0){
 			print("DP83820: can't map %8.8luX\n", p->mem[1].bar);
 			print("DP83820: can't map %8.8luX\n", p->mem[1].bar);
 			continue;
 			continue;
 		}
 		}
 
 
 		ctlr = malloc(sizeof(Ctlr));
 		ctlr = malloc(sizeof(Ctlr));
-		ctlr->port = port;
+		ctlr->port = p->mem[1].bar & ~0x0F;
 		ctlr->pcidev = p;
 		ctlr->pcidev = p;
 		ctlr->id = (p->did<<16)|p->vid;
 		ctlr->id = (p->did<<16)|p->vid;
 
 
-		ctlr->nic = KADDR(ctlr->port);
+		ctlr->nic = mem;
 		if(dp83820reset(ctlr)){
 		if(dp83820reset(ctlr)){
 			free(ctlr);
 			free(ctlr);
 			continue;
 			continue;

+ 4 - 4
sys/src/9/pc/etherelnk3.c

@@ -1485,15 +1485,15 @@ tcm59Xpci(void)
 			break;
 			break;
 		case 0x5157:
 		case 0x5157:
 			ctlr->eepromcmd = EepromRead8bRegister;
 			ctlr->eepromcmd = EepromRead8bRegister;
-			ctlr->cbfnpa = upamalloc(p->mem[2].bar, p->mem[2].size, 0);
+			ctlr->cbfnpa = p->mem[2].bar&~0x0F;
+			ctlr->cbfn = vmap(p->mem[2].bar&~0x0F, p->mem[2].size);
 			break;
 			break;
 		case 0x6056:
 		case 0x6056:
 			ctlr->eepromcmd = EepromReadOffRegister;
 			ctlr->eepromcmd = EepromReadOffRegister;
-			ctlr->cbfnpa = upamalloc(p->mem[2].bar, p->mem[2].size, 0);
+			ctlr->cbfnpa = p->mem[2].bar&~0x0F;
+			ctlr->cbfn = vmap(p->mem[2].bar&~0x0F, p->mem[2].size);
 			break;
 			break;
 		}
 		}
-		if(ctlr->cbfnpa != 0)
-			ctlr->cbfn = KADDR(ctlr->cbfnpa);
 		pcisetbme(p);
 		pcisetbme(p);
 	}
 	}
 }
 }

+ 6 - 6
sys/src/9/pc/etherga620.c

@@ -758,7 +758,7 @@ ga620init(Ether* edev)
 	 * memory it is accessed via the Local Memory Window; with a send
 	 * memory it is accessed via the Local Memory Window; with a send
 	 * ring size of 128 the window covers the whole ring and then need
 	 * ring size of 128 the window covers the whole ring and then need
 	 * only be set once:
 	 * only be set once:
-	 *	ctlr->sr = KADDR(ctlr->port+Lmw);
+	 *	ctlr->sr = (uchar*)ctlr->nic+Lmw;
 	 *	ga620lmw(ctlr, Sr, nil, sizeof(Sbd)*Nsr);
 	 *	ga620lmw(ctlr, Sr, nil, sizeof(Sbd)*Nsr);
 	 *	ctlr->gib->srcb.addr.lo = Sr;
 	 *	ctlr->gib->srcb.addr.lo = Sr;
 	 * There is nowhere in the Sbd to hold the Block* associated
 	 * There is nowhere in the Sbd to hold the Block* associated
@@ -1114,7 +1114,7 @@ ga620reset(Ctlr* ctlr)
 static void
 static void
 ga620pci(void)
 ga620pci(void)
 {
 {
-	int port;
+	void *mem;
 	Pcidev *p;
 	Pcidev *p;
 	Ctlr *ctlr;
 	Ctlr *ctlr;
 
 
@@ -1135,18 +1135,18 @@ ga620pci(void)
 			break;
 			break;
 		}
 		}
 
 
-		port = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
-		if(port == 0){
+		mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
+		if(mem == 0){
 			print("ga620: can't map %8.8luX\n", p->mem[0].bar);
 			print("ga620: can't map %8.8luX\n", p->mem[0].bar);
 			continue;
 			continue;
 		}
 		}
 
 
 		ctlr = malloc(sizeof(Ctlr));
 		ctlr = malloc(sizeof(Ctlr));
-		ctlr->port = port;
+		ctlr->port = p->mem[0].bar & ~0x0F;
 		ctlr->pcidev = p;
 		ctlr->pcidev = p;
 		ctlr->id = (p->did<<16)|p->vid;
 		ctlr->id = (p->did<<16)|p->vid;
 
 
-		ctlr->nic = KADDR(ctlr->port);
+		ctlr->nic = mem;
 		if(ga620reset(ctlr)){
 		if(ga620reset(ctlr)){
 			free(ctlr);
 			free(ctlr);
 			continue;
 			continue;

+ 10 - 8
sys/src/9/pc/etherigbe.c

@@ -439,7 +439,7 @@ enum {
 
 
 typedef struct Ctlr Ctlr;
 typedef struct Ctlr Ctlr;
 typedef struct Ctlr {
 typedef struct Ctlr {
-	int	port;
+	ulong	port;
 	Pcidev*	pcidev;
 	Pcidev*	pcidev;
 	Ctlr*	next;
 	Ctlr*	next;
 	int	active;
 	int	active;
@@ -1468,7 +1468,8 @@ igbemii(Ctlr* ctlr)
 		ctlr->mii = nil;
 		ctlr->mii = nil;
 		return -1;
 		return -1;
 	}
 	}
-	print("oui %X phyno %d\n", phy->oui, phy->phyno);
+	USED(phy);
+	// print("oui %X phyno %d\n", phy->oui, phy->phyno);
 
 
 	/*
 	/*
 	 * 8254X-specific PHY registers not in 802.3:
 	 * 8254X-specific PHY registers not in 802.3:
@@ -1848,10 +1849,11 @@ igbereset(Ctlr* ctlr)
 static void
 static void
 igbepci(void)
 igbepci(void)
 {
 {
-	int port, cls;
+	int cls;
 	Pcidev *p;
 	Pcidev *p;
 	Ctlr *ctlr;
 	Ctlr *ctlr;
-
+	void *mem;
+	
 	p = nil;
 	p = nil;
 	while(p = pcimatch(p, 0, 0)){
 	while(p = pcimatch(p, 0, 0)){
 		if(p->ccrb != 0x02 || p->ccru != 0)
 		if(p->ccrb != 0x02 || p->ccru != 0)
@@ -1874,8 +1876,8 @@ igbepci(void)
 			break;
 			break;
 		}
 		}
 
 
-		port = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
-		if(port == 0){
+		mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
+		if(mem == nil){
 			print("igbe: can't map %8.8luX\n", p->mem[0].bar);
 			print("igbe: can't map %8.8luX\n", p->mem[0].bar);
 			continue;
 			continue;
 		}
 		}
@@ -1893,11 +1895,11 @@ igbepci(void)
 				break;
 				break;
 		}
 		}
 		ctlr = malloc(sizeof(Ctlr));
 		ctlr = malloc(sizeof(Ctlr));
-		ctlr->port = port;
+		ctlr->port = p->mem[0].bar & ~0x0F;
 		ctlr->pcidev = p;
 		ctlr->pcidev = p;
 		ctlr->id = (p->did<<16)|p->vid;
 		ctlr->id = (p->did<<16)|p->vid;
 		ctlr->cls = cls*4;
 		ctlr->cls = cls*4;
-		ctlr->nic = KADDR(ctlr->port);
+		ctlr->nic = mem;
 
 
 		if(igbereset(ctlr)){
 		if(igbereset(ctlr)){
 			free(ctlr);
 			free(ctlr);

+ 1 - 1
sys/src/9/pc/ethervt6102.c

@@ -925,7 +925,7 @@ vt6102reset(Ctlr* ctlr)
 		ctlr->mii = nil;
 		ctlr->mii = nil;
 		return -1;
 		return -1;
 	}
 	}
-	print("oui %X phyno %d\n", phy->oui, phy->phyno);
+	// print("oui %X phyno %d\n", phy->oui, phy->phyno);
 
 
 	//miiane(ctlr->mii, ~0, ~0, ~0);
 	//miiane(ctlr->mii, ~0, ~0, ~0);
 
 

+ 6 - 5
sys/src/9/pc/etherwavelan.c

@@ -87,6 +87,7 @@ static struct {
 	int did;
 	int did;
 } wavelanpci[] = {
 } wavelanpci[] = {
 	0x1260, 0x3873,	/* Intersil Prism2.5 */
 	0x1260, 0x3873,	/* Intersil Prism2.5 */
+	0x1737,	0x0019,	/* Linksys WPC-11 untested */
 };
 };
 
 
 static Ctlr *ctlrhead, *ctlrtail;
 static Ctlr *ctlrhead, *ctlrtail;
@@ -95,7 +96,7 @@ static void
 wavelanpciscan(void)
 wavelanpciscan(void)
 {
 {
 	int i;
 	int i;
-	ulong pa;
+	void *mem;
 	Pcidev *p;
 	Pcidev *p;
 	Ctlr *ctlr;
 	Ctlr *ctlr;
 
 
@@ -117,13 +118,13 @@ wavelanpciscan(void)
 
 
 		ctlr = malloc(sizeof(Ctlr));
 		ctlr = malloc(sizeof(Ctlr));
 		ctlr->pcidev = p;
 		ctlr->pcidev = p;
-		pa = upamalloc(p->mem[0].bar&~0xF, p->mem[0].size, 0);
-		if(pa == 0){
-			print("wavelanpci: %.4ux %.4ux: upamalloc 0x%.8lux %d failed\n", p->vid, p->did, p->mem[0].bar&~0xF, p->mem[0].size);
+		mem = vmap(p->mem[0].bar&~0xF, p->mem[0].size);
+		if(mem == nil){
+			print("wavelanpci: %.4ux %.4ux: vmap 0x%.8lux %d failed\n", p->vid, p->did, p->mem[0].bar&~0xF, p->mem[0].size);
 			free(ctlr);
 			free(ctlr);
 			continue;
 			continue;
 		}
 		}
-		ctlr->mmb = (ushort*)KADDR(pa);
+		ctlr->mmb = mem;
 		if(ctlrhead != nil)
 		if(ctlrhead != nil)
 			ctlrtail->next = ctlr;
 			ctlrtail->next = ctlr;
 		else
 		else

+ 24 - 10
sys/src/9/pc/fns.h

@@ -3,9 +3,7 @@
 void	aamloop(int);
 void	aamloop(int);
 Dirtab*	addarchfile(char*, int, long(*)(Chan*,void*,long,vlong), long(*)(Chan*,void*,long,vlong));
 Dirtab*	addarchfile(char*, int, long(*)(Chan*,void*,long,vlong), long(*)(Chan*,void*,long,vlong));
 void	archinit(void);
 void	archinit(void);
-void	bootargs(ulong);
-int	cistrcmp(char*, char*);
-int	cistrncmp(char*, char*, int);
+void	bootargs(void*);
 void	clockintr(Ureg*, void*);
 void	clockintr(Ureg*, void*);
 void	(*coherence)(void);
 void	(*coherence)(void);
 void	cpuid(char*, int*, int*);
 void	cpuid(char*, int*, int*);
@@ -46,11 +44,13 @@ void	i8253init(void);
 void	i8253link(void);
 void	i8253link(void);
 uvlong	i8253read(uvlong*);
 uvlong	i8253read(uvlong*);
 void	i8253timerset(uvlong);
 void	i8253timerset(uvlong);
+int	i8259disable(int);
+int	i8259enable(Vctl*);
 void	i8259init(void);
 void	i8259init(void);
 int	i8259isr(int);
 int	i8259isr(int);
-int	i8259enable(Vctl*);
+void	i8259on(void);
+void	i8259off(void);
 int	i8259vecno(int);
 int	i8259vecno(int);
-int	i8259disable(int);
 void	idle(void);
 void	idle(void);
 void	idlehands(void);
 void	idlehands(void);
 int	inb(int);
 int	inb(int);
@@ -61,6 +61,9 @@ ulong	inl(int);
 void	insl(int, void*, int);
 void	insl(int, void*, int);
 int	intrdisable(int, void (*)(Ureg *, void *), void*, int, char*);
 int	intrdisable(int, void (*)(Ureg *, void *), void*, int, char*);
 void	intrenable(int, void (*)(Ureg*, void*), void*, int, char*);
 void	intrenable(int, void (*)(Ureg*, void*), void*, int, char*);
+void	introff(void);
+void	intron(void);
+void	invlpg(ulong);
 void	iofree(int);
 void	iofree(int);
 void	ioinit(void);
 void	ioinit(void);
 int	iounused(int, int);
 int	iounused(int, int);
@@ -68,6 +71,7 @@ int	ioalloc(int, int, int, char*);
 int	ioreserve(int, int, int, char*);
 int	ioreserve(int, int, int, char*);
 int	iprint(char*, ...);
 int	iprint(char*, ...);
 int	isaconfig(char*, int, ISAConf*);
 int	isaconfig(char*, int, ISAConf*);
+void*	kaddr(ulong);
 void	kbdenable(void);
 void	kbdenable(void);
 void	kbdinit(void);
 void	kbdinit(void);
 #define	kmapinval()
 #define	kmapinval()
@@ -82,10 +86,9 @@ void	mathinit(void);
 void	mb386(void);
 void	mb386(void);
 void	mb586(void);
 void	mb586(void);
 void	meminit(void);
 void	meminit(void);
+void	memorysummary(void);
 #define mmuflushtlb(pdb) putcr3(pdb)
 #define mmuflushtlb(pdb) putcr3(pdb)
 void	mmuinit(void);
 void	mmuinit(void);
-ulong	mmukmap(ulong, ulong, int);
-int	mmukmapsync(ulong);
 ulong*	mmuwalk(ulong*, ulong, int, int);
 ulong*	mmuwalk(ulong*, ulong, int, int);
 uchar	nvramread(int);
 uchar	nvramread(int);
 void	nvramwrite(int, uchar);
 void	nvramwrite(int, uchar);
@@ -95,6 +98,7 @@ void	outs(int, ushort);
 void	outss(int, void*, int);
 void	outss(int, void*, int);
 void	outl(int, ulong);
 void	outl(int, ulong);
 void	outsl(int, void*, int);
 void	outsl(int, void*, int);
+ulong	paddr(void*);
 int	pciscan(int, Pcidev**);
 int	pciscan(int, Pcidev**);
 ulong	pcibarsize(Pcidev*, int);
 ulong	pcibarsize(Pcidev*, int);
 int	pcicfgr8(Pcidev*, int);
 int	pcicfgr8(Pcidev*, int);
@@ -122,33 +126,43 @@ int	(*_pcmspecial)(char *, ISAConf *);
 void	pcmspecialclose(int);
 void	pcmspecialclose(int);
 void	(*_pcmspecialclose)(int);
 void	(*_pcmspecialclose)(int);
 void	pcmunmap(int, PCMmap*);
 void	pcmunmap(int, PCMmap*);
+int	pdbmap(ulong*, ulong, ulong, int);
 void	procrestore(Proc*);
 void	procrestore(Proc*);
 void	procsave(Proc*);
 void	procsave(Proc*);
 void	procsetup(Proc*);
 void	procsetup(Proc*);
 void	putcr3(ulong);
 void	putcr3(ulong);
 void	putcr4(ulong);
 void	putcr4(ulong);
+void*	rampage(void);
 void	rdmsr(int, vlong*);
 void	rdmsr(int, vlong*);
+void	realmode(Ureg*);
 void	screeninit(void);
 void	screeninit(void);
 void	(*screenputs)(char*, int);
 void	(*screenputs)(char*, int);
 void	syncclock(void);
 void	syncclock(void);
+void*	tmpmap(Page*);
+void	tmpunmap(void*);
 void	touser(void*);
 void	touser(void*);
 void	trapenable(int, void (*)(Ureg*, void*), void*, char*);
 void	trapenable(int, void (*)(Ureg*, void*), void*, char*);
 void	trapinit(void);
 void	trapinit(void);
+void	trapinit0(void);
 int	tas(void*);
 int	tas(void*);
 uvlong	tscticks(uvlong*);
 uvlong	tscticks(uvlong*);
 ulong	umbmalloc(ulong, int, int);
 ulong	umbmalloc(ulong, int, int);
 void	umbfree(ulong, int);
 void	umbfree(ulong, int);
 ulong	umbrwmalloc(ulong, int, int);
 ulong	umbrwmalloc(ulong, int, int);
 void	umbrwfree(ulong, int);
 void	umbrwfree(ulong, int);
-ulong	upamalloc(ulong, int, int);
+ulong	upaalloc(int, int);
 void	upafree(ulong, int);
 void	upafree(ulong, int);
+void	upareserve(ulong, int);
 #define	userureg(ur) (((ur)->cs & 0xFFFF) == UESEL)
 #define	userureg(ur) (((ur)->cs & 0xFFFF) == UESEL)
 void	vectortable(void);
 void	vectortable(void);
+void*	vmap(ulong, int);
+int	vmapsync(ulong);
+void	vunmap(void*, int);
 void	wrmsr(int, vlong);
 void	wrmsr(int, vlong);
 int	xchgw(ushort*, int);
 int	xchgw(ushort*, int);
 
 
 #define	waserror()	(up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
 #define	waserror()	(up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
-#define KADDR(a)	((void*)((ulong)(a)|KZERO))
-#define PADDR(a)	((ulong)(a)&~KZERO)
+#define	KADDR(a)	kaddr(a)
+#define PADDR(a)	paddr((void*)(a))
 
 
 #define	dcflush(a, b)
 #define	dcflush(a, b)

+ 15 - 0
sys/src/9/pc/i8259.c

@@ -197,3 +197,18 @@ i8259disable(int irq)
 	iunlock(&i8259lock);
 	iunlock(&i8259lock);
 	return 0;
 	return 0;
 }
 }
+
+void
+i8259on(void)
+{
+	outb(Int0aux, i8259mask&0xFF);
+	outb(Int1aux, (i8259mask>>8)&0xFF);
+}
+
+void
+i8259off(void)
+{
+	outb(Int0aux, 0xFF);
+	outb(Int1aux, 0xFF);
+}
+

+ 269 - 21
sys/src/9/pc/l.s

@@ -1,4 +1,6 @@
 #include "mem.h"
 #include "mem.h"
+#include "/sys/src/boot/pc/x16.h"
+#undef DELAY
 
 
 #define PADDR(a)	((a) & ~KZERO)
 #define PADDR(a)	((a) & ~KZERO)
 #define KADDR(a)	(KZERO|(a))
 #define KADDR(a)	(KZERO|(a))
@@ -13,6 +15,7 @@
 #define RDTSC 		BYTE $0x0F; BYTE $0x31	/* RDTSC, result in AX/DX (lo/hi) */
 #define RDTSC 		BYTE $0x0F; BYTE $0x31	/* RDTSC, result in AX/DX (lo/hi) */
 #define RDMSR		BYTE $0x0F; BYTE $0x32	/* RDMSR, result in AX/DX (lo/hi) */
 #define RDMSR		BYTE $0x0F; BYTE $0x32	/* RDMSR, result in AX/DX (lo/hi) */
 #define HLT		BYTE $0xF4
 #define HLT		BYTE $0xF4
+#define INVLPG	BYTE $0x0F; BYTE $0x01; BYTE $0x39	/* INVLPG (%ecx) */
 
 
 /*
 /*
  * Macros for calculating offsets within the page directory base
  * Macros for calculating offsets within the page directory base
@@ -27,8 +30,8 @@
  * 9load currently sets up the mmu, however the first 16MB of memory is identity
  * 9load currently sets up the mmu, however the first 16MB of memory is identity
  * mapped, so behave as if the mmu was not setup
  * mapped, so behave as if the mmu was not setup
  */
  */
-TEXT _start0x80100020(SB), $0
-	MOVL	$_start0x00100020(SB), AX
+TEXT _startKADDR(SB), $0
+	MOVL	$_startPADDR(SB), AX
 	ANDL	$~KZERO, AX
 	ANDL	$~KZERO, AX
 	JMP*	AX
 	JMP*	AX
 
 
@@ -40,10 +43,10 @@ TEXT _multibootheader(SB), $0
 	LONG	$0x00010003			/* flags */
 	LONG	$0x00010003			/* flags */
 	LONG	$-(0x1BADB002 + 0x00010003)	/* checksum */
 	LONG	$-(0x1BADB002 + 0x00010003)	/* checksum */
 	LONG	$_multibootheader-KZERO(SB)	/* header_addr */
 	LONG	$_multibootheader-KZERO(SB)	/* header_addr */
-	LONG	$_start0x80100020-KZERO(SB)	/* load_addr */
+	LONG	$_startKADDR-KZERO(SB)		/* load_addr */
 	LONG	$edata-KZERO(SB)		/* load_end_addr */
 	LONG	$edata-KZERO(SB)		/* load_end_addr */
 	LONG	$end-KZERO(SB)			/* bss_end_addr */
 	LONG	$end-KZERO(SB)			/* bss_end_addr */
-	LONG	$_start0x80100020-KZERO(SB)	/* entry_addr */
+	LONG	$_startKADDR-KZERO(SB)		/* entry_addr */
 	LONG	$0				/* mode_type */
 	LONG	$0				/* mode_type */
 	LONG	$0				/* width */
 	LONG	$0				/* width */
 	LONG	$0				/* height */
 	LONG	$0				/* height */
@@ -51,7 +54,7 @@ TEXT _multibootheader(SB), $0
 
 
 /*
 /*
  * In protected mode with paging turned off and segment registers setup to linear map all memory.
  * In protected mode with paging turned off and segment registers setup to linear map all memory.
- * Entered via a jump to 0x00100020, the physical address of the virtual kernel entry point of 0x80100020
+ * Entered via a jump to PADDR(entry), the physical address of the virtual kernel entry point of KADDR(entry)
  * Make the basic page tables for processor 0. Four pages are needed for the basic set:
  * Make the basic page tables for processor 0. Four pages are needed for the basic set:
  * a page directory, a page table for mapping the first 4MB of physical memory to KZERO,
  * a page directory, a page table for mapping the first 4MB of physical memory to KZERO,
  * and virtual and physical pages for mapping the Mach structure.
  * and virtual and physical pages for mapping the Mach structure.
@@ -60,7 +63,7 @@ TEXT _multibootheader(SB), $0
  * identity mapping is removed once the MMU is going and the JMP has been made
  * identity mapping is removed once the MMU is going and the JMP has been made
  * to virtual memory.
  * to virtual memory.
  */
  */
-TEXT _start0x00100020(SB), $0
+TEXT _startPADDR(SB), $0
 	CLI					/* make sure interrupts are off */
 	CLI					/* make sure interrupts are off */
 
 
 	/* set up the gdt so we have sane plan 9 style gdts. */
 	/* set up the gdt so we have sane plan 9 style gdts. */
@@ -109,10 +112,21 @@ TEXT tgdt(SB), $0
  *  that's needed as we start executing in physical addresses. 
  *  that's needed as we start executing in physical addresses. 
  */
  */
 TEXT tgdtptr(SB), $0
 TEXT tgdtptr(SB), $0
-
 	WORD	$(3*8)
 	WORD	$(3*8)
 	LONG	$tgdt-KZERO(SB)
 	LONG	$tgdt-KZERO(SB)
 
 
+TEXT m0rgdtptr(SB), $0
+	WORD	$(NGDT*8-1)
+	LONG	$(CPU0GDT-KZERO)
+
+TEXT m0gdtptr(SB), $0
+	WORD	$(NGDT*8-1)
+	LONG	$CPU0GDT
+
+TEXT m0idtptr(SB), $0
+	WORD $(256*8-1)
+	LONG $IDTADDR
+
 TEXT mode32bit(SB), $0
 TEXT mode32bit(SB), $0
 	/* At this point, the GDT setup is done. */
 	/* At this point, the GDT setup is done. */
 
 
@@ -126,7 +140,7 @@ TEXT mode32bit(SB), $0
 
 
 	MOVL	$PADDR(CPU0PDB), AX
 	MOVL	$PADDR(CPU0PDB), AX
 	ADDL	$PDO(KZERO), AX			/* page directory offset for KZERO */
 	ADDL	$PDO(KZERO), AX			/* page directory offset for KZERO */
-	MOVL	$PADDR(CPU0PTE), (AX)		/* PTE's for 0x80000000 */
+	MOVL	$PADDR(CPU0PTE), (AX)		/* PTE's for KZERO */
 	MOVL	$(PTEWRITE|PTEVALID), BX	/* page permissions */
 	MOVL	$(PTEWRITE|PTEVALID), BX	/* page permissions */
 	ORL	BX, (AX)
 	ORL	BX, (AX)
 
 
@@ -211,6 +225,234 @@ _idle:
 	HLT
 	HLT
 	JMP	_idle
 	JMP	_idle
 
 
+/*
+ * Save registers.
+ */
+TEXT saveregs(SB), $0
+	/* appease 8l */
+	SUBL $32, SP
+	POPL AX
+	POPL AX
+	POPL AX
+	POPL AX
+	POPL AX
+	POPL AX
+	POPL AX
+	POPL AX
+	
+	PUSHL	AX
+	PUSHL	BX
+	PUSHL	CX
+	PUSHL	DX
+	PUSHL	BP
+	PUSHL	DI
+	PUSHL	SI
+	PUSHFL
+
+	XCHGL	32(SP), AX	/* swap return PC and saved flags */
+	XCHGL	0(SP), AX
+	XCHGL	32(SP), AX
+	RET
+
+TEXT restoreregs(SB), $0
+	/* appease 8l */
+	PUSHL	AX
+	PUSHL	AX
+	PUSHL	AX
+	PUSHL	AX
+	PUSHL	AX
+	PUSHL	AX
+	PUSHL	AX
+	PUSHL	AX
+	ADDL	$32, SP
+	
+	XCHGL	32(SP), AX	/* swap return PC and saved flags */
+	XCHGL	0(SP), AX
+	XCHGL	32(SP), AX
+
+	POPFL
+	POPL	SI
+	POPL	DI
+	POPL	BP
+	POPL	DX
+	POPL	CX
+	POPL	BX
+	POPL	AX
+	RET
+
+/*
+ * Assumed to be in protected mode at time of call.
+ * Switch to real mode, execute an interrupt, and
+ * then switch back to protected mode.  
+ *
+ * Assumes:
+ *
+ *	- no device interrupts are going to come in
+ *	- 0-16MB is identity mapped in page tables
+ *	- realmode() has copied us down from 0x100000 to 0x8000
+ *	- can use code segment 0x0800 in real mode
+ *		to get at l.s code
+ *	- l.s code is less than 1 page
+ */
+#define RELOC	(RMCODE-KTZERO)
+
+TEXT realmodeidtptr(SB), $0
+	WORD	$(4*256-1)
+	LONG	$0
+
+TEXT realmode0(SB), $0
+	CALL	saveregs(SB)
+
+	/* switch to low code address */
+	LEAL	physcode-KZERO(SB), AX
+	JMP *AX
+
+TEXT physcode(SB), $0
+
+	/* switch to low stack */
+	MOVL	SP, AX
+	MOVL	$0x7C00, SP
+	PUSHL	AX
+
+	/* change gdt to physical pointer */
+	MOVL	m0rgdtptr-KZERO(SB), GDTR
+
+	/* load IDT with real-mode version*/
+	MOVL	realmodeidtptr-KZERO(SB), IDTR
+
+	/* edit INT $0x00 instruction below */
+	MOVL	$(RMUADDR-KZERO+48), AX	/* &rmu.trap */
+	MOVL	(AX), AX
+	MOVB	AX, realmodeintrinst+(-KZERO+1+RELOC)(SB)
+
+	/* disable paging */
+	MOVL	CR0, AX
+	ANDL	$0x7FFFFFFF, AX
+	MOVL	AX, CR0
+	/* JMP .+2 to clear prefetch queue*/
+	BYTE $0xEB; BYTE $0x00
+
+	/* jump to 16-bit code segment */
+/*	JMPFAR	SELECTOR(KESEG16, SELGDT, 0):$again16bit(SB) /**/
+	 BYTE	$0xEA
+	 LONG	$again16bit-KZERO(SB)
+	 WORD	$SELECTOR(KESEG16, SELGDT, 0)
+
+TEXT again16bit(SB), $0
+	/*
+	 * Now in 16-bit compatibility mode.
+	 * These are 32-bit instructions being interpreted
+	 * as 16-bit instructions.  I'm being lazy and
+	 * not using the macros because I know when
+	 * the 16- and 32-bit instructions look the same
+	 * or close enough.
+	 */
+
+	/* disable protected mode and jump to real mode cs */
+	OPSIZE; MOVL CR0, AX
+	OPSIZE; XORL BX, BX
+	OPSIZE; INCL BX
+	OPSIZE; XORL BX, AX
+	OPSIZE; MOVL AX, CR0
+
+	/* JMPFAR 0x0800:now16real */
+	 BYTE $0xEA
+	 WORD	$now16real-KZERO(SB)
+	 WORD	$0x0800
+
+TEXT now16real(SB), $0
+	/* copy the registers for the bios call */
+	LWI(0x0000, rAX)
+	MOVW	AX,SS
+	LWI(RMUADDR, rBP)
+	
+	/* offsets are in Ureg */
+	LXW(44, xBP, rAX)
+	MOVW	AX, DS
+	LXW(40, xBP, rAX)
+	MOVW	AX, ES
+
+	OPSIZE; LXW(0, xBP, rDI)
+	OPSIZE; LXW(4, xBP, rSI)
+	OPSIZE; LXW(16, xBP, rBX)
+	OPSIZE; LXW(20, xBP, rDX)
+	OPSIZE; LXW(24, xBP, rCX)
+	OPSIZE; LXW(28, xBP, rAX)
+
+	CLC
+
+TEXT realmodeintrinst(SB), $0
+	INT $0x00
+
+	/* save the registers after the call */
+
+	LWI(0x7bfc, rSP)
+	OPSIZE; PUSHFL
+	OPSIZE; PUSHL AX
+
+	LWI(0, rAX)
+	MOVW	AX,SS
+	LWI(RMUADDR, rBP)
+	
+	OPSIZE; SXW(rDI, 0, xBP)
+	OPSIZE; SXW(rSI, 4, xBP)
+	OPSIZE; SXW(rBX, 16, xBP)
+	OPSIZE; SXW(rDX, 20, xBP)
+	OPSIZE; SXW(rCX, 24, xBP)
+	OPSIZE; POPL AX
+	OPSIZE; SXW(rAX, 28, xBP)
+
+	MOVW	DS, AX
+	OPSIZE; SXW(rAX, 44, xBP)
+	MOVW	ES, AX
+	OPSIZE; SXW(rAX, 40, xBP)
+
+	OPSIZE; POPL AX
+	OPSIZE; SXW(rAX, 64, xBP)	/* flags */
+
+	/* re-enter protected mode and jump to 32-bit code */
+	OPSIZE; MOVL $1, AX
+	OPSIZE; MOVL AX, CR0
+	
+/*	JMPFAR	SELECTOR(KESEG, SELGDT, 0):$again32bit(SB) /**/
+	 OPSIZE
+	 BYTE $0xEA
+	 LONG	$again32bit-KZERO(SB)
+	 WORD	$SELECTOR(KESEG, SELGDT, 0)
+
+TEXT again32bit(SB), $0
+	MOVW	$SELECTOR(KDSEG, SELGDT, 0),AX
+	MOVW	AX,DS
+	MOVW	AX,SS
+	MOVW	AX,ES
+	MOVW	AX,FS
+	MOVW	AX,GS
+
+	/* enable paging and jump to kzero-address code */
+	MOVL	CR0, AX
+	ORL	$0x80000000, AX
+	MOVL	AX, CR0
+	LEAL	again32kzero(SB), AX
+	JMP*	AX
+
+TEXT again32kzero(SB), $0
+	/* breathe a sigh of relief - back in 32-bit protected mode */
+
+	/* switch to old stack */	
+	PUSHL	AX	/* match popl below for 8l */
+	MOVL	$0x7BFC, SP
+	POPL	SP
+
+	/* restore idt */
+	MOVL	m0idtptr(SB),IDTR
+
+	/* restore gdt */
+	MOVL	m0gdtptr(SB), GDTR
+
+	CALL	restoreregs(SB)
+	RET
+
+/*
 /*
 /*
  * Port I/O.
  * Port I/O.
  *	in[bsl]		input a byte|short|long
  *	in[bsl]		input a byte|short|long
@@ -347,6 +589,12 @@ TEXT putcr4(SB), $0
 	MOVL	AX, CR4
 	MOVL	AX, CR4
 	RET
 	RET
 
 
+TEXT invlpg(SB), $0
+	/* 486+ only */
+	MOVL	va+0(FP), CX
+	INVLPG
+	RET
+
 TEXT _cycles(SB), $0				/* time stamp counter */
 TEXT _cycles(SB), $0				/* time stamp counter */
 	RDTSC
 	RDTSC
 	MOVL	vlong+0(FP), CX			/* &vlong */
 	MOVL	vlong+0(FP), CX			/* &vlong */
@@ -442,21 +690,21 @@ _aamloop:
  * FNxxx variations) so WAIT instructions must be explicitly placed in the
  * FNxxx variations) so WAIT instructions must be explicitly placed in the
  * code as necessary.
  * code as necessary.
  */
  */
-#define	FPOFF(l)							;\
-	MOVL	CR0, AX 					 	;\
-	ANDL	$0xC, AX			/* EM, TS */	 	;\
-	CMPL	AX, $0x8					 	;\
-	JEQ 	l						 	;\
-	WAIT							 	;\
-l:								 	;\
-	MOVL	CR0, AX							;\
-	ANDL	$~0x4, AX			/* EM=0 */		;\
-	ORL	$0x28, AX			/* NE=1, TS=1 */	;\
+#define	FPOFF(l)						 ;\
+	MOVL	CR0, AX 					 ;\
+	ANDL	$0xC, AX			/* EM, TS */	 ;\
+	CMPL	AX, $0x8					 ;\
+	JEQ 	l						 ;\
+	WAIT							 ;\
+l:								 ;\
+	MOVL	CR0, AX						 ;\
+	ANDL	$~0x4, AX			/* EM=0 */	 ;\
+	ORL	$0x28, AX			/* NE=1, TS=1 */ ;\
 	MOVL	AX, CR0
 	MOVL	AX, CR0
 
 
-#define	FPON								;\
-	MOVL	CR0, AX							;\
-	ANDL	$~0xC, AX			/* EM=0, TS=0 */	;\
+#define	FPON							 ;\
+	MOVL	CR0, AX						 ;\
+	ANDL	$~0xC, AX			/* EM=0, TS=0 */ ;\
 	MOVL	AX, CR0
 	MOVL	AX, CR0
 	
 	
 TEXT fpoff(SB), $0				/* disable */
 TEXT fpoff(SB), $0				/* disable */

+ 42 - 17
sys/src/9/pc/main.c

@@ -29,6 +29,7 @@ char *confname[MAXCONF];
 char *confval[MAXCONF];
 char *confval[MAXCONF];
 int nconf;
 int nconf;
 uchar *sp;	/* user stack of init proc */
 uchar *sp;	/* user stack of init proc */
+int delaylink;
 
 
 static void
 static void
 options(void)
 options(void)
@@ -69,6 +70,7 @@ options(void)
 	}
 	}
 }
 }
 
 
+void mmuinit0(void);
 void
 void
 main(void)
 main(void)
 {
 {
@@ -81,6 +83,9 @@ main(void)
 
 
 	print("\nPlan 9\n");
 	print("\nPlan 9\n");
 
 
+	trapinit0();
+	mmuinit0();
+
 	kbdinit();
 	kbdinit();
 	i8253init();
 	i8253init();
 	cpuidentify();
 	cpuidentify();
@@ -101,7 +106,11 @@ main(void)
 		arch->clockenable();
 		arch->clockenable();
 	procinit0();
 	procinit0();
 	initseg();
 	initseg();
-	links();
+	if(delaylink){
+		bootlinks();
+		pcimatch(0, 0, 0);
+	}else
+		links();
 	conf.monitor = 1;
 	conf.monitor = 1;
 	chandevreset();
 	chandevreset();
 	pageinit();
 	pageinit();
@@ -194,9 +203,9 @@ init0(void)
 void
 void
 userinit(void)
 userinit(void)
 {
 {
+	void *v;
 	Proc *p;
 	Proc *p;
 	Segment *s;
 	Segment *s;
-	KMap *k;
 	Page *pg;
 	Page *pg;
 
 
 	p = newproc();
 	p = newproc();
@@ -226,14 +235,18 @@ userinit(void)
 
 
 	/*
 	/*
 	 * User Stack
 	 * User Stack
+	 *
+	 * N.B. cannot call newpage() with clear=1, because pc kmap
+	 * requires up != nil.  use tmpmap instead.
 	 */
 	 */
 	s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
 	s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
 	p->seg[SSEG] = s;
 	p->seg[SSEG] = s;
-	pg = newpage(1, 0, USTKTOP-BY2PG);
+	pg = newpage(0, 0, USTKTOP-BY2PG);
+	v = tmpmap(pg);
+	memset(v, 0, BY2PG);
 	segpage(s, pg);
 	segpage(s, pg);
-	k = kmap(pg);
-	bootargs(VA(k));
-	kunmap(k);
+	bootargs(v);
+	tmpunmap(v);
 
 
 	/*
 	/*
 	 * Text
 	 * Text
@@ -241,12 +254,13 @@ userinit(void)
 	s = newseg(SG_TEXT, UTZERO, 1);
 	s = newseg(SG_TEXT, UTZERO, 1);
 	s->flushme++;
 	s->flushme++;
 	p->seg[TSEG] = s;
 	p->seg[TSEG] = s;
-	pg = newpage(1, 0, UTZERO);
+	pg = newpage(0, 0, UTZERO);
 	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
 	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
 	segpage(s, pg);
 	segpage(s, pg);
-	k = kmap(s->map[0]->pages[0]);
-	memmove((ulong*)VA(k), initcode, sizeof initcode);
-	kunmap(k);
+	v = tmpmap(pg);
+	memset(v, 0, BY2PG);
+	memmove(v, initcode, sizeof initcode);
+	tmpunmap(v);
 
 
 	ready(p);
 	ready(p);
 }
 }
@@ -263,7 +277,7 @@ pusharg(char *p)
 }
 }
 
 
 void
 void
-bootargs(ulong base)
+bootargs(void *base)
 {
 {
  	int i, ac;
  	int i, ac;
 	uchar *av[32];
 	uchar *av[32];
@@ -295,9 +309,9 @@ bootargs(ulong base)
 	sp -= (ac+1)*sizeof(sp);
 	sp -= (ac+1)*sizeof(sp);
 	lsp = (uchar**)sp;
 	lsp = (uchar**)sp;
 	for(i = 0; i < ac; i++)
 	for(i = 0; i < ac; i++)
-		*lsp++ = av[i] + ((USTKTOP - BY2PG) - base);
+		*lsp++ = av[i] + ((USTKTOP - BY2PG) - (ulong)base);
 	*lsp = 0;
 	*lsp = 0;
-	sp += (USTKTOP - BY2PG) - base - sizeof(ulong);
+	sp += (USTKTOP - BY2PG) - (ulong)base - sizeof(ulong);
 }
 }
 
 
 char*
 char*
@@ -344,7 +358,7 @@ void
 confinit(void)
 confinit(void)
 {
 {
 	char *p;
 	char *p;
-	int userpcnt;
+	int i, userpcnt;
 	ulong kpages;
 	ulong kpages;
 
 
 	if(p = getconf("*kernelpercent"))
 	if(p = getconf("*kernelpercent"))
@@ -352,7 +366,9 @@ confinit(void)
 	else
 	else
 		userpcnt = 0;
 		userpcnt = 0;
 
 
-	conf.npage = conf.npage0 + conf.npage1;
+	conf.npage = 0;
+	for(i=0; i<nelem(conf.mem); i++)
+		conf.npage += conf.mem[i].npage;
 
 
 	conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
 	conf.nproc = 100 + ((conf.npage*BY2PG)/MB)*5;
 	if(cpuserver)
 	if(cpuserver)
@@ -397,6 +413,14 @@ confinit(void)
 		if(conf.npage*BY2PG < 16*MB)
 		if(conf.npage*BY2PG < 16*MB)
 			imagmem->minarena = 4*1024*1024;
 			imagmem->minarena = 4*1024*1024;
 	}
 	}
+
+	/*
+	 * can't go past the end of virtual memory
+	 * (ulong)-KZERO is 2^32 - KZERO
+	 */
+	if(kpages > ((ulong)-KZERO)/BY2PG)
+		kpages = ((ulong)-KZERO)/BY2PG;
+
 	conf.upages = conf.npage - kpages;
 	conf.upages = conf.npage - kpages;
 	conf.ialloc = (kpages/2)*BY2PG;
 	conf.ialloc = (kpages/2)*BY2PG;
 
 
@@ -493,7 +517,7 @@ matherror(Ureg *ur, void*)
  *  math coprocessor emulation fault
  *  math coprocessor emulation fault
  */
  */
 static void
 static void
-mathemu(Ureg*, void*)
+mathemu(Ureg *ureg, void*)
 {
 {
 	if(up->fpstate & FPillegal){
 	if(up->fpstate & FPillegal){
 		/* someone did floating point in a note handler */
 		/* someone did floating point in a note handler */
@@ -521,7 +545,8 @@ mathemu(Ureg*, void*)
 		up->fpstate = FPactive;
 		up->fpstate = FPactive;
 		break;
 		break;
 	case FPactive:
 	case FPactive:
-		panic("math emu");
+		panic("math emu pid %ld %s pc 0x%lux", 
+			up->pid, up->text, ureg->pc);
 		break;
 		break;
 	}
 	}
 }
 }

+ 36 - 25
sys/src/9/pc/mem.h

@@ -11,6 +11,7 @@
 #define	BY2V		8			/* bytes per double word */
 #define	BY2V		8			/* bytes per double word */
 #define	BY2PG		4096			/* bytes per page */
 #define	BY2PG		4096			/* bytes per page */
 #define	WD2PG		(BY2PG/BY2WD)		/* words per page */
 #define	WD2PG		(BY2PG/BY2WD)		/* words per page */
+#define	BY2XPG		(4096*1024)	/* bytes per big page */
 #define	PGSHIFT		12			/* log(BY2PG) */
 #define	PGSHIFT		12			/* log(BY2PG) */
 #define	ROUND(s, sz)	(((s)+((sz)-1))&~((sz)-1))
 #define	ROUND(s, sz)	(((s)+((sz)-1))&~((sz)-1))
 #define	PGROUND(s)	ROUND(s, BY2PG)
 #define	PGROUND(s)	ROUND(s, BY2PG)
@@ -26,40 +27,48 @@
 #define	MS2HZ		(1000/HZ)		/* millisec per clock tick */
 #define	MS2HZ		(1000/HZ)		/* millisec per clock tick */
 #define	TK2SEC(t)	((t)/HZ)		/* ticks to seconds */
 #define	TK2SEC(t)	((t)/HZ)		/* ticks to seconds */
 
 
-/*
- * Fundamental addresses
- */
-#define	IDTADDR		0x80000800		/* idt */
-#define	REBOOTADDR	0x00001000		/* reboot code - physical address */
-#define	APBOOTSTRAP	0x80001000		/* AP bootstrap code */
-#define	CONFADDR	0x80001200		/* info passed from boot loader */
-#define	CPU0PDB		0x80002000		/* bootstrap processor PDB */
-#define	CPU0PTE		0x80003000		/* bootstrap processor PTE's for 0-4MB */
-#define	CPU0GDT		0x80004000		/* bootstrap processor GDT */
-#define	MACHADDR	0x80005000		/* as seen by current processor */
-#define	CPU0MACH	0x80006000		/* Mach for bootstrap processor */
-#define	MACHSIZE	BY2PG
-/*
- * N.B.  ramscan knows that CPU0MACH+BY2PG is the end of reserved data
- * N.B.  _start0x00100020 knows that CPU0PDB is the first reserved page
- * and that there are 5 of them.
- */
-
 /*
 /*
  *  Address spaces
  *  Address spaces
- *
- *  User is at 0-2GB
- *  Kernel is at 2GB-4GB
  */
  */
+#define	KZERO		0xF0000000		/* base of kernel address space */
+#define	KTZERO		(KZERO+0x100000)		/* first address in kernel text - 9load sits below */
+#define	VPT			(KZERO-VPTSIZE)
+#define	VPTSIZE		BY2XPG
+#define	NVPT		(VPTSIZE/BY2WD)
+#define	KMAP		(VPT-KMAPSIZE)
+#define	KMAPSIZE	BY2XPG
+#define	VMAP		(KMAP-VMAPSIZE)
+#define	VMAPSIZE	(0x10000000-VPTSIZE-KMAPSIZE)
 #define	UZERO		0			/* base of user address space */
 #define	UZERO		0			/* base of user address space */
 #define	UTZERO		(UZERO+BY2PG)		/* first address in user text */
 #define	UTZERO		(UZERO+BY2PG)		/* first address in user text */
-#define	KZERO		0x80000000		/* base of kernel address space */
-#define	KTZERO		0x80100000		/* first address in kernel text */
-#define	USTKTOP		(KZERO-BY2PG)		/* byte just beyond user stack */
+#define	USTKTOP		(VMAP-BY2PG)		/* byte just beyond user stack */
 #define	USTKSIZE	(16*1024*1024)		/* size of user stack */
 #define	USTKSIZE	(16*1024*1024)		/* size of user stack */
 #define	TSTKTOP		(USTKTOP-USTKSIZE)	/* end of new stack in sysexec */
 #define	TSTKTOP		(USTKTOP-USTKSIZE)	/* end of new stack in sysexec */
 #define	TSTKSIZ 	100
 #define	TSTKSIZ 	100
 
 
+/*
+ * Fundamental addresses - bottom 64kB saved for return to real mode
+ */
+#define	CONFADDR	(KZERO+0x1200)		/* info passed from boot loader */
+#define	TMPADDR		(KZERO+0x2000)		/* used for temporary mappings */
+#define	APBOOTSTRAP	(KZERO+0x3000)		/* AP bootstrap code */
+#define	RMUADDR		(KZERO+0x7C00)		/* real mode Ureg */
+#define	RMCODE		(KZERO+0x8000)		/* copy of first page of KTEXT */
+#define	RMBUF		(KZERO+0x9000)		/* buffer for user space - known to vga */
+#define	IDTADDR		(KZERO+0x10800)		/* idt */
+#define	REBOOTADDR	(KZERO+0x11000)		/* reboot code - physical address */
+#define	CPU0PDB		(KZERO+0x12000)		/* bootstrap processor PDB */
+#define	CPU0PTE		(KZERO+0x13000)		/* bootstrap processor PTE's for 0-4MB */
+#define	CPU0GDT		(KZERO+0x14000)		/* bootstrap processor GDT */
+#define	MACHADDR	(KZERO+0x15000)		/* as seen by current processor */
+#define	CPU0MACH	(KZERO+0x16000)		/* Mach for bootstrap processor */
+#define	MACHSIZE	BY2PG
+/*
+ * N.B.  ramscan knows that CPU0MACH+BY2PG is the end of reserved data
+ * N.B.  _startPADDR knows that CPU0PDB is the first reserved page
+ * and that there are 5 of them.
+ */
+
 /*
 /*
  *  known x86 segments (in GDT) and their selectors
  *  known x86 segments (in GDT) and their selectors
  */
  */
@@ -72,6 +81,7 @@
 #define	APMCSEG		6	/* APM code segment */
 #define	APMCSEG		6	/* APM code segment */
 #define	APMCSEG16	7	/* APM 16-bit code segment */
 #define	APMCSEG16	7	/* APM 16-bit code segment */
 #define	APMDSEG		8	/* APM data segment */
 #define	APMDSEG		8	/* APM data segment */
+#define	KESEG16		9	/* kernel executable 16-bit */
 #define	NGDT		10	/* number of GDT entries required */
 #define	NGDT		10	/* number of GDT entries required */
 /* #define	APM40SEG	8	/* APM segment 0x40 */
 /* #define	APM40SEG	8	/* APM segment 0x40 */
 
 
@@ -141,3 +151,4 @@
 #define	PTX(va)		((((ulong)(va))>>12) & 0x03FF)
 #define	PTX(va)		((((ulong)(va))>>12) & 0x03FF)
 
 
 #define	getpgcolor(a)	0
 #define	getpgcolor(a)	0
+

+ 364 - 88
sys/src/9/pc/memory.c

@@ -8,6 +8,7 @@
 #include "dat.h"
 #include "dat.h"
 #include "fns.h"
 #include "fns.h"
 #include "io.h"
 #include "io.h"
+#include "ureg.h"
 
 
 #define MEMDEBUG	0
 #define MEMDEBUG	0
 
 
@@ -15,19 +16,20 @@ enum {
 	MemUPA		= 0,		/* unbacked physical address */
 	MemUPA		= 0,		/* unbacked physical address */
 	MemRAM		= 1,		/* physical memory */
 	MemRAM		= 1,		/* physical memory */
 	MemUMB		= 2,		/* upper memory block (<16MB) */
 	MemUMB		= 2,		/* upper memory block (<16MB) */
-	NMemType	= 3,
+	MemReserved	= 3,
+	NMemType	= 4,
 
 
 	KB		= 1024,
 	KB		= 1024,
 
 
 	MemMinMB	= 4,		/* minimum physical memory (<=4MB) */
 	MemMinMB	= 4,		/* minimum physical memory (<=4MB) */
-	MemMaxMB	= 768,		/* maximum physical memory to check */
+	MemMaxMB	= 3*1024+768,		/* maximum physical memory to check */
 
 
 	NMemBase	= 10,
 	NMemBase	= 10,
 };
 };
 
 
 typedef struct Map Map;
 typedef struct Map Map;
 struct Map {
 struct Map {
-	int	size;
+	ulong	size;
 	ulong	addr;
 	ulong	addr;
 };
 };
 
 
@@ -40,6 +42,9 @@ struct RMap {
 	Lock;
 	Lock;
 };
 };
 
 
+/* 
+ * Memory allocation tracking.
+ */
 static Map mapupa[16];
 static Map mapupa[16];
 static RMap rmapupa = {
 static RMap rmapupa = {
 	"unallocated unbacked physical memory",
 	"unallocated unbacked physical memory",
@@ -82,7 +87,7 @@ mapprint(RMap *rmap)
 
 
 	print("%s\n", rmap->name);	
 	print("%s\n", rmap->name);	
 	for(mp = rmap->map; mp->size; mp++)
 	for(mp = rmap->map; mp->size; mp++)
-		print("\t%8.8luX %8.8uX %8.8luX\n", mp->addr, mp->size, mp->addr+mp->size);
+		print("\t%8.8luX %8.8luX (%lud)\n", mp->addr, mp->addr+mp->size, mp->size);
 }
 }
 
 
 
 
@@ -91,9 +96,6 @@ memdebug(void)
 {
 {
 	ulong maxpa, maxpa1, maxpa2;
 	ulong maxpa, maxpa1, maxpa2;
 
 
-	if(MEMDEBUG == 0)
-		return;
-
 	maxpa = (nvramread(0x18)<<8)|nvramread(0x17);
 	maxpa = (nvramread(0x18)<<8)|nvramread(0x17);
 	maxpa1 = (nvramread(0x31)<<8)|nvramread(0x30);
 	maxpa1 = (nvramread(0x31)<<8)|nvramread(0x30);
 	maxpa2 = (nvramread(0x16)<<8)|nvramread(0x15);
 	maxpa2 = (nvramread(0x16)<<8)|nvramread(0x15);
@@ -209,6 +211,21 @@ mapalloc(RMap* rmap, ulong addr, int size, int align)
 	return 0;
 	return 0;
 }
 }
 
 
+/*
+ * Allocate from the ram map directly to make page tables.
+ * Called by mmuwalk during e820scan.
+ */
+void*
+rampage(void)
+{
+	ulong m;
+	
+	m = mapalloc(&rmapram, 0, BY2PG, BY2PG);
+	if(m == 0)
+		return nil;
+	return KADDR(m);
+}
+
 static void
 static void
 umbscan(void)
 umbscan(void)
 {
 {
@@ -269,18 +286,11 @@ umbscan(void)
 }
 }
 
 
 static void
 static void
-ramscan(ulong maxmem)
+lowraminit(void)
 {
 {
-	ulong *k0, kzero, map, maxpa, pa, *pte, *table, *va, x, n;
-	int nvalid[NMemType];
+	ulong n, pa, x;
 	uchar *bda;
 	uchar *bda;
 
 
-	/*
-	 * The bootstrap code has has created a prototype page
-	 * table which maps the first MemMinMB of physical memory to KZERO.
-	 * The page directory is at m->pdb and the first page of
-	 * free memory is after the per-processor MMU information.
-	 */
 	/*
 	/*
 	 * Initialise the memory bank information for conventional memory
 	 * Initialise the memory bank information for conventional memory
 	 * (i.e. less than 640KB). The base is the first location after the
 	 * (i.e. less than 640KB). The base is the first location after the
@@ -297,6 +307,21 @@ ramscan(ulong maxmem)
 	pa = MemMinMB*MB;
 	pa = MemMinMB*MB;
 	mapfree(&rmapram, x, pa-x);
 	mapfree(&rmapram, x, pa-x);
 	memset(KADDR(x), 0, pa-x);		/* keep us honest */
 	memset(KADDR(x), 0, pa-x);		/* keep us honest */
+}
+
+static void
+ramscan(ulong maxmem)
+{
+	ulong *k0, kzero, map, maxkpa, maxpa, pa, *pte, *table, *va, vbase, x;
+	int nvalid[NMemType];
+
+	/*
+	 * The bootstrap code has has created a prototype page
+	 * table which maps the first MemMinMB of physical memory to KZERO.
+	 * The page directory is at m->pdb and the first page of
+	 * free memory is after the per-processor MMU information.
+	 */
+	pa = MemMinMB*MB;
 
 
 	/*
 	/*
 	 * Check if the extended memory size can be obtained from the CMOS.
 	 * Check if the extended memory size can be obtained from the CMOS.
@@ -314,10 +339,9 @@ ramscan(ulong maxmem)
 			maxpa = MB+x*KB;
 			maxpa = MB+x*KB;
 		if(maxpa < 24*MB)
 		if(maxpa < 24*MB)
 			maxpa = 24*MB;
 			maxpa = 24*MB;
-		maxmem = MemMaxMB*MB;
-	}
-	else
+	}else
 		maxpa = maxmem;
 		maxpa = maxmem;
+	maxkpa = (u32int)-KZERO;	/* 2^32 - KZERO */
 
 
 	/*
 	/*
 	 * March up memory from MemMinMB to maxpa 1MB at a time,
 	 * March up memory from MemMinMB to maxpa 1MB at a time,
@@ -330,15 +354,24 @@ ramscan(ulong maxmem)
 	map = 0;
 	map = 0;
 	x = 0x12345678;
 	x = 0x12345678;
 	memset(nvalid, 0, sizeof(nvalid));
 	memset(nvalid, 0, sizeof(nvalid));
+	
+	/*
+	 * Can't map memory to KADDR(pa) when we're walking because
+	 * can only use KADDR for relatively low addresses.  Instead,
+	 * map each 4MB we scan to the virtual address range 4MB-8MB
+	 * while we are scanning.
+	 */
+	vbase = 4*MB;
 	while(pa < maxpa){
 	while(pa < maxpa){
 		/*
 		/*
 		 * Map the page. Use mapalloc(&rmapram, ...) to make
 		 * Map the page. Use mapalloc(&rmapram, ...) to make
 		 * the page table if necessary, it will be returned to the
 		 * the page table if necessary, it will be returned to the
-		 * pool later if it isn't needed.
+		 * pool later if it isn't needed.  Map in a fixed range (the second 4M)
+		 * because high physical addresses cannot be passed to KADDR.
 		 */
 		 */
-		va = KADDR(pa);
+		va = (void*)(vbase + pa%(4*MB));
 		table = &m->pdb[PDX(va)];
 		table = &m->pdb[PDX(va)];
-		if(*table == 0){
+		if(pa%(4*MB) == 0){
 			if(map == 0 && (map = mapalloc(&rmapram, 0, BY2PG, BY2PG)) == 0)
 			if(map == 0 && (map = mapalloc(&rmapram, 0, BY2PG, BY2PG)) == 0)
 				break;
 				break;
 			memset(KADDR(map), 0, BY2PG);
 			memset(KADDR(map), 0, BY2PG);
@@ -350,10 +383,9 @@ ramscan(ulong maxmem)
 
 
 		*pte = pa|PTEWRITE|PTEUNCACHED|PTEVALID;
 		*pte = pa|PTEWRITE|PTEUNCACHED|PTEVALID;
 		mmuflushtlb(PADDR(m->pdb));
 		mmuflushtlb(PADDR(m->pdb));
-
 		/*
 		/*
 		 * Write a pattern to the page and write a different
 		 * Write a pattern to the page and write a different
-		 * pattern to a possible mirror at KZER0. If the data
+		 * pattern to a possible mirror at KZERO. If the data
 		 * reads back correctly the chunk is some type of RAM (possibly
 		 * reads back correctly the chunk is some type of RAM (possibly
 		 * a linearly-mapped VGA framebuffer, for instance...) and
 		 * a linearly-mapped VGA framebuffer, for instance...) and
 		 * can be cleared and added to the memory pool. If not, the
 		 * can be cleared and added to the memory pool. If not, the
@@ -389,7 +421,6 @@ ramscan(ulong maxmem)
 			*pte = 0;
 			*pte = 0;
 			pa += MB;
 			pa += MB;
 		}
 		}
-
 		/*
 		/*
 		 * Done with this 4MB chunk, review the options:
 		 * Done with this 4MB chunk, review the options:
 		 * 1) not physical memory and >=16MB - invalidate the PDB entry;
 		 * 1) not physical memory and >=16MB - invalidate the PDB entry;
@@ -399,46 +430,284 @@ ramscan(ulong maxmem)
 		 * 4) mixed or no 4MB page extension - commit the already
 		 * 4) mixed or no 4MB page extension - commit the already
 		 *    initialised space for the page table.
 		 *    initialised space for the page table.
 		 */
 		 */
-		if((pa % (4*MB)) == 0){
-			table = &m->pdb[PDX(va)];
+		if(pa%(4*MB) == 0 && pa >= 32*MB && nvalid[MemUPA] == (4*MB)/BY2PG){
+			/*
+			 * If we encounter a 4MB chunk of missing memory
+			 * at a sufficiently high offset, call it the end of
+			 * memory.  Otherwise we run the risk of thinking
+			 * that video memory is real RAM.
+			 */
+			break;
+		}
+		if(pa <= maxkpa && pa%(4*MB) == 0){
+			table = &m->pdb[PDX(KADDR(pa - 4*MB))];
 			if(nvalid[MemUPA] == (4*MB)/BY2PG)
 			if(nvalid[MemUPA] == (4*MB)/BY2PG)
 				*table = 0;
 				*table = 0;
 			else if(nvalid[MemRAM] == (4*MB)/BY2PG && (m->cpuiddx & 0x08))
 			else if(nvalid[MemRAM] == (4*MB)/BY2PG && (m->cpuiddx & 0x08))
 				*table = (pa - 4*MB)|PTESIZE|PTEWRITE|PTEVALID;
 				*table = (pa - 4*MB)|PTESIZE|PTEWRITE|PTEVALID;
 			else if(nvalid[MemUMB] == (4*MB)/BY2PG && (m->cpuiddx & 0x08))
 			else if(nvalid[MemUMB] == (4*MB)/BY2PG && (m->cpuiddx & 0x08))
 				*table = (pa - 4*MB)|PTESIZE|PTEWRITE|PTEUNCACHED|PTEVALID;
 				*table = (pa - 4*MB)|PTESIZE|PTEWRITE|PTEUNCACHED|PTEVALID;
-			else
+			else{
+				*table = map|PTEWRITE|PTEVALID;
 				map = 0;
 				map = 0;
+			}
 		}
 		}
-
 		mmuflushtlb(PADDR(m->pdb));
 		mmuflushtlb(PADDR(m->pdb));
 		x += 0x3141526;
 		x += 0x3141526;
 	}
 	}
-
 	/*
 	/*
 	 * If we didn't reach the end of the 4MB chunk, that part won't
 	 * If we didn't reach the end of the 4MB chunk, that part won't
 	 * be mapped.  Commit the already initialised space for the page table.
 	 * be mapped.  Commit the already initialised space for the page table.
 	 */
 	 */
-	if(pa % (4*MB))
+	if(pa % (4*MB) && pa <= maxkpa){
+		m->pdb[PDX(KADDR(pa))] = map|PTEWRITE|PTEVALID;
 		map = 0;
 		map = 0;
-
+	}
 	if(map)
 	if(map)
 		mapfree(&rmapram, map, BY2PG);
 		mapfree(&rmapram, map, BY2PG);
-	if(pa < maxmem)
-		mapfree(&rmapupa, pa, maxmem-pa);
-	if(maxmem < 0xFFE00000)
-		mapfree(&rmapupa, maxmem, 0x00000000-maxmem);
-	if(MEMDEBUG)
-		print("maxmem %luX %luX\n", maxmem, 0x00000000-maxmem);
+
+	m->pdb[PDX(vbase)] = 0;
+	mmuflushtlb(PADDR(m->pdb));
+
+	mapfree(&rmapupa, pa, (u32int)-pa);
 	*k0 = kzero;
 	*k0 = kzero;
 }
 }
 
 
+/*
+ * BIOS Int 0x15 E820 memory map.
+ */
+enum
+{
+	SMAP = ('S'<<24)|('M'<<16)|('A'<<8)|'P',
+	Ememory = 1,
+	Ereserved = 2,
+	Carry = 1,
+};
+
+typedef struct Emap Emap;
+struct Emap
+{
+	uvlong base;
+	uvlong len;
+	ulong type;
+};
+static Emap emap[16];
+int nemap;
+
+static char *etypes[] =
+{
+	"type=0",
+	"memory",
+	"reserved",
+	"acpi reclaim",
+	"acpi nvs",
+};
+
+static int
+emapcmp(const void *va, const void *vb)
+{
+	Emap *a, *b;
+	
+	a = (Emap*)va;
+	b = (Emap*)vb;
+	if(a->base < b->base)
+		return -1;
+	if(a->base > b->base)
+		return 1;
+	if(a->len < b->len)
+		return -1;
+	if(a->len > b->len)
+		return 1;
+	return a->type - b->type;
+}
+
+static void
+map(ulong base, ulong len, int type)
+{
+	ulong e, n;
+	ulong *table, flags, maxkpa;
+	
+	/*
+	 * Split any call crossing 4*MB to make below simpler.
+	 */
+	if(base < 4*MB && len > 4*MB-base){
+		n = 4*MB - base;
+		map(base, n, type);
+		map(4*MB, len-n, type);
+	}
+	
+	/*
+	 * Let lowraminit and umbscan hash out the low 4MB.
+	 */
+	if(base < 4*MB)
+		return;
+
+	/*
+	 * Any non-memory below 16*MB is used as upper mem blocks.
+	 */
+	if(type == MemUPA && base < 16*MB && base+len > 16*MB){
+		map(base, 16*MB-base, MemUMB);
+		map(16*MB, len-(16*MB-base), MemUPA);
+		return;
+	}
+	
+	/*
+	 * Memory below CPU0MACH is reserved for the kernel
+	 * and already mapped.
+	 */
+	if(base < PADDR(CPU0MACH)+BY2PG){
+		n = PADDR(CPU0MACH)+BY2PG - base;
+		if(len <= n)
+			return;
+		map(PADDR(CPU0MACH), len-n, type);
+		return;
+	}
+	
+	/*
+	 * Memory between KTZERO and end is the kernel itself
+	 * and is already mapped.
+	 */
+	if(base < PADDR(KTZERO) && base+len > PADDR(KTZERO)){
+		map(base, PADDR(KTZERO)-base, type);
+		return;
+	}
+	if(PADDR(KTZERO) < base && base < PADDR(PGROUND((ulong)end))){
+		n = PADDR(PGROUND((ulong)end));
+		if(len <= n)
+			return;
+		map(PADDR(PGROUND((ulong)end)), len-n, type);
+		return;
+	}
+	
+	/*
+	 * Now we have a simple case.
+	 */
+	// print("map %.8lux %.8lux %d\n", base, base+len, type);
+	switch(type){
+	case MemRAM:
+		mapfree(&rmapram, base, len);
+		flags = PTEWRITE;
+		break;
+	case MemUMB:
+		mapfree(&rmapumb, base, len);
+		flags = PTEWRITE|PTEUNCACHED;
+		break;
+	case MemUPA:
+		mapfree(&rmapupa, base, len);
+		/* don't need to map this but will anyway */
+		flags = PTEWRITE|PTEUNCACHED;
+		break;
+	default:
+	case MemReserved:
+		/* don't put in any pools but still map it. */
+		flags = PTEWRITE|PTEUNCACHED;
+		break;
+	}
+	
+	/*
+	 * bottom 4MB is already mapped - just twiddle flags.
+	 * (not currently used - see above)
+	 */
+	if(base < 4*MB){
+		table = KADDR(PPN(m->pdb[PDX(base)]));
+		e = base+len;
+		base = PPN(base);
+		for(; base<e; base+=BY2PG)
+			table[PTX(base)] |= flags;
+		return;
+	}
+	
+	/*
+	 * Only map from KZERO to 2^32.
+	 */
+	maxkpa = -KZERO;
+	if(base >= maxkpa)
+		return;
+	if(len > maxkpa-base)
+		len = maxkpa - base;
+	pdbmap(m->pdb, base|flags, base+KZERO, len);
+}
+
+static int
+e820scan(void)
+{
+	int i;
+	Ureg u;
+	ulong cont, base, last, len;
+	Emap *e;
+
+	if(getconf("*norealmode") || getconf("*noe820scan"))
+		return -1;
+
+	cont = 0;
+	for(i=0; i<nelem(emap); i++){
+		memset(&u, 0, sizeof u);
+		u.ax = 0xE820;
+		u.bx = cont;
+		u.cx = 20;
+		u.dx = SMAP;
+		u.es = (PADDR(RMBUF)>>4)&0xF000;
+		u.di = PADDR(RMBUF)&0xFFFF;
+		u.trap = 0x15;
+		realmode(&u);
+		cont = u.bx;
+		if((u.flags&Carry) || u.ax != SMAP || u.cx != 20)
+			break;
+		e = &emap[nemap++];
+		*e = *(Emap*)RMBUF;
+		if(u.bx == 0)
+			break;
+	}
+	if(nemap == 0)
+		return -1;
+	
+	qsort(emap, nemap, sizeof emap[0], emapcmp);
+	
+	for(i=0; i<nemap; i++){
+		e = &emap[i];
+		print("E820: %.8llux %.8llux ", e->base, e->base+e->len);
+		if(e->type < nelem(etypes))
+			print("%s\n", etypes[e->type]);
+		else
+			print("type=%lud\n", e->type);
+	}
+
+	last = 0;
+	for(i=0; i<nemap; i++){	
+		e = &emap[i];
+		/*
+		 * pull out the info but only about the low 32 bits...
+		 */
+		if(e->base >= (1LL<<32))
+			break;
+		base = e->base;
+		if(base+e->len > (1LL<<32))
+			len = -base;
+		else
+			len = e->len;
+		/*
+		 * If the map skips addresses, mark them available.
+		 */
+		if(last < e->base)
+			map(last, e->base-last, MemUPA);
+		last = base+len;
+		if(e->type == Ememory)
+			map(base, len, MemRAM);
+		else
+			map(base, len, MemReserved);
+	}
+	
+	return 0;
+}
+
 void
 void
 meminit(void)
 meminit(void)
 {
 {
-	Map *mp, *xmp;
+	int i;
+	Map *mp;
+	Confmem *cm;
 	ulong pa, *pte;
 	ulong pa, *pte;
-	ulong maxmem;
+	ulong maxmem, lost;
 	char *p;
 	char *p;
 
 
 	if(p = getconf("*maxmem"))
 	if(p = getconf("*maxmem"))
@@ -463,31 +732,33 @@ meminit(void)
 	mmuflushtlb(PADDR(m->pdb));
 	mmuflushtlb(PADDR(m->pdb));
 
 
 	umbscan();
 	umbscan();
-	ramscan(maxmem);
+	lowraminit();
+	if(e820scan() < 0)
+		ramscan(maxmem);
 
 
 	/*
 	/*
-	 * Set the conf entries describing two banks of allocatable memory.
-	 * Grab the first and largest entries in rmapram as left by ramscan().
-	 *
-	 * It would be nice to have more than 2 memory banks describable in conf.
+	 * Set the conf entries describing banks of allocatable memory.
 	 */
 	 */
-	mp = rmapram.map;
-	conf.base0 = mp->addr;
-	conf.npage0 = mp->size/BY2PG;
-	mp++;
-	for(xmp = 0; mp->size; mp++){
-		if(xmp == 0 || mp->size > xmp->size)
-			xmp = mp;
+	for(i=0; i<nelem(mapram) && i<nelem(conf.mem); i++){
+		mp = &rmapram.map[i];
+		cm = &conf.mem[i];
+		cm->base = mp->addr;
+		cm->npage = mp->size/BY2PG;
 	}
 	}
+	
+	lost = 0;
+	for(; i<nelem(mapram); i++)
+		lost += rmapram.map[i].size;
+	if(lost)
+		print("meminit - lost %lud bytes\n", lost);
 
 
-	if(xmp){		
-		conf.base1 = xmp->addr;
-		conf.npage1 = xmp->size/BY2PG;
-	}
 	if(MEMDEBUG)
 	if(MEMDEBUG)
 		memdebug();
 		memdebug();
 }
 }
 
 
+/*
+ * Allocate memory from the upper memory blocks.
+ */
 ulong
 ulong
 umbmalloc(ulong addr, int size, int align)
 umbmalloc(ulong addr, int size, int align)
 {
 {
@@ -536,47 +807,52 @@ umbrwfree(ulong addr, int size)
 	mapfree(&rmapumbrw, PADDR(addr), size);
 	mapfree(&rmapumbrw, PADDR(addr), size);
 }
 }
 
 
+/*
+ * Give out otherwise-unused physical address space
+ * for use in configuring devices.  Note that unlike upamalloc
+ * before it, upaalloc does not map the physical address
+ * into virtual memory.  Call vmap to do that.
+ */
 ulong
 ulong
-upamalloc(ulong pa, int size, int align)
+upaalloc(int size, int align)
 {
 {
-	ulong a, ae;
-
-	if(a = mapalloc(&xrmapupa, pa, size, align))
-		return a;
+	ulong a;
 
 
-	if((a = mapalloc(&rmapupa, pa, size, align)) == 0){
-		memdebug();
-		return 0;
+	a = mapalloc(&rmapupa, 0, size, align);
+	if(a == 0){
+		print("out of physical address space allocating %d\n", size);
+		mapprint(&rmapupa);
 	}
 	}
-
-	/*
-	 * Upamalloc is a request to map a range of physical addresses.
-	 * Therefore, if pa is 0 mapalloc will choose the base address.
-	 * Note, however, mmukmap is always asked to give a 1-to-1 mapping
-	 * of va to pa.
-	ae = mmukmap(a, a, size);
-	 * ...but for the moment go back to the old scheme for VLB cards.
-	 */
-	ae = mmukmap(a, 0, size);
-
-	/*
-	 * Should check here that it was all delivered
-	 * and put it back and barf if not.
-	 */
-	USED(ae);
-
-	/*
-	 * Be very careful this returns a PHYSICAL address
-	 * mapped 1-to-1 with the virtual address.
-	 * If a < KZERO it's probably not a good idea to
-	 * try KADDR(a)...
-	 */
 	return a;
 	return a;
 }
 }
 
 
 void
 void
 upafree(ulong pa, int size)
 upafree(ulong pa, int size)
 {
 {
-	mapfree(&xrmapupa, pa, size);
+	mapfree(&rmapupa, pa, size);
+}
+
+void
+upareserve(ulong pa, int size)
+{
+	ulong a;
+	
+	a = mapalloc(&rmapupa, pa, size, 0);
+	if(a != pa){
+		/*
+		 * This can happen when we're using the E820
+		 * map, which might have already reserved some
+		 * of the regions claimed by the pci devices.
+		 */
+	//	print("upareserve: cannot reserve pa=%#.8lux size=%d\n", pa, size);
+		if(a != 0)
+			mapfree(&rmapupa, a, size);
+	}
+}
+
+void
+memorysummary(void)
+{
+	memdebug();
 }
 }
 
 

+ 38 - 17
sys/src/9/pc/mkfile

@@ -1,11 +1,18 @@
 CONF=pc
 CONF=pc
 CONFLIST=pc pccpu pcf pccpuf pcdisk pcauth
 CONFLIST=pc pccpu pcf pccpuf pcdisk pcauth
-CRAPLIST=pccd pccpud pccpusape pcext pcf pcflop pcglenda pcgr pclml pcmartha pcsape pcblast
+CRAPLIST=pccd pcflop pcmartha
+EXTRACOPIES=
+#EXTRACOPIES=lookout boundary	# copy to these servers on install
 
 
 objtype=386
 objtype=386
 </$objtype/mkfile
 </$objtype/mkfile
 p=9
 p=9
 
 
+# must match mem.h
+
+APBOOTSTRAP=0xF0003000
+KTZERO=0xF0100020
+
 DEVS=`{rc ../port/mkdevlist $CONF}
 DEVS=`{rc ../port/mkdevlist $CONF}
 
 
 PORT=\
 PORT=\
@@ -16,9 +23,9 @@ PORT=\
 	cache.$O\
 	cache.$O\
 	chan.$O\
 	chan.$O\
 	dev.$O\
 	dev.$O\
+	edf.$O\
 	fault.$O\
 	fault.$O\
 	latin1.$O\
 	latin1.$O\
-	edf.$O\
 	page.$O\
 	page.$O\
 	parse.$O\
 	parse.$O\
 	pgrp.$O\
 	pgrp.$O\
@@ -27,6 +34,7 @@ PORT=\
 	proc.$O\
 	proc.$O\
 	qio.$O\
 	qio.$O\
 	qlock.$O\
 	qlock.$O\
+	rdb.$O\
 	rebootcmd.$O\
 	rebootcmd.$O\
 	segment.$O\
 	segment.$O\
 	swap.$O\
 	swap.$O\
@@ -47,7 +55,6 @@ OBJ=\
 	memory.$O\
 	memory.$O\
 	mmu.$O\
 	mmu.$O\
 	random.$O\
 	random.$O\
-	rdb.$O\
 	trap.$O\
 	trap.$O\
 	$CONF.root.$O\
 	$CONF.root.$O\
 	$CONF.rootc.$O\
 	$CONF.rootc.$O\
@@ -67,15 +74,16 @@ SDEV=`{echo devsd.c sd*.c | sed 's/\.c/.'$O'/g'}
 
 
 $p$CONF:	$CONF.c $OBJ $LIB
 $p$CONF:	$CONF.c $OBJ $LIB
 	$CC $CFLAGS '-DKERNDATE='`{date -n} $CONF.c
 	$CC $CFLAGS '-DKERNDATE='`{date -n} $CONF.c
-	$LD -o $target -T0x80100020 -l $OBJ $CONF.$O $LIB
+	$LD -o $target -T$KTZERO -l $OBJ $CONF.$O $LIB
 	size $target
 	size $target
 
 
-$p$CONF.gz: $p$CONF
-	strip < $p$CONF | gzip -9 > $p$CONF.gz
+$p$CONF.gz:	$p$CONF
+	strip -o /fd/1 $p$CONF | gzip -9 > $p$CONF.gz
 
 
-install:V: $p$CONF $p$CONF.gz
+install:V:	$p$CONF $p$CONF.gz
 	cp $p$CONF $p$CONF.gz /$objtype/
 	cp $p$CONF $p$CONF.gz /$objtype/
-	# import lookout / /n/lookout && cp $p$CONF $p$CONF.gz /n/lookout/$objtype/
+	for(i in $EXTRACOPIES)
+		import $i / /n/$i && cp $p$CONF $p$CONF.gz /n/$i/$objtype/
 
 
 <../boot/bootmkfile
 <../boot/bootmkfile
 <../port/portmkfile
 <../port/portmkfile
@@ -90,20 +98,21 @@ apic.$O archmp.$O mp.$O:	mp.h
 $SDEV:				../port/sd.h
 $SDEV:				../port/sd.h
 sd53c8xx.$O:			sd53c8xx.i
 sd53c8xx.$O:			sd53c8xx.i
 main.$O:			init.h reboot.h
 main.$O:			init.h reboot.h
-wavelan.$O:	wavelan.c ../pc/wavelan.c ../pc/wavelan.h
-etherwavelan.$O:	etherwavelan.c  ../pc/wavelan.h
-devusb.$O usbuhci.$O usbohci.$O:	usb.h
-trap.$O:	/sys/include/tos.h
+wavelan.$O:			wavelan.c ../pc/wavelan.c ../pc/wavelan.h
+etherwavelan.$O:		etherwavelan.c ../pc/wavelan.h
+devusb.$O usbuhci.$O usbohci.$O: usb.h
+trap.$O:			/sys/include/tos.h
 
 
 sd53c8xx.i:	sd53c8xx.n
 sd53c8xx.i:	sd53c8xx.n
 	aux/na $prereq > $target
 	aux/na $prereq > $target
 
 
-init.h:	../port/initcode.c init9.c
+init.h:		../port/initcode.c init9.c
 	$CC ../port/initcode.c
 	$CC ../port/initcode.c
 	$CC init9.c
 	$CC init9.c
 	$LD -l -R1 -o init.out init9.$O initcode.$O /386/lib/libc.a
 	$LD -l -R1 -o init.out init9.$O initcode.$O /386/lib/libc.a
+	strip init.out
 	{echo 'uchar initcode[]={'
 	{echo 'uchar initcode[]={'
-	 strip < init.out | xd -1x |
+	 cat init.out | xd -1x |
 		sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
 		sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
 	 echo '};'} > init.h
 	 echo '};'} > init.h
 
 
@@ -117,14 +126,14 @@ reboot.h:	rebootcode.s
 
 
 apbootstrap.h:	apbootstrap.s mem.h
 apbootstrap.h:	apbootstrap.s mem.h
 	$AS $prereq
 	$AS $prereq
-	$LD -o apbootstrap.out -T0x80001000 -R4 -l -s apbootstrap.$O
+	$LD -o apbootstrap.out -T$APBOOTSTRAP -R4 -l -s apbootstrap.$O
 	{echo 'uchar apbootstrap[]={'
 	{echo 'uchar apbootstrap[]={'
 	 xd -1x apbootstrap.out |
 	 xd -1x apbootstrap.out |
 		sed -e '1,2d' -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
 		sed -e '1,2d' -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
 	 echo '};'} > $target
 	 echo '};'} > $target
 
 
 acid:V:
 acid:V:
-	8c -a -w -I. ../port/qio.c>acid
+	8c -a -w -I. i8253.c>acid
 
 
 %.checkether:VQ:
 %.checkether:VQ:
 	for (i in ether*.c){
 	for (i in ether*.c){
@@ -148,4 +157,16 @@ checkdist:VQ:
 		mk $i.$j
 		mk $i.$j
 
 
 %.clean:V:
 %.clean:V:
-	rm -f $stem.c [9bz]$stem [9bz]$stem.gz boot$stem.*
+	rm -f $stem.c [9bz]$stem [9bz]$stem.gz boot$stem.* reboot.h apbootstrap.h init.h
+
+# testing
+9load:D: /usr/rsc/boot/$O.load 9pcload
+	cat $prereq >$target
+
+9load.flp: 9load
+	disk/format -b /386/pbs -df $target $prereq
+
+$p$CONF.flp: /386/9load plan9.ini $p$CONF.gz
+	disk/format -b /386/pbs -df $target $prereq
+
+

+ 656 - 282
sys/src/9/pc/mmu.c

@@ -1,3 +1,37 @@
+/*
+ * Memory mappings.  Life was easier when 2G of memory was enough.
+ *
+ * The kernel memory starts at KZERO, with the text loaded at KZERO+1M
+ * (9load sits under 1M during the load).  The memory from KZERO to the
+ * top of memory is mapped 1-1 with physical memory, starting at physical
+ * address 0.  All kernel memory and data structures (i.e., the entries stored
+ * into conf.mem) must sit in this physical range: if KZERO is at 0xF0000000,
+ * then the kernel can only have 256MB of memory for itself.
+ * 
+ * The 256M below KZERO comprises three parts.  The lowest 4M is the
+ * virtual page table, a virtual address representation of the current 
+ * page table tree.  The second 4M is used for temporary per-process
+ * mappings managed by kmap and kunmap.  The remaining 248M is used
+ * for global (shared by all procs and all processors) device memory
+ * mappings and managed by vmap and vunmap.  The total amount (256M)
+ * could probably be reduced somewhat if desired.  The largest device
+ * mapping is that of the video card, and even though modern video cards
+ * have embarrassing amounts of memory, the video drivers only use one
+ * frame buffer worth (at most 16M).  Each is described in more detail below.
+ *
+ * The VPT is a 4M frame constructed by inserting the pdb into itself.
+ * This short-circuits one level of the page tables, with the result that 
+ * the contents of second-level page tables can be accessed at VPT.  
+ * We use the VPT to edit the page tables (see mmu) after inserting them
+ * into the page directory.  It is a convenient mechanism for mapping what
+ * might be otherwise-inaccessible pages.  The idea was borrowed from
+ * the Exokernel.
+ *
+ * The VPT doesn't solve all our problems, because we still need to 
+ * prepare page directories before we can install them.  For that, we
+ * use tmpmap/tmpunmap, which map a single page at TMPADDR.
+ */
+
 #include	"u.h"
 #include	"u.h"
 #include	"../port/lib.h"
 #include	"../port/lib.h"
 #include	"mem.h"
 #include	"mem.h"
@@ -5,8 +39,12 @@
 #include	"fns.h"
 #include	"fns.h"
 #include	"io.h"
 #include	"io.h"
 
 
+/*
+ * Simple segment descriptors with no translation.
+ */
 #define	DATASEGM(p) 	{ 0xFFFF, SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(p)|SEGDATA|SEGW }
 #define	DATASEGM(p) 	{ 0xFFFF, SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(p)|SEGDATA|SEGW }
 #define	EXECSEGM(p) 	{ 0xFFFF, SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(p)|SEGEXEC|SEGR }
 #define	EXECSEGM(p) 	{ 0xFFFF, SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(p)|SEGEXEC|SEGR }
+#define	EXEC16SEGM(p) 	{ 0xFFFF, SEGG|(0xF<<16)|SEGP|SEGPL(p)|SEGEXEC|SEGR }
 #define	TSSSEGM(b,p)	{ ((b)<<16)|sizeof(Tss),\
 #define	TSSSEGM(b,p)	{ ((b)<<16)|sizeof(Tss),\
 			  ((b)&0xFF000000)|(((b)>>16)&0xFF)|SEGTSS|SEGPL(p)|SEGP }
 			  ((b)&0xFF000000)|(((b)>>16)&0xFF)|SEGTSS|SEGPL(p)|SEGP }
 
 
@@ -18,63 +56,21 @@ Segdesc gdt[NGDT] =
 [UDSEG]		DATASEGM(3),		/* user data/stack */
 [UDSEG]		DATASEGM(3),		/* user data/stack */
 [UESEG]		EXECSEGM(3),		/* user code */
 [UESEG]		EXECSEGM(3),		/* user code */
 [TSSSEG]	TSSSEGM(0,0),		/* tss segment */
 [TSSSEG]	TSSSEGM(0,0),		/* tss segment */
+[KESEG16]		EXEC16SEGM(0),	/* kernel code 16-bit */
 };
 };
 
 
-static void
-taskswitch(ulong pdb, ulong stack)
-{
-	Tss *tss;
+static int didmmuinit;
+static void taskswitch(ulong, ulong);
+static void memglobal(void);
 
 
-	tss = m->tss;
-	tss->ss0 = KDSEL;
-	tss->esp0 = stack;
-	tss->ss1 = KDSEL;
-	tss->esp1 = stack;
-	tss->ss2 = KDSEL;
-	tss->esp2 = stack;
-	tss->cr3 = pdb;
-	putcr3(pdb);
-}
+#define	vpt ((ulong*)VPT)
+#define	VPTX(va)		(((ulong)(va))>>12)
+#define	vpd (vpt+VPTX(VPT))
 
 
-/* 
- * On processors that support it, we set the PTEGLOBAL bit in
- * page table and page directory entries that map kernel memory.
- * Doing this tells the processor not to bother flushing them
- * from the TLB when doing the TLB flush associated with a 
- * context switch (write to CR3).  Since kernel memory mappings
- * are never removed, this is safe.  (If we ever remove kernel memory
- * mappings, we can do a full flush by turning off the PGE bit in CR4,
- * writing to CR3, and then turning the PGE bit back on.) 
- *
- * See also mmukmap below.
- * 
- * Processor support for the PTEGLOBAL bit is enabled in devarch.c.
- */
-static void
-memglobal(void)
+void
+mmuinit0(void)
 {
 {
-	int i, j;
-	ulong *pde, *pte;
-
-	/* only need to do this once, on bootstrap processor */
-	if(m->machno != 0)
-		return;
-
-	if(!m->havepge)
-		return;
-
-	pde = m->pdb;
-	for(i=512; i<1024; i++){	/* 512: start at entry for virtual 0x80000000 */
-		if(pde[i] & PTEVALID){
-			pde[i] |= PTEGLOBAL;
-			if(!(pde[i] & PTESIZE)){
-				pte = KADDR(pde[i]&~(BY2PG-1));
-				for(j=0; j<1024; j++)
-					if(pte[j] & PTEVALID)
-						pte[j] |= PTEGLOBAL;
-			}
-		}
-	}			
+	memmove(m->gdt, gdt, sizeof gdt);
 }
 }
 
 
 void
 void
@@ -83,8 +79,14 @@ mmuinit(void)
 	ulong x, *p;
 	ulong x, *p;
 	ushort ptr[3];
 	ushort ptr[3];
 
 
-	memglobal();
+	didmmuinit = 1;
+
+	if(0) print("vpt=%#.8ux vpd=%#.8lux kmap=%#.8ux\n",
+		VPT, (ulong)vpd, KMAP);
 
 
+	memglobal();
+	m->pdb[PDX(VPT)] = PADDR(m->pdb)|PTEWRITE|PTEVALID;
+	
 	m->tss = malloc(sizeof(Tss));
 	m->tss = malloc(sizeof(Tss));
 	memset(m->tss, 0, sizeof(Tss));
 	memset(m->tss, 0, sizeof(Tss));
 	m->tss->iomap = 0xDFFF<<16;
 	m->tss->iomap = 0xDFFF<<16;
@@ -98,7 +100,6 @@ mmuinit(void)
 	 * than Intels in this regard).  Under VMware it pays off
 	 * than Intels in this regard).  Under VMware it pays off
 	 * a factor of about 10 to 100.
 	 * a factor of about 10 to 100.
 	 */
 	 */
-
 	memmove(m->gdt, gdt, sizeof gdt);
 	memmove(m->gdt, gdt, sizeof gdt);
 	x = (ulong)m->tss;
 	x = (ulong)m->tss;
 	m->gdt[TSSSEG].d0 = (x<<16)|sizeof(Tss);
 	m->gdt[TSSSEG].d0 = (x<<16)|sizeof(Tss);
@@ -128,6 +129,52 @@ mmuinit(void)
 	ltr(TSSSEL);
 	ltr(TSSSEL);
 }
 }
 
 
+/* 
+ * On processors that support it, we set the PTEGLOBAL bit in
+ * page table and page directory entries that map kernel memory.
+ * Doing this tells the processor not to bother flushing them
+ * from the TLB when doing the TLB flush associated with a 
+ * context switch (write to CR3).  Since kernel memory mappings
+ * are never removed, this is safe.  (If we ever remove kernel memory
+ * mappings, we can do a full flush by turning off the PGE bit in CR4,
+ * writing to CR3, and then turning the PGE bit back on.) 
+ *
+ * See also mmukmap below.
+ * 
+ * Processor support for the PTEGLOBAL bit is enabled in devarch.c.
+ */
+static void
+memglobal(void)
+{
+	int i, j;
+	ulong *pde, *pte;
+
+	/* only need to do this once, on bootstrap processor */
+	if(m->machno != 0)
+		return;
+
+	if(!m->havepge)
+		return;
+
+	pde = m->pdb;
+	for(i=PDX(KZERO); i<1024; i++){
+		if(pde[i] & PTEVALID){
+			pde[i] |= PTEGLOBAL;
+			if(!(pde[i] & PTESIZE)){
+				pte = KADDR(pde[i]&~(BY2PG-1));
+				for(j=0; j<1024; j++)
+					if(pte[j] & PTEVALID)
+						pte[j] |= PTEGLOBAL;
+			}
+		}
+	}			
+}
+
+/*
+ * Flush all the user-space and device-mapping mmu info
+ * for this process, because something has been deleted.
+ * It will be paged back in on demand.
+ */
 void
 void
 flushmmu(void)
 flushmmu(void)
 {
 {
@@ -139,23 +186,106 @@ flushmmu(void)
 	splx(s);
 	splx(s);
 }
 }
 
 
+/*
+ * Flush a single page mapping from the tlb.
+ */
+void
+flushpg(ulong va)
+{
+	if(X86FAMILY(m->cpuidax) >= 4)
+		invlpg(va);
+	else
+		putcr3(m->tss->cr3);
+}
+	
+/*
+ * Allocate a new page for a page directory. 
+ * We keep a small cache of pre-initialized
+ * page directories in each mach.
+ */
+static Page*
+mmupdballoc(void)
+{
+	int s;
+	Page *page;
+	ulong *pdb;
+
+	s = splhi();
+	if(m->pdbpool == 0){
+		spllo();
+		page = newpage(0, 0, 0);
+		page->va = (ulong)vpd;
+		splhi();
+		pdb = tmpmap(page);
+		memmove(pdb, m->pdb, BY2PG);
+		pdb[PDX(VPT)] = page->pa|PTEWRITE|PTEVALID;	/* set up VPT */
+		tmpunmap(pdb);
+	}else{
+		page = m->pdbpool;
+		m->pdbpool = page->next;
+		m->pdbcnt--;
+	}
+	splx(s);
+	return page;
+}
+
+static void
+mmupdbfree(Proc *proc, Page *p)
+{
+	if(islo())
+		panic("mmupdbfree: islo");
+	if(m->pdbcnt >= 10){
+		p->next = proc->mmufree;
+		proc->mmufree = p;
+	}else{
+		p->next = m->pdbpool;
+		m->pdbpool = p;
+	}
+}
+
+/*
+ * A user-space memory segment has been deleted, or the
+ * process is exiting.  Clear all the pde entries for user-space
+ * memory mappings and device mappings.  Any entries that
+ * are needed will be paged back in as necessary.
+ */
 static void
 static void
 mmuptefree(Proc* proc)
 mmuptefree(Proc* proc)
 {
 {
+	int s;
 	ulong *pdb;
 	ulong *pdb;
 	Page **last, *page;
 	Page **last, *page;
 
 
-	if(proc->mmupdb && proc->mmuused){
-		pdb = (ulong*)proc->mmupdb->va;
-		last = &proc->mmuused;
-		for(page = *last; page; page = page->next){
-			pdb[page->daddr] = 0;
-			last = &page->next;
-		}
-		*last = proc->mmufree;
-		proc->mmufree = proc->mmuused;
-		proc->mmuused = 0;
+	if(proc->mmupdb == nil || proc->mmuused == nil)
+		return;
+	s = splhi();
+	pdb = tmpmap(proc->mmupdb);
+	last = &proc->mmuused;
+	for(page = *last; page; page = page->next){
+		pdb[page->daddr] = 0;
+		last = &page->next;
 	}
 	}
+	tmpunmap(pdb);
+	splx(s);
+	*last = proc->mmufree;
+	proc->mmufree = proc->mmuused;
+	proc->mmuused = 0;
+}
+
+static void
+taskswitch(ulong pdb, ulong stack)
+{
+	Tss *tss;
+
+	tss = m->tss;
+	tss->ss0 = KDSEL;
+	tss->esp0 = stack;
+	tss->ss1 = KDSEL;
+	tss->esp1 = stack;
+	tss->ss2 = KDSEL;
+	tss->esp2 = stack;
+	tss->cr3 = pdb;
+	putcr3(pdb);
 }
 }
 
 
 void
 void
@@ -169,47 +299,37 @@ mmuswitch(Proc* proc)
 	}
 	}
 
 
 	if(proc->mmupdb){
 	if(proc->mmupdb){
-		pdb = (ulong*)proc->mmupdb->va;
+		pdb = tmpmap(proc->mmupdb);
 		pdb[PDX(MACHADDR)] = m->pdb[PDX(MACHADDR)];
 		pdb[PDX(MACHADDR)] = m->pdb[PDX(MACHADDR)];
+		tmpunmap(pdb);
 		taskswitch(proc->mmupdb->pa, (ulong)(proc->kstack+KSTACK));
 		taskswitch(proc->mmupdb->pa, (ulong)(proc->kstack+KSTACK));
-	}
-	else
+	}else
 		taskswitch(PADDR(m->pdb), (ulong)(proc->kstack+KSTACK));
 		taskswitch(PADDR(m->pdb), (ulong)(proc->kstack+KSTACK));
 }
 }
 
 
+/*
+ * Release any pages allocated for a page directory base or page-tables
+ * for this process:
+ *   switch to the prototype pdb for this processor (m->pdb);
+ *   call mmuptefree() to place all pages used for page-tables (proc->mmuused)
+ *   onto the process' free list (proc->mmufree). This has the side-effect of
+ *   cleaning any user entries in the pdb (proc->mmupdb);
+ *   if there's a pdb put it in the cache of pre-initialised pdb's
+ *   for this processor (m->pdbpool) or on the process' free list;
+ *   finally, place any pages freed back into the free pool (palloc).
+ * This routine is only called from sched() with palloc locked.
+ */
 void
 void
 mmurelease(Proc* proc)
 mmurelease(Proc* proc)
 {
 {
 	Page *page, *next;
 	Page *page, *next;
 
 
-	/*
-	 * Release any pages allocated for a page directory base or page-tables
-	 * for this process:
-	 *   switch to the prototype pdb for this processor (m->pdb);
-	 *   call mmuptefree() to place all pages used for page-tables (proc->mmuused)
-	 *   onto the process' free list (proc->mmufree). This has the side-effect of
-	 *   cleaning any user entries in the pdb (proc->mmupdb);
-	 *   if there's a pdb put it in the cache of pre-initialised pdb's
-	 *   for this processor (m->pdbpool) or on the process' free list;
-	 *   finally, place any pages freed back into the free pool (palloc).
-	 * This routine is only called from sched() with palloc locked.
-	 */
 	taskswitch(PADDR(m->pdb), (ulong)m + BY2PG);
 	taskswitch(PADDR(m->pdb), (ulong)m + BY2PG);
-	mmuptefree(proc);
-
 	if(proc->mmupdb){
 	if(proc->mmupdb){
-		if(m->pdbcnt > 10){
-			proc->mmupdb->next = proc->mmufree;
-			proc->mmufree = proc->mmupdb;
-		}
-		else{
-			proc->mmupdb->next = m->pdbpool;
-			m->pdbpool = proc->mmupdb;
-			m->pdbcnt++;
-		}
+		mmuptefree(proc);
+		mmupdbfree(proc, proc->mmupdb);
 		proc->mmupdb = 0;
 		proc->mmupdb = 0;
 	}
 	}
-
 	for(page = proc->mmufree; page; page = next){
 	for(page = proc->mmufree; page; page = next){
 		next = page->next;
 		next = page->next;
 		if(--page->ref)
 		if(--page->ref)
@@ -221,103 +341,90 @@ mmurelease(Proc* proc)
 	proc->mmufree = 0;
 	proc->mmufree = 0;
 }
 }
 
 
-static Page*
-mmupdballoc(void)
+/*
+ * Allocate and install pdb for the current process.
+ */
+static void
+upallocpdb(void)
 {
 {
 	int s;
 	int s;
+	ulong *pdb;
 	Page *page;
 	Page *page;
-
+	
+	page = mmupdballoc();
 	s = splhi();
 	s = splhi();
-	if(m->pdbpool == 0){
-		spllo();
-		page = newpage(0, 0, 0);
-		page->va = VA(kmap(page));
-		memmove((void*)page->va, m->pdb, BY2PG);
-	}
-	else{
-		page = m->pdbpool;
-		m->pdbpool = page->next;
-		m->pdbcnt--;
-	}
+	pdb = tmpmap(page);
+	pdb[PDX(MACHADDR)] = m->pdb[PDX(MACHADDR)];
+	tmpunmap(pdb);
+	up->mmupdb = page;
+	mmuflushtlb(up->mmupdb->pa);
 	splx(s);
 	splx(s);
-	return page;
 }
 }
-
-void
-checkmmu(ulong va, ulong pa)
-{
-	ulong *pdb, *pte;
-	int pdbx;
 	
 	
-	if(up->mmupdb == 0)
-		return;
-
-	pdb = (ulong*)up->mmupdb->va;
-	pdbx = PDX(va);
-	if(PPN(pdb[pdbx]) == 0){
-		/* okay to be empty - will fault and get filled */
-		return;
-	}
-	
-	pte = KADDR(PPN(pdb[pdbx]));
-	if(pte[PTX(va)] == 0)
-		return;
-	if((pte[PTX(va)]&~4095) != pa)
-		print("%ld %s: va=0x%08lux pa=0x%08lux pte=0x%08lux\n",
-			up->pid, up->text,
-			va, pa, pte[PTX(va)]);
-}
-
+/*
+ * Update the mmu in response to a user fault.  pa may have PTEWRITE set.
+ */
 void
 void
 putmmu(ulong va, ulong pa, Page*)
 putmmu(ulong va, ulong pa, Page*)
 {
 {
-	int pdbx;
+	int old;
 	Page *page;
 	Page *page;
-	ulong *pdb, *pte;
-	int s;
 
 
-	if(up->mmupdb == 0)
-		up->mmupdb = mmupdballoc();
-	pdb = (ulong*)up->mmupdb->va;
-	pdbx = PDX(va);
-
-	if(PPN(pdb[pdbx]) == 0){
-		if(up->mmufree == 0){
-			page = newpage(1, 0, 0);
-			page->va = VA(kmap(page));
-		}
-		else {
+	if(up->mmupdb == nil)
+		upallocpdb();
+
+	if(!(vpd[PDX(va)]&PTEVALID)){
+		if(up->mmufree == 0)
+			page = newpage(0, 0, 0);
+		else{
 			page = up->mmufree;
 			page = up->mmufree;
 			up->mmufree = page->next;
 			up->mmufree = page->next;
-			memset((void*)page->va, 0, BY2PG);
 		}
 		}
-		pdb[pdbx] = PPN(page->pa)|PTEUSER|PTEWRITE|PTEVALID;
-		page->daddr = pdbx;
+		vpd[PDX(va)] = PPN(page->pa)|PTEUSER|PTEWRITE|PTEVALID;
+		/* page is now mapped into the VPT - clear it */
+		memset((void*)(VPT+PDX(va)*BY2PG), 0, BY2PG);
+		page->daddr = PDX(va);
 		page->next = up->mmuused;
 		page->next = up->mmuused;
 		up->mmuused = page;
 		up->mmuused = page;
 	}
 	}
+	old = vpt[VPTX(va)];
+	vpt[VPTX(va)] = pa|PTEUSER|PTEVALID;
+	if(old&PTEVALID)
+		flushpg(va);
+}
 
 
-	pte = KADDR(PPN(pdb[pdbx]));
-	pte[PTX(va)] = pa|PTEUSER;
-
-	s = splhi();
-	pdb[PDX(MACHADDR)] = m->pdb[PDX(MACHADDR)];
-	mmuflushtlb(up->mmupdb->pa);
-	splx(s);
+/*
+ * Double-check the user MMU.
+ * Error checking only.
+ */
+void
+checkmmu(ulong va, ulong pa)
+{
+	if(up->mmupdb == 0)
+		return;
+	if(!(vpd[PDX(va)]&PTEVALID) || !(vpt[VPTX(va)]&PTEVALID))
+		return;
+	if(PPN(vpt[VPTX(va)]) != pa)
+		print("%ld %s: va=0x%08lux pa=0x%08lux pte=0x%08lux\n",
+			up->pid, up->text,
+			va, pa, vpt[VPTX(va)]);
 }
 }
 
 
+/*
+ * Walk the page-table pointed to by pdb and return a pointer
+ * to the entry for virtual address va at the requested level.
+ * If the entry is invalid and create isn't requested then bail
+ * out early. Otherwise, for the 2nd level walk, allocate a new
+ * page-table page and register it in the 1st level.  This is used
+ * only to edit kernel mappings, which use pages from kernel memory,
+ * so it's okay to use KADDR to look at the tables.
+ */
 ulong*
 ulong*
 mmuwalk(ulong* pdb, ulong va, int level, int create)
 mmuwalk(ulong* pdb, ulong va, int level, int create)
 {
 {
-	ulong pa, *table;
+	ulong *table;
+	void *map;
 
 
-	/*
-	 * Walk the page-table pointed to by pdb and return a pointer
-	 * to the entry for virtual address va at the requested level.
-	 * If the entry is invalid and create isn't requested then bail
-	 * out early. Otherwise, for the 2nd level walk, allocate a new
-	 * page-table page and register it in the 1st level.
-	 */
 	table = &pdb[PDX(va)];
 	table = &pdb[PDX(va)];
 	if(!(*table & PTEVALID) && create == 0)
 	if(!(*table & PTEVALID) && create == 0)
 		return 0;
 		return 0;
@@ -334,163 +441,430 @@ mmuwalk(ulong* pdb, ulong va, int level, int create)
 		if(*table & PTESIZE)
 		if(*table & PTESIZE)
 			panic("mmuwalk2: va %luX entry %luX\n", va, *table);
 			panic("mmuwalk2: va %luX entry %luX\n", va, *table);
 		if(!(*table & PTEVALID)){
 		if(!(*table & PTEVALID)){
-			pa = PADDR(xspanalloc(BY2PG, BY2PG, 0));
-			*table = pa|PTEWRITE|PTEVALID;
+			/*
+			 * Have to call low-level allocator from
+			 * memory.c if we haven't set up the xalloc
+			 * tables yet.
+			 */
+			if(didmmuinit)
+				map = xspanalloc(BY2PG, BY2PG, 0);
+			else
+				map = rampage();
+			if(map == nil)
+				panic("mmuwalk xspanalloc failed");
+			*table = PADDR(map)|PTEWRITE|PTEVALID;
 		}
 		}
 		table = KADDR(PPN(*table));
 		table = KADDR(PPN(*table));
-
 		return &table[PTX(va)];
 		return &table[PTX(va)];
 	}
 	}
 }
 }
 
 
-static Lock mmukmaplock;
-
-int
-mmukmapsync(ulong va)
-{
-	Mach *mach0;
-	ulong entry, *pte;
+/*
+ * Device mappings are shared by all procs and processors and
+ * live in the virtual range VMAP to VMAP+VMAPSIZE.  The master
+ * copy of the mappings is stored in mach0->pdb, and they are
+ * paged in from there as necessary by vmapsync during faults.
+ */
 
 
-	mach0 = MACHP(0);
+static Lock vmaplock;
 
 
-	ilock(&mmukmaplock);
+static int findhole(ulong *a, int n, int count);
+static ulong vmapalloc(ulong size);
+static void pdbunmap(ulong*, ulong, int);
 
 
-	if((pte = mmuwalk(mach0->pdb, va, 1, 0)) == nil){
-		iunlock(&mmukmaplock);
-		return 0;
+/*
+ * Add a device mapping to the vmap range.
+ */
+void*
+vmap(ulong pa, int size)
+{
+	int osize;
+	ulong o, va;
+	
+	/*
+	 * might be asking for less than a page.
+	 */
+	osize = size;
+	o = pa & (BY2PG-1);
+	pa -= o;
+	size += o;
+
+	size = ROUND(size, BY2PG);
+	if(pa == 0){
+		print("vmap pa=0 pc=%#.8lux\n", getcallerpc(&pa));
+		return nil;
 	}
 	}
-	if(!(*pte & PTESIZE) && mmuwalk(mach0->pdb, va, 2, 0) == nil){
-		iunlock(&mmukmaplock);
+	ilock(&vmaplock);
+	if((va = vmapalloc(size)) == 0 
+	|| pdbmap(MACHP(0)->pdb, pa|PTEUNCACHED|PTEWRITE, va, size) < 0){
+		iunlock(&vmaplock);
 		return 0;
 		return 0;
 	}
 	}
-	entry = *pte;
+	iunlock(&vmaplock);
+	/* avoid trap on local processor
+	for(i=0; i<size; i+=4*MB)
+		vmapsync(va+i);
+	*/
+	USED(osize);
+//	print("  vmap %#.8lux %d => %#.8lux\n", pa+o, osize, va+o);
+	return (void*)(va + o);
+}
 
 
-	if(!(m->pdb[PDX(va)] & PTEVALID))
-		m->pdb[PDX(va)] = entry;
+static int
+findhole(ulong *a, int n, int count)
+{
+	int have, i;
+	
+	have = 0;
+	for(i=0; i<n; i++){
+		if(a[i] == 0)
+			have++;
+		else
+			have = 0;
+		if(have >= count)
+			return i+1 - have;
+	}
+	return -1;
+}
 
 
-	if(up && up->mmupdb){
-		((ulong*)up->mmupdb->va)[PDX(va)] = entry;
-		mmuflushtlb(up->mmupdb->pa);
+/*
+ * Look for free space in the vmap.
+ */
+static ulong
+vmapalloc(ulong size)
+{
+	int i, n, o;
+	ulong *vpdb;
+	int vpdbsize;
+	
+	vpdb = &MACHP(0)->pdb[PDX(VMAP)];
+	vpdbsize = VMAPSIZE/(4*MB);
+
+	if(size >= 4*MB){
+		n = (size+4*MB-1) / (4*MB);
+		if((o = findhole(vpdb, vpdbsize, n)) != -1)
+			return VMAP + o*4*MB;
+		return VMAP + o;
 	}
 	}
-	else
-		mmuflushtlb(PADDR(m->pdb));
+	n = (size+BY2PG-1) / BY2PG;
+	for(i=0; i<vpdbsize; i++)
+		if((vpdb[i]&PTEVALID) && !(vpdb[i]&PTESIZE))
+			if((o = findhole(KADDR(PPN(vpdb[i])), WD2PG, n)) != -1)
+				return VMAP + i*4*MB + o*BY2PG;
+	if((o = findhole(vpdb, vpdbsize, 1)) != -1)
+		return VMAP + o*4*MB;
+		
+	/*
+	 * could span page directory entries, but not worth the trouble.
+	 * not going to be very much contention.
+	 */
+	return 0;
+}
 
 
-	iunlock(&mmukmaplock);
+/*
+ * Remove a device mapping from the vmap range.
+ * Since pdbunmap does not remove page tables, just entries,
+ * the call need not be interlocked with vmap.
+ */
+void
+vunmap(void *v, int size)
+{
+	int i;
+	ulong va, o;
+	Mach *nm;
+	Proc *p;
+	
+	/*
+	 * might not be aligned
+	 */
+	va = (ulong)v;
+	o = va&(BY2PG-1);
+	va -= o;
+	size += o;
+	size = ROUND(size, BY2PG);
+	
+	if(size < 0 || va < VMAP || va+size > VMAP+VMAPSIZE)
+		panic("vunmap va=%#.8lux size=%#x pc=%#.8lux\n",
+			va, size, getcallerpc(&va));
 
 
-	return 1;
+	pdbunmap(MACHP(0)->pdb, va, size);
+	
+	/*
+	 * Flush mapping from all the tlbs and copied pdbs.
+	 * This can be (and is) slow, since it is called only rarely.
+	 */
+	for(i=0; i<conf.nproc; i++){
+		p = proctab(i);
+		if(p->state == Dead)
+			continue;
+		if(p != up)
+			p->newtlb = 1;
+	}
+	for(i=0; i<conf.nmach; i++){
+		nm = MACHP(i);
+		if(nm != m)
+			nm->flushmmu = 1;
+	}
+	flushmmu();
+	for(i=0; i<conf.nmach; i++){
+		nm = MACHP(i);
+		if(nm != m)
+			while((active.machs&(1<<nm->machno)) && nm->flushmmu)
+				;
+	}
 }
 }
 
 
-ulong
-mmukmap(ulong pa, ulong va, int size)
+/*
+ * Add kernel mappings for pa -> va for a section of size bytes.
+ */
+int
+pdbmap(ulong *pdb, ulong pa, ulong va, int size)
 {
 {
-	Mach *mach0;
-	ulong ova, pae, *table, pgsz, *pte, x;
-	int pse, sync;
+	int pse;
+	ulong pae, pgsz, *pte, *table;
+	ulong flag;
+	
+	flag = pa&0xFFF;
+	pa &= ~0xFFF;
 
 
-	mach0 = MACHP(0);
-	if((mach0->cpuiddx & 0x08) && (getcr4() & 0x10))
+	if((MACHP(0)->cpuiddx & 0x08) && (getcr4() & 0x10))
 		pse = 1;
 		pse = 1;
 	else
 	else
 		pse = 0;
 		pse = 0;
-	sync = 0;
-
-	pa = PPN(pa);
-	if(va == 0)
-		va = (ulong)KADDR(pa);
-	else
-		va = PPN(va);
-	ova = va;
 
 
 	pae = pa + size;
 	pae = pa + size;
-	ilock(&mmukmaplock);
 	while(pa < pae){
 	while(pa < pae){
-		table = &mach0->pdb[PDX(va)];
-		/*
-		 * Possibly already mapped.
-		 */
-		if(*table & PTEVALID){
-			if(*table & PTESIZE){
-				/*
-				 * Big page. Does it fit within?
-				 * If it does, adjust pgsz so the correct end can be
-				 * returned and get out.
-				 * If not, adjust pgsz up to the next 4MB boundary
-				 * and continue.
-				 */
-				x = PPN(*table);
-				if(x != pa)
-					panic("mmukmap1: pa %luX  entry %luX\n",
-						pa, *table);
-				x += 4*MB;
-				if(pae <= x){
-					pa = pae;
-					break;
-				}
-				pgsz = x - pa;
-				pa += pgsz;
-				va += pgsz;
-
-				continue;
-			}
-			else{
-				/*
-				 * Little page. Walk to the entry.
-				 * If the entry is valid, set pgsz and continue.
-				 * If not, make it so, set pgsz, sync and continue.
-				 */
-				pte = mmuwalk(mach0->pdb, va, 2, 0);
-				if(pte && *pte & PTEVALID){
-					x = PPN(*pte);
-					if(x != pa)
-						panic("mmukmap2: pa %luX entry %luX\n",
-							pa, *pte);
-					pgsz = BY2PG;
-					pa += pgsz;
-					va += pgsz;
-					sync++;
-
-					continue;
-				}
-			}
-		}
+		table = &pdb[PDX(va)];
+		if((*table&PTEVALID) && (*table&PTESIZE))
+			panic("vmap: va=%#.8lux pa=%#.8lux pde=%#.8lux",
+				va, pa, *table);
 
 
 		/*
 		/*
-		 * Not mapped. Check if it can be mapped using a big page -
-		 * starts on a 4MB boundary, size >= 4MB and processor can do it.
-		 * If not a big page, walk the walk, talk the talk.
-		 * Sync is set.
-		 *
-		 * If we're creating a kernel mapping, we know that it will never
-		 * expire and thus we can set the PTEGLOBAL bit to make the entry
-	 	 * persist in the TLB across flushes.  If we do add support later for
-		 * unmapping kernel addresses, see devarch.c for instructions on
-		 * how to do a full TLB flush.
+		 * Check if it can be mapped using a 4MB page:
+		 * va, pa aligned and size >= 4MB and processor can do it.
 		 */
 		 */
-		if(pse && (pa % (4*MB)) == 0 && (pae >= pa+4*MB)){
-			*table = pa|PTESIZE|PTEWRITE|PTEUNCACHED|PTEVALID;
-			if((va&KZERO) && m->havepge)
-				*table |= PTEGLOBAL;
+		if(pse && pa%(4*MB) == 0 && va%(4*MB) == 0 && (pae >= pa+4*MB)){
+			*table = pa|PTESIZE|flag|PTEVALID;
 			pgsz = 4*MB;
 			pgsz = 4*MB;
-		}
-		else{
-			pte = mmuwalk(mach0->pdb, va, 2, 1);
-			*pte = pa|PTEWRITE|PTEUNCACHED|PTEVALID;
-			if((va&KZERO) && m->havepge)
-				*pte |= PTEGLOBAL;
+		}else{
+			pte = mmuwalk(pdb, va, 2, 1);
+			if(*pte&PTEVALID)
+				panic("vmap: va=%#.8lux pa=%#.8lux pte=%#.8lux",
+					va, pa, *pte);
+			*pte = pa|flag|PTEVALID;
 			pgsz = BY2PG;
 			pgsz = BY2PG;
 		}
 		}
 		pa += pgsz;
 		pa += pgsz;
 		va += pgsz;
 		va += pgsz;
-		sync++;
 	}
 	}
-	iunlock(&mmukmaplock);
+	return 0;
+}
+
+/*
+ * Remove mappings.  Must already exist, for sanity.
+ * Only used for kernel mappings, so okay to use KADDR.
+ */
+static void
+pdbunmap(ulong *pdb, ulong va, int size)
+{
+	ulong vae;
+	ulong *table;
+	
+	vae = va+size;
+	while(va < vae){
+		table = &pdb[PDX(va)];
+		if(!(*table & PTEVALID)){
+			panic("vunmap: not mapped");
+			/* 
+			va = (va+4*MB-1) & ~(4*MB-1);
+			continue;
+			*/
+		}
+		if(*table & PTESIZE){
+			*table = 0;
+			va = (va+4*MB-1) & ~(4*MB-1);
+			continue;
+		}
+		table = KADDR(PPN(*table));
+		if(!(table[PTX(va)] & PTEVALID))
+			panic("vunmap: not mapped");
+		table[PTX(va)] = 0;
+		va += BY2PG;
+	}
+}
+
+/*
+ * Handle a fault by bringing vmap up to date.
+ * Only copy pdb entries and they never go away,
+ * so no locking needed.
+ */
+int
+vmapsync(ulong va)
+{
+	ulong entry, *table;
+
+	if(va < VMAP || va >= VMAP+VMAPSIZE)
+		return 0;
+
+	entry = MACHP(0)->pdb[PDX(va)];
+	if(!(entry&PTEVALID))
+		return 0;
+	if(!(entry&PTESIZE)){
+		/* make sure entry will help the fault */
+		table = KADDR(PPN(entry));
+		if(!(table[PTX(va)]&PTEVALID))
+			return 0;
+	}
+	vpd[PDX(va)] = entry;
+	/*
+	 * TLB doesn't cache negative results, so no flush needed.
+	 */
+	return 1;
+}
+
+
+/*
+ * KMap is used to map individual pages into virtual memory.
+ * It is rare to have more than a few KMaps at a time (in the 
+ * absence of interrupts, only two at a time are ever used,
+ * but interrupts can stack).  The mappings are local to a process,
+ * so we can use the same range of virtual address space for
+ * all processes without any coordination.
+ */
+#define kpt (vpt+VPTX(KMAP))
+#define NKPT (KMAPSIZE/BY2PG)
+
+KMap*
+kmap(Page *page)
+{
+	int i, o, s;
+	Page *pdb;
+
+	if(up == nil)
+		panic("kmap: up=0 pc=%#.8lux", getcallerpc(&page));
+	if(up->mmupdb == nil)
+		upallocpdb();
+	if(!(vpd[PDX(KMAP)]&PTEVALID)){
+		/* allocate page directory */
+		if(KMAPSIZE > BY2XPG)
+			panic("bad kmapsize");
+		s = spllo();
+		pdb = newpage(0, 0, 0);
+		splx(s);
+		vpd[PDX(KMAP)] = pdb->pa|PTEWRITE|PTEVALID;
+		memset(kpt, 0, BY2PG);
+
+		/* might as well finish the job */
+		kpt[0] = page->pa|PTEWRITE|PTEVALID;
+		up->lastkmap = 0;
+		return (KMap*)KMAP;
+	}
+	o = up->lastkmap+1;
+	for(i=0; i<NKPT; i++){
+		if(kpt[(i+o)%NKPT] == 0){
+			o = (i+o)%NKPT;
+			kpt[o] = page->pa|PTEWRITE|PTEVALID;
+			up->lastkmap = o;
+			return (KMap*)(KMAP+o*BY2PG);
+		}
+	}
+	panic("out of kmap");
+	return nil;
+}
+
+void
+kunmap(KMap *k)
+{
+	ulong va;
+
+	va = (ulong)k;
+	if(up->mmupdb == nil || !(vpd[PDX(KMAP)]&PTEVALID))
+		panic("kunmap: no kmaps");
+	if(va < KMAP || va >= KMAP+KMAPSIZE)
+		panic("kunmap: bad address %#.8lux pc=%#.8lux", va, getcallerpc(&k));
+	if(!(vpt[VPTX(va)]&PTEVALID))
+		panic("kunmap: not mapped %#.8lux pc=%#.8lux", va, getcallerpc(&k));
+	vpt[VPTX(va)] = 0;
+	flushpg(va);
+}
+
+
+/*
+ * Temporary one-page mapping used to edit page directories.
+ *
+ * The fasttmp #define controls whether the code optimizes
+ * the case where the page is already mapped in the physical
+ * memory window.  
+ */
+#define fasttmp 1
+
+void*
+tmpmap(Page *p)
+{
+	ulong i;
+	ulong *entry;
+	
+	if(islo())
+		panic("tmpaddr: islo");
+
+	if(fasttmp && p->pa < -KZERO)
+		return KADDR(p->pa);
 
 
 	/*
 	/*
-	 * If something was added
-	 * then need to sync up.
+	 * PDX(TMPADDR) == PDX(MACHADDR), so this
+	 * entry is private to the processor and shared 
+	 * between up->mmupdb (if any) and m->pdb.
 	 */
 	 */
-	if(sync)
-		mmukmapsync(ova);
+	entry = &vpt[VPTX(TMPADDR)];
+	if(!(*entry&PTEVALID)){
+		for(i=KZERO; i<=CPU0MACH; i+=BY2PG)
+			print("%.8lux: *%.8lux=%.8lux (vpt=%.8lux index=%.8lux)\n", i, &vpt[VPTX(i)], vpt[VPTX(i)], vpt, VPTX(i));
+		panic("tmpmap: no entry");
+	}
+	if(PPN(*entry) != PPN(TMPADDR-KZERO))
+		panic("tmpmap: already mapped entry=%#.8lux", *entry);
+	*entry = p->pa|PTEWRITE|PTEVALID;
+	flushpg(TMPADDR);
+	return (void*)TMPADDR;
+}
 
 
-	return pa;
+void
+tmpunmap(void *v)
+{
+	ulong *entry;
+	
+	if(islo())
+		panic("tmpaddr: islo");
+	if(fasttmp && (ulong)v >= KZERO && v != (void*)TMPADDR)
+		return;
+	if(v != (void*)TMPADDR)
+		panic("tmpunmap: bad address");
+	entry = &vpt[VPTX(TMPADDR)];
+	if(!(*entry&PTEVALID) || PPN(*entry) == PPN(PADDR(TMPADDR)))
+		panic("tmpmap: not mapped entry=%#.8lux", *entry);
+	*entry = PPN(TMPADDR-KZERO)|PTEWRITE|PTEVALID;
+	flushpg(TMPADDR);
+}
+
+/*
+ * These could go back to being macros once the kernel is debugged,
+ * but the extra checking is nice to have.
+ */
+void*
+kaddr(ulong pa)
+{
+	if(pa > (ulong)-KZERO)
+		panic("kaddr: pa=%#.8lux", pa);
+	return (void*)(pa+KZERO);
+}
+
+ulong
+paddr(void *v)
+{
+	ulong va;
+	
+	va = (ulong)v;
+	if(va < KZERO)
+		panic("paddr: va=%#.8lux", va);
+	return va-KZERO;
 }
 }

+ 10 - 5
sys/src/9/pc/mp.c

@@ -137,6 +137,7 @@ static Apic*
 mkioapic(PCMPioapic* p)
 mkioapic(PCMPioapic* p)
 {
 {
 	Apic *apic;
 	Apic *apic;
+	void *va;
 
 
 	if(!(p->flags & PcmpEN) || p->apicno > MaxAPICNO)
 	if(!(p->flags & PcmpEN) || p->apicno > MaxAPICNO)
 		return 0;
 		return 0;
@@ -144,13 +145,13 @@ mkioapic(PCMPioapic* p)
 	/*
 	/*
 	 * Map the I/O APIC.
 	 * Map the I/O APIC.
 	 */
 	 */
-	if(mmukmap(p->addr, 0, 1024) == 0)
+	if((va = vmap(p->addr, 1024)) == 0)
 		return 0;
 		return 0;
 
 
 	apic = &mpapic[p->apicno];
 	apic = &mpapic[p->apicno];
 	apic->type = PcmpIOAPIC;
 	apic->type = PcmpIOAPIC;
 	apic->apicno = p->apicno;
 	apic->apicno = p->apicno;
-	apic->addr = KADDR(p->addr);
+	apic->addr = va;
 	apic->flags = p->flags;
 	apic->flags = p->flags;
 
 
 	return apic;
 	return apic;
@@ -440,6 +441,9 @@ mpstartap(Apic* apic)
 	*p++ = PADDR(APBOOTSTRAP);
 	*p++ = PADDR(APBOOTSTRAP);
 	*p++ = PADDR(APBOOTSTRAP)>>8;
 	*p++ = PADDR(APBOOTSTRAP)>>8;
 	i = (PADDR(APBOOTSTRAP) & ~0xFFFF)/16;
 	i = (PADDR(APBOOTSTRAP) & ~0xFFFF)/16;
+	/* code assumes i==0 */
+	if(i != 0)
+		print("mp: bad APBOOTSTRAP\n");
 	*p++ = i;
 	*p++ = i;
 	*p = i>>8;
 	*p = i>>8;
 
 
@@ -465,6 +469,7 @@ mpinit(void)
 	PCMP *pcmp;
 	PCMP *pcmp;
 	uchar *e, *p;
 	uchar *e, *p;
 	Apic *apic, *bpapic;
 	Apic *apic, *bpapic;
+	void *va;
 
 
 	i8259init();
 	i8259init();
 	syncclock();
 	syncclock();
@@ -476,7 +481,7 @@ mpinit(void)
 	/*
 	/*
 	 * Map the local APIC.
 	 * Map the local APIC.
 	 */
 	 */
-	if(mmukmap(pcmp->lapicbase, 0, 1024) == 0)
+	if((va = vmap(pcmp->lapicbase, 1024)) == nil)
 		return;
 		return;
 
 
 	bpapic = nil;
 	bpapic = nil;
@@ -508,7 +513,7 @@ mpinit(void)
 			 * guarantee that the bootstrap processor appears
 			 * guarantee that the bootstrap processor appears
 			 * first in the table before the others.
 			 * first in the table before the others.
 			 */
 			 */
-			apic->addr = KADDR(pcmp->lapicbase);
+			apic->addr = va;
 			if(apic->flags & PcmpBP)
 			if(apic->flags & PcmpBP)
 				bpapic = apic;
 				bpapic = apic;
 		}
 		}
@@ -766,7 +771,7 @@ mpintrenable(Vctl* v)
 		if(vno != -1)
 		if(vno != -1)
 			return vno;
 			return vno;
 	}
 	}
-
+	print("mpintrenable: out of choices %d %d\n", mpeisabus, mpisabus);
 	return -1;
 	return -1;
 }
 }
 
 

+ 2 - 0
sys/src/9/pc/mp.h

@@ -217,6 +217,8 @@ extern void lapicspurious(Ureg*, void*);
 extern int lapicisr(int);
 extern int lapicisr(int);
 extern int lapiceoi(int);
 extern int lapiceoi(int);
 extern void lapicicrw(int, int);
 extern void lapicicrw(int, int);
+extern void lapicintron(void);
+extern void lapicintroff(void);
 
 
 extern void mpinit(void);
 extern void mpinit(void);
 extern void mpshutdown(void);
 extern void mpshutdown(void);

+ 2 - 0
sys/src/9/pc/pc

@@ -38,6 +38,7 @@ dev
 link
 link
 	devpccard
 	devpccard
 	devi82365
 	devi82365
+	realmode
 	ether2000	ether8390
 	ether2000	ether8390
 	ether2114x	pci
 	ether2114x	pci
 	ether589	etherelnk3
 	ether589	etherelnk3
@@ -93,6 +94,7 @@ misc
 	vgat2r4		+cur
 	vgat2r4		+cur
 	vgatvp3020	=cur
 	vgatvp3020	=cur
 	vgatvp3026	=cur
 	vgatvp3026	=cur
+	vgavesa
 	vgavmware	+cur
 	vgavmware	+cur
 
 
 ip
 ip

+ 4 - 1
sys/src/9/pc/pcauth

@@ -37,13 +37,14 @@ link
 	loopbackmedium
 	loopbackmedium
 
 
 misc
 misc
+	realmode
 	sdata		pci sdscsi
 	sdata		pci sdscsi
 
 
 	uarti8250
 	uarti8250
 	uartpci
 	uartpci
 
 
 	vgamach64xx	+cur
 	vgamach64xx	+cur
-	vgas3  +cur vgasavage
+	vgas3 		+cur vgasavage
 
 
 ip
 ip
 	il
 	il
@@ -65,4 +66,6 @@ bootdir
 	bootpcauth.out boot
 	bootpcauth.out boot
 	/386/bin/ip/ipconfig
 	/386/bin/ip/ipconfig
 	/386/bin/auth/factotum
 	/386/bin/auth/factotum
+	/386/bin/fossil/fossil
+	/386/bin/venti/venti
 	/386/bin/disk/kfs
 	/386/bin/disk/kfs

+ 1 - 0
sys/src/9/pc/pccd

@@ -61,6 +61,7 @@ link
 	usbuhci
 	usbuhci
 
 
 misc
 misc
+	realmode
 	archmp		mp apic
 	archmp		mp apic
 
 
 	sdata		pci sdscsi
 	sdata		pci sdscsi

+ 2 - 0
sys/src/9/pc/pccpu

@@ -28,6 +28,7 @@ dev
 	usb
 	usb
 
 
 link
 link
+	realmode
 	ether2000	ether8390
 	ether2000	ether8390
 	ether2114x	pci
 	ether2114x	pci
 	ether79c970	pci
 	ether79c970	pci
@@ -53,6 +54,7 @@ misc
 
 
 	sdata		pci sdscsi
 	sdata		pci sdscsi
 	sd53c8xx	pci sdscsi
 	sd53c8xx	pci sdscsi
+	sdmv50xx	pci sdscsi
 
 
 
 
 ip
 ip

+ 2 - 0
sys/src/9/pc/pccpuf

@@ -58,6 +58,7 @@ link
 	usbuhci
 	usbuhci
 
 
 misc
 misc
+	realmode
 	archmp		mp apic
 	archmp		mp apic
 
 
 	uarti8250
 	uarti8250
@@ -86,6 +87,7 @@ misc
 	vgat2r4		+cur
 	vgat2r4		+cur
 	vgatvp3020	=cur
 	vgatvp3020	=cur
 	vgatvp3026	=cur
 	vgatvp3026	=cur
+	vgavesa
 	vgavmware	+cur
 	vgavmware	+cur
 
 
 
 

+ 2 - 0
sys/src/9/pc/pcdisk

@@ -60,6 +60,7 @@ link
 	usbuhci
 	usbuhci
 
 
 misc
 misc
+	realmode
 	archmp		mp apic
 	archmp		mp apic
 
 
 	sdata		pci sdscsi
 	sdata		pci sdscsi
@@ -89,6 +90,7 @@ misc
 	vgat2r4		+cur
 	vgat2r4		+cur
 	vgatvp3020	=cur
 	vgatvp3020	=cur
 	vgatvp3026	=cur
 	vgatvp3026	=cur
+	vgavesa
 	vgavmware	+cur
 	vgavmware	+cur
 
 
 ip
 ip

+ 2 - 0
sys/src/9/pc/pcf

@@ -62,6 +62,7 @@ link
 	usbuhci
 	usbuhci
 
 
 misc
 misc
+	realmode
 	archmp		mp apic
 	archmp		mp apic
 
 
 	sdata		pci sdscsi
 	sdata		pci sdscsi
@@ -91,6 +92,7 @@ misc
 	vgat2r4		+cur
 	vgat2r4		+cur
 	vgatvp3020	=cur
 	vgatvp3020	=cur
 	vgatvp3026	=cur
 	vgatvp3026	=cur
+	vgavesa
 	vgavmware	+cur
 	vgavmware	+cur
 
 
 ip
 ip

+ 2 - 0
sys/src/9/pc/pcflop

@@ -62,6 +62,7 @@ link
 #	usbuhci
 #	usbuhci
 
 
 misc
 misc
+	realmode
 #	archmp		mp apic
 #	archmp		mp apic
 
 
 	sdata		pci sdscsi
 	sdata		pci sdscsi
@@ -91,6 +92,7 @@ misc
 	vgat2r4		+cur
 	vgat2r4		+cur
 	vgatvp3020	=cur
 	vgatvp3020	=cur
 	vgatvp3026	=cur
 	vgatvp3026	=cur
+	vgavesa
 	vgavmware	+cur
 	vgavmware	+cur
 
 
 ip
 ip

+ 19 - 0
sys/src/9/pc/pci.c

@@ -759,6 +759,8 @@ pcirouting(void)
 	}
 	}
 }
 }
 
 
+static void pcireservemem(void);
+
 static void
 static void
 pcicfginit(void)
 pcicfginit(void)
 {
 {
@@ -898,12 +900,29 @@ pcicfginit(void)
 		pcirouting();
 		pcirouting();
 
 
 out:
 out:
+	pcireservemem();
 	unlock(&pcicfginitlock);
 	unlock(&pcicfginitlock);
 
 
 	if(getconf("*pcihinv"))
 	if(getconf("*pcihinv"))
 		pcihinv(nil);
 		pcihinv(nil);
 }
 }
 
 
+static void
+pcireservemem(void)
+{
+	int i;
+	Pcidev *p;
+	
+	/*
+	 * mark all the physical address space claimed by pci devices
+	 * as in use, so that upaalloc doesn't give it out.
+	 */
+	for(p=pciroot; p; p=p->list)
+		for(i=0; i<nelem(p->mem); i++)
+			if(p->mem[i].bar && (p->mem[i].bar&1) == 0)
+				upareserve(p->mem[i].bar&~0x0F, p->mem[i].size);
+}
+
 static int
 static int
 pcicfgrw8(int tbdf, int rno, int data, int read)
 pcicfgrw8(int tbdf, int rno, int data, int read)
 {
 {

+ 132 - 0
sys/src/9/pc/realmode.c

@@ -0,0 +1,132 @@
+#include	"u.h"
+#include	"tos.h"
+#include	"../port/lib.h"
+#include	"mem.h"
+#include	"dat.h"
+#include	"fns.h"
+#include	"io.h"
+#include	"ureg.h"
+#include	"../port/error.h"
+
+/*
+ * Back the processor into real mode to run a BIOS call,
+ * then return.  This must be used carefully, since it 
+ * completely disables hardware interrupts (e.g., the i8259)
+ * while running.  It is *not* using VM86 mode. 
+ * Maybe that's really the right answer, but real mode
+ * is fine for now.  We don't expect to use this very much --
+ * just for VGA and APM.
+ */
+#define realmoderegs (*(Ureg*)RMUADDR)
+
+#define LORMBUF (RMBUF-KZERO)
+
+static Ureg rmu;
+static Lock rmlock;
+
+void
+realmode(Ureg *ureg)
+{
+	int s;
+	extern void realmode0(void);	/* in l.s */
+	extern void i8259off(void), i8259on(void);
+
+	if(getconf("*norealmode"))
+		return;
+
+	lock(&rmlock);
+	realmoderegs = *ureg;
+
+	/* copy l.s so that it can be run from 16-bit mode */
+	memmove((void*)RMCODE, (void*)KTZERO, 0x1000);
+
+	s = splhi();
+	m->pdb[PDX(0)] = m->pdb[PDX(KZERO)];	/* identity map low */
+	putcr3(PADDR(m->pdb));
+	i8259off();
+	realmode0();
+	if(m->tss){
+		/*
+		 * Called from memory.c before initialization of mmu.
+		 * Don't turn interrupts on before the kernel is ready!
+		 */
+		i8259on();
+		putcr3(m->tss->cr3);
+	}
+	m->pdb[PDX(0)] = 0;	/* remove low mapping */
+	splx(s);
+	*ureg = realmoderegs;
+	unlock(&rmlock);
+}
+
+static long
+rtrapread(Chan*, void *a, long n, vlong off)
+{
+	if(off < 0)
+		error("badarg");
+	if(n+off > sizeof rmu)
+		n = sizeof rmu - off;
+	if(n <= 0)
+		return 0;
+	memmove(a, (char*)&rmu+off, n);
+	return n;
+}
+
+static long
+rtrapwrite(Chan*, void *a, long n, vlong off)
+{
+	if(off || n != sizeof rmu)
+		error("write a Ureg");
+	memmove(&rmu, a, sizeof rmu);
+	/*
+	 * Sanity check
+	 */
+	if(rmu.trap == 0x10){	/* VBE */
+		rmu.es = (LORMBUF>>4)&0xF000;
+		rmu.di = LORMBUF&0xFFFF;
+	}else
+		error("invalid trap arguments");
+	realmode(&rmu);
+	return n;
+}
+
+static long
+rmemrw(int isr, void *a, long n, vlong off)
+{
+	if(off >= 1024*1024 || off+n >= 1024*1024)
+		return 0;
+	if(off < 0 || n < 0)
+		error("bad offset/count");
+	if(isr)
+		memmove(a, KADDR((ulong)off), n);
+	else{
+		/* writes are more restricted */
+		if(LORMBUF <= off && off < LORMBUF+BY2PG
+		&& off+n <= LORMBUF+BY2PG)
+			{}
+		else
+			error("bad offset/count in write");
+		memmove(KADDR((ulong)off), a, n);
+	}
+	return n;
+}
+
+static long
+rmemread(Chan*, void *a, long n, vlong off)
+{
+	return rmemrw(1, a, n, off);
+}
+
+static long
+rmemwrite(Chan*, void *a, long n, vlong off)
+{
+	return rmemrw(0, a, n, off);
+}
+
+void
+realmodelink(void)
+{
+	addarchfile("realmode", 0660, rtrapread, rtrapwrite);
+	addarchfile("realmodemem", 0660, rmemread, rmemwrite);
+}
+

+ 0 - 7
sys/src/9/pc/reboot.h

@@ -1,7 +0,0 @@
-uchar rebootcode[]={
-0x8b,0x7c,0x24,0x04,0x89,0xf8,0x8b,0x74,0x24,0x08,0x8b,0x4c,0x24,0x0c,0x0f,0x20,
-0xc2,0x81,0xe2,0xff,0xff,0xff,0x7f,0x0f,0x22,0xc2,0x31,0xd2,0x0f,0x22,0xda,0x39,
-0xfe,0x7f,0x08,0x89,0xf2,0x01,0xca,0x39,0xfa,0x7f,0x07,0xfc,0xf3,0xa4,0x09,0xc0,
-0xff,0xe0,0x01,0xcf,0x01,0xce,0x4f,0x4e,0xfd,0xf3,0xa4,0xeb,0xf1,
-
-};

+ 339 - 28
sys/src/9/pc/screen.c

@@ -38,11 +38,14 @@ Cursor	arrow = {
 	},
 	},
 };
 };
 
 
+int didswcursorinit;
+
 int
 int
 screensize(int x, int y, int z, ulong chan)
 screensize(int x, int y, int z, ulong chan)
 {
 {
 	VGAscr *scr;
 	VGAscr *scr;
 
 
+	lock(&vgascreenlock);
 	memimageinit();
 	memimageinit();
 	scr = &vgascreen[0];
 	scr = &vgascreen[0];
 
 
@@ -50,7 +53,7 @@ screensize(int x, int y, int z, ulong chan)
 	 * BUG: need to check if any xalloc'ed memory needs to
 	 * BUG: need to check if any xalloc'ed memory needs to
 	 * be given back if aperture is set.
 	 * be given back if aperture is set.
 	 */
 	 */
-	if(scr->aperture == 0){
+	if(scr->paddr == 0){
 		int width = (x*z)/BI2WD;
 		int width = (x*z)/BI2WD;
 
 
 		gscreendata.bdata = xalloc(width*BY2WD*y);
 		gscreendata.bdata = xalloc(width*BY2WD*y);
@@ -58,19 +61,23 @@ screensize(int x, int y, int z, ulong chan)
 			error("screensize: vga soft memory");
 			error("screensize: vga soft memory");
 /*		memset(gscreendata.bdata, 0x72, width*BY2WD*y);	/* not really black */
 /*		memset(gscreendata.bdata, 0x72, width*BY2WD*y);	/* not really black */
 		scr->useflush = 1;
 		scr->useflush = 1;
-		scr->aperture = VGAMEM();
+		scr->paddr = VGAMEM();
+		scr->vaddr = KADDR(scr->paddr);
 		scr->apsize = 1<<16;
 		scr->apsize = 1<<16;
 	}
 	}
 	else
 	else
-		gscreendata.bdata = KADDR(scr->aperture);
+		gscreendata.bdata = scr->vaddr;
 
 
 	if(gscreen)
 	if(gscreen)
 		freememimage(gscreen);
 		freememimage(gscreen);
+	scr->gscreen = nil;
 
 
 	gscreen = allocmemimaged(Rect(0,0,x,y), chan, &gscreendata);
 	gscreen = allocmemimaged(Rect(0,0,x,y), chan, &gscreendata);
 	vgaimageinit(chan);
 	vgaimageinit(chan);
-	if(gscreen == nil)
+	if(gscreen == nil){
+		unlock(&vgascreenlock);
 		return -1;
 		return -1;
+	}
 
 
 	if(scr->dev && scr->dev->flush)
 	if(scr->dev && scr->dev->flush)
 		scr->useflush = 1;
 		scr->useflush = 1;
@@ -81,7 +88,10 @@ screensize(int x, int y, int z, ulong chan)
 	scr->gscreen = gscreen;
 	scr->gscreen = gscreen;
 
 
 	physgscreenr = gscreen->r;
 	physgscreenr = gscreen->r;
+	unlock(&vgascreenlock);
 
 
+	if(didswcursorinit)
+		swcursorinit();
 	drawcmap();
 	drawcmap();
 	return 0;
 	return 0;
 }
 }
@@ -90,32 +100,31 @@ int
 screenaperture(int size, int align)
 screenaperture(int size, int align)
 {
 {
 	VGAscr *scr;
 	VGAscr *scr;
-	ulong aperture;
 
 
 	scr = &vgascreen[0];
 	scr = &vgascreen[0];
 
 
-	if(size == 0){
-		if(scr->aperture && scr->isupamem)
-			upafree(scr->aperture, scr->apsize);
-		scr->aperture = 0;
-		scr->isupamem = 0;
+	if(scr->paddr)	/* set up during enable */
 		return 0;
 		return 0;
-	}
+
+	if(size == 0)
+		return 0;
+
 	if(scr->dev && scr->dev->linear){
 	if(scr->dev && scr->dev->linear){
-		aperture = scr->dev->linear(scr, &size, &align);
-		if(aperture == 0)
-			return 1;
-	}else{
-		aperture = upamalloc(0, size, align);
-		if(aperture == 0)
-			return 1;
-
-		if(scr->aperture && scr->isupamem)
-			upafree(scr->aperture, scr->apsize);
-		scr->isupamem = 1;
+		scr->dev->linear(scr, size, align);
+		return 0;
 	}
 	}
 
 
-	scr->aperture = aperture;
+	/*
+	 * Need to allocate some physical address space.
+	 * The driver will tell the card to use it.
+	 */
+	size = PGROUND(size);
+	scr->paddr = upaalloc(size, align);
+	if(scr->paddr == 0)
+		return -1;
+	scr->vaddr = vmap(scr->paddr, size);
+	if(scr->vaddr == nil)
+		return -1;
 	scr->apsize = size;
 	scr->apsize = size;
 
 
 	return 0;
 	return 0;
@@ -179,7 +188,7 @@ flushmemscreen(Rectangle r)
 	off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x*scr->gscreen->depth)/8;
 	off = r.min.y*scr->gscreen->width*BY2WD+(r.min.x*scr->gscreen->depth)/8;
 	page = off/scr->apsize;
 	page = off/scr->apsize;
 	off %= scr->apsize;
 	off %= scr->apsize;
-	disp = KADDR(scr->aperture);
+	disp = scr->vaddr;
 	sdisp = disp+off;
 	sdisp = disp+off;
 	edisp = disp+scr->apsize;
 	edisp = disp+scr->apsize;
 
 
@@ -339,17 +348,29 @@ int
 hwdraw(Memdrawparam *par)
 hwdraw(Memdrawparam *par)
 {
 {
 	VGAscr *scr;
 	VGAscr *scr;
-	Memimage *dst, *src;
+	Memimage *dst, *src, *mask;
 	int m;
 	int m;
 
 
 	if(hwaccel == 0)
 	if(hwaccel == 0)
 		return 0;
 		return 0;
 
 
-	dst = par->dst;
 	scr = &vgascreen[0];
 	scr = &vgascreen[0];
-	if(dst == nil || dst->data == nil)
+	if((dst=par->dst) == nil || dst->data == nil)
+		return 0;
+	if((src=par->src) == nil || src->data == nil)
+		return 0;
+	if((mask=par->mask) == nil || mask->data == nil)
 		return 0;
 		return 0;
 
 
+	if(scr->cur == &swcursor){
+		if(dst->data->bdata == gscreendata.bdata)
+			swcursoravoid(par->r);
+		if(src->data->bdata == gscreendata.bdata)
+			swcursoravoid(par->sr);
+		if(mask->data->bdata == gscreendata.bdata)
+			swcursoravoid(par->mr);
+	}
+	
 	if(dst->data->bdata != gscreendata.bdata)
 	if(dst->data->bdata != gscreendata.bdata)
 		return 0;
 		return 0;
 
 
@@ -374,7 +395,6 @@ hwdraw(Memdrawparam *par)
 	 * the source is not replicated, memmove suffices.
 	 * the source is not replicated, memmove suffices.
 	 */
 	 */
 	m = Simplemask|Fullmask;
 	m = Simplemask|Fullmask;
-	src = par->src;
 	if(scr->scroll
 	if(scr->scroll
 	&& src->data->bdata==dst->data->bdata
 	&& src->data->bdata==dst->data->bdata
 	&& !(src->flags&Falpha)
 	&& !(src->flags&Falpha)
@@ -398,3 +418,294 @@ blankscreen(int blank)
 			vgablank(scr, blank);
 			vgablank(scr, blank);
 	}
 	}
 }
 }
+
+void
+vgalinearpciid(VGAscr *scr, int vid, int did)
+{
+	Pcidev *p;
+
+	p = nil;
+	while((p = pcimatch(p, vid, 0)) != nil){
+		if(p->ccrb != 3)	/* video card */
+			continue;
+		if(did != 0 && p->did != did)
+			continue;
+		break;
+	}
+	if(p == nil)
+		error("pci video card not found");
+
+	scr->pci = p;
+	vgalinearpci(scr);
+}
+
+void
+vgalinearpci(VGAscr *scr)
+{
+	ulong paddr;
+	int i, size, best;
+	Pcidev *p;
+	
+	p = scr->pci;
+	if(p == nil)
+		return;
+
+	/*
+	 * Scan for largest memory region on card.
+	 * Some S3 cards (e.g. Savage) have enormous
+	 * mmio regions (but even larger frame buffers).
+	 */
+	best = -1;
+	for(i=0; i<nelem(p->mem); i++){
+		if(p->mem[i].bar&1)	/* not memory */
+			continue;
+		if(p->mem[i].size < 640*480)	/* not big enough */
+			continue;
+		if(best==-1 || p->mem[i].size > p->mem[best].size)
+			best = i;
+	}
+	if(best >= 0){
+		paddr = p->mem[best].bar & ~0x0F;
+		size = p->mem[best].size;
+		vgalinearaddr(scr, paddr, size);
+		return;
+	}
+	error("no video memory found on pci card");
+}
+
+void
+vgalinearaddr(VGAscr *scr, ulong paddr, int size)
+{
+	int x, nsize;
+	ulong npaddr;
+
+	/*
+	 * new approach.  instead of trying to resize this
+	 * later, let's assume that we can just allocate the
+	 * entire window to start with.
+	 */
+
+	if(scr->paddr == paddr && size <= scr->apsize)
+		return;
+
+	if(scr->paddr){
+		/*
+		 * could call vunmap and vmap,
+		 * but worried about dangling pointers in devdraw
+		 */
+		error("cannot grow vga frame buffer");
+	}
+	
+	/* round to page boundary, just in case */
+	x = paddr&(BY2PG-1);
+	npaddr = paddr-x;
+	nsize = PGROUND(size+x);
+
+	scr->vaddr = vmap(npaddr, nsize);
+	if(scr->vaddr == 0)
+		error("cannot allocate vga frame buffer");
+	scr->vaddr = (char*)scr->vaddr+x;
+	scr->paddr = paddr;
+	scr->apsize = nsize;
+}
+
+
+/*
+ * Software cursor. 
+ */
+int	swvisible;	/* is the cursor visible? */
+int	swenabled;	/* is the cursor supposed to be on the screen? */
+Memimage*	swback;	/* screen under cursor */
+Memimage*	swimg;	/* cursor image */
+Memimage*	swmask;	/* cursor mask */
+Memimage*	swimg1;
+Memimage*	swmask1;
+
+Point	swoffset;
+Rectangle	swrect;	/* screen rectangle in swback */
+Point	swpt;	/* desired cursor location */
+Point	swvispt;	/* actual cursor location */
+int	swvers;	/* incremented each time cursor image changes */
+int	swvisvers;	/* the version on the screen */
+
+/*
+ * called with drawlock locked for us, most of the time.
+ * kernel prints at inopportune times might mean we don't
+ * hold the lock, but memimagedraw is now reentrant so
+ * that should be okay: worst case we get cursor droppings.
+ */
+void
+swcursorhide(void)
+{
+	if(swvisible == 0)
+		return;
+	if(swback == nil)
+		return;
+	swvisible = 0;
+	memimagedraw(gscreen, swrect, swback, ZP, memopaque, ZP, S);
+}
+
+void
+swcursoravoid(Rectangle r)
+{
+	if(swvisible && rectXrect(r, swrect))
+		swcursorhide();
+}
+
+void
+swcursordraw(void)
+{
+	if(swvisible)
+		return;
+	if(swenabled == 0)
+		return;
+	if(swback == nil || swimg1 == nil || swmask1 == nil)
+		return;
+	assert(!canqlock(&drawlock));
+	swvispt = swpt;
+	swvisvers = swvers;
+	swrect = rectaddpt(Rect(0,0,16,16), swvispt);
+	memimagedraw(swback, swback->r, gscreen, swpt, memopaque, ZP, S);
+	memimagedraw(gscreen, swrect, swimg1, ZP, swmask1, ZP, SoverD);
+	swvisible = 1;
+}
+
+/*
+ * Need to lock drawlock for ourselves.
+ */
+void
+swenable(VGAscr*)
+{
+	swenabled = 1;
+	if(canqlock(&drawlock)){
+		swcursordraw();
+		qunlock(&drawlock);
+	}
+}
+
+void
+swdisable(VGAscr*)
+{
+	swenabled = 0;
+	if(canqlock(&drawlock)){
+		swcursorhide();
+		qunlock(&drawlock);
+	}
+}
+
+void
+swload(VGAscr*, Cursor *curs)
+{
+	uchar *ip, *mp;
+	int i, j, set, clr;
+
+	if(!swimg || !swmask || !swimg1 || !swmask1)
+		return;
+	/*
+	 * Build cursor image and mask.
+	 * Image is just the usual cursor image
+	 * but mask is a transparent alpha mask.
+	 * 
+	 * The 16x16x8 memimages do not have
+	 * padding at the end of their scan lines.
+	 */
+	ip = byteaddr(swimg, ZP);
+	mp = byteaddr(swmask, ZP);
+	for(i=0; i<32; i++){
+		set = curs->set[i];
+		clr = curs->clr[i];
+		for(j=0x80; j; j>>=1){
+			*ip++ = set&j ? 0x00 : 0xFF;
+			*mp++ = (clr|set)&j ? 0xFF : 0x00;
+		}
+	}
+	swoffset = curs->offset;
+	swvers++;
+	memimagedraw(swimg1, swimg1->r, swimg, ZP, memopaque, ZP, S);
+	memimagedraw(swmask1, swmask1->r, swmask, ZP, memopaque, ZP, S);
+}
+
+int
+swmove(VGAscr*, Point p)
+{
+	swpt = addpt(p, swoffset);
+	return 0;
+}
+
+void
+swcursorclock(void)
+{
+	int x;
+
+	if(!swenabled)
+		return;
+	if(swvisible && eqpt(swpt, swvispt) && swvers==swvisvers)
+		return;
+
+	x = splhi();
+	if(swenabled)
+	if(!swvisible || !eqpt(swpt, swvispt) || swvers!=swvisvers)
+	if(canqlock(&drawlock)){
+		swcursorhide();
+		swcursordraw();
+		qunlock(&drawlock);
+	}
+	splx(x);
+}
+
+void
+swcursorinit(void)
+{
+	static int init, warned;
+	VGAscr *scr;
+
+	didswcursorinit = 1;
+	if(!init){
+		init = 1;
+		addclock0link(swcursorclock, 50);
+	}
+	scr = &vgascreen[0];
+	if(scr==nil || scr->gscreen==nil)
+		return;
+
+	if(scr->dev == nil || scr->dev->linear == nil){
+		if(!warned){
+			print("cannot use software cursor on non-linear vga screen\n");
+			warned = 1;
+		}
+		return;
+	}
+
+	if(swback){
+		freememimage(swback);
+		freememimage(swmask);
+		freememimage(swmask1);
+		freememimage(swimg);
+		freememimage(swimg1);
+	}
+
+	swback = allocmemimage(Rect(0,0,32,32), gscreen->chan);
+	swmask = allocmemimage(Rect(0,0,16,16), GREY8);
+	swmask1 = allocmemimage(Rect(0,0,16,16), GREY1);
+	swimg = allocmemimage(Rect(0,0,16,16), GREY8);
+	swimg1 = allocmemimage(Rect(0,0,16,16), GREY1);
+	if(swback==nil || swmask==nil || swmask1==nil || swimg==nil || swimg1 == nil){
+		print("software cursor: allocmemimage: %r");
+		return;
+	}
+
+	memfillcolor(swmask, DOpaque);
+	memfillcolor(swmask1, DOpaque);
+	memfillcolor(swimg, DBlack);
+	memfillcolor(swimg1, DBlack);
+}
+
+VGAcur swcursor =
+{
+	"soft",
+	swenable,
+	swdisable,
+	swload,
+	swmove,
+};
+

+ 25 - 7
sys/src/9/pc/screen.h

@@ -67,7 +67,7 @@ struct VGAdev {
 	void	(*enable)(VGAscr*);
 	void	(*enable)(VGAscr*);
 	void	(*disable)(VGAscr*);
 	void	(*disable)(VGAscr*);
 	void	(*page)(VGAscr*, int);
 	void	(*page)(VGAscr*, int);
-	ulong	(*linear)(VGAscr*, int*, int*);
+	void	(*linear)(VGAscr*, int, int);
 	void	(*drawinit)(VGAscr*);
 	void	(*drawinit)(VGAscr*);
 	int	(*fill)(VGAscr*, Rectangle, ulong);
 	int	(*fill)(VGAscr*, Rectangle, ulong);
 	void	(*ovlctl)(VGAscr*, Chan*, void*, int);
 	void	(*ovlctl)(VGAscr*, Chan*, void*, int);
@@ -91,6 +91,7 @@ struct VGAcur {
 struct VGAscr {
 struct VGAscr {
 	Lock	devlock;
 	Lock	devlock;
 	VGAdev*	dev;
 	VGAdev*	dev;
+	Pcidev*	pci;
 
 
 	VGAcur*	cur;
 	VGAcur*	cur;
 	ulong	storage;
 	ulong	storage;
@@ -98,16 +99,16 @@ struct VGAscr {
 
 
 	int	useflush;
 	int	useflush;
 
 
-	ulong	aperture;			/* physical address */
-	int	isupamem;
-	int	apsize;
+	ulong	paddr;		/* frame buffer */
+	void*	vaddr;
+	int		apsize;
 
 
 	ulong	io;				/* device specific registers */
 	ulong	io;				/* device specific registers */
-
+	ulong	*mmio;
+	
 	ulong	colormap[Pcolours][3];
 	ulong	colormap[Pcolours][3];
 	int	palettedepth;
 	int	palettedepth;
 
 
-	ulong	*mmio;
 	Memimage* gscreen;
 	Memimage* gscreen;
 	Memdata* gscreendata;
 	Memdata* gscreendata;
 	Memsubfont* memdefont;
 	Memsubfont* memdefont;
@@ -128,6 +129,7 @@ enum {
 
 
 /* mouse.c */
 /* mouse.c */
 extern void mousectl(Cmdbuf*);
 extern void mousectl(Cmdbuf*);
+extern void mouseresize(void);
 
 
 /* screen.c */
 /* screen.c */
 extern int		hwaccel;	/* use hw acceleration; default on */
 extern int		hwaccel;	/* use hw acceleration; default on */
@@ -144,18 +146,34 @@ extern int	screenaperture(int, int);
 extern Rectangle physgscreenr;	/* actual monitor size */
 extern Rectangle physgscreenr;	/* actual monitor size */
 extern void	blankscreen(int);
 extern void	blankscreen(int);
 
 
+extern VGAcur swcursor;
+extern void swcursorinit(void);
+extern void swcursorhide(void);
+extern void swcursoravoid(Rectangle);
+extern void swcursorunhide(void);
+
 /* devdraw.c */
 /* devdraw.c */
 extern void	deletescreenimage(void);
 extern void	deletescreenimage(void);
+extern void	resetscreenimage(void);
 extern int		drawhasclients(void);
 extern int		drawhasclients(void);
 extern ulong	blanktime;
 extern ulong	blanktime;
 extern void	setscreenimageclipr(Rectangle);
 extern void	setscreenimageclipr(Rectangle);
 extern void	drawflush(void);
 extern void	drawflush(void);
 extern int drawidletime(void);
 extern int drawidletime(void);
+extern QLock	drawlock;
 
 
 /* vga.c */
 /* vga.c */
 extern void	vgascreenwin(VGAscr*);
 extern void	vgascreenwin(VGAscr*);
 extern void	vgaimageinit(ulong);
 extern void	vgaimageinit(ulong);
-extern ulong	vgapcilinear(VGAscr*, int*, int*, int, int);
+extern void	vgalinearpciid(VGAscr*, int, int);
+extern void	vgalinearpci(VGAscr*);
+extern void	vgalinearaddr(VGAscr*, ulong, int);
 
 
 extern void	drawblankscreen(int);
 extern void	drawblankscreen(int);
 extern void	vgablank(VGAscr*, int);
 extern void	vgablank(VGAscr*, int);
+
+extern Lock	vgascreenlock;
+
+
+
+

+ 190 - 68
sys/src/9/pc/sd53c8xx.c

@@ -52,8 +52,9 @@ extern SDifc sd53c8xxifc;
 
 
 #else
 #else
 
 
-#define KPRINT	if(0) print
-#define IPRINT	if(0) print
+static int idebug = 1;
+#define KPRINT	if(0) iprint
+#define IPRINT	if(idebug) iprint
 #define DEBUG(n)	(0)
 #define DEBUG(n)	(0)
 #define IFLUSH()
 #define IFLUSH()
 
 
@@ -304,7 +305,6 @@ typedef struct Controller {
 	struct {
 	struct {
 		Lock;
 		Lock;
 		uchar head[4];		/* head of free list (NCR byte order) */
 		uchar head[4];		/* head of free list (NCR byte order) */
-		Dsa	*tail;
 		Dsa	*freechain;
 		Dsa	*freechain;
 	} dsalist;
 	} dsalist;
 
 
@@ -383,32 +383,51 @@ oprint(char *format, ...)
 
 
 #include "sd53c8xx.i"
 #include "sd53c8xx.i"
 
 
+/*
+ * We used to use a linked list of Dsas with nil as the terminator,
+ * but occasionally the 896 card seems not to notice that the 0
+ * is really a 0, and then it tries to reference the Dsa at address 0.
+ * To address this, we use a sentinel dsa that links back to itself
+ * and has state A_STATE_END.  If the card takes an iteration or
+ * two to notice that the state says A_STATE_END, that's no big 
+ * deal.  Clearly this isn't the right approach, but I'm just
+ * stumped.  Even with this, we occasionally get prints about
+ * "WSR set", usually with about the same frequency that the
+ * card used to walk past 0. 
+ */
+static Dsa *dsaend;
+
+static Dsa*
+dsaallocnew(Controller *c)
+{
+	Dsa *d;
+	
+	/* c->dsalist must be ilocked */
+	d = xalloc(sizeof *d);
+	lesetl(d->next, legetl(c->dsalist.head));
+	lesetl(&d->stateb, A_STATE_FREE);
+	coherence();
+	lesetl(c->dsalist.head, DMASEG(d));
+	coherence();
+	return d;
+}
+
 static Dsa *
 static Dsa *
 dsaalloc(Controller *c, int target, int lun)
 dsaalloc(Controller *c, int target, int lun)
 {
 {
 	Dsa *d;
 	Dsa *d;
 
 
 	ilock(&c->dsalist);
 	ilock(&c->dsalist);
-	if ((d = c->dsalist.freechain) == 0) {
-		d = xalloc(sizeof(*d));
-		if (DEBUG(1)) {
-			KPRINT(PRINTPREFIX "%d/%d: allocated new dsa %lux\n", target, lun, (ulong)d);
-		}
-		lesetl(d->next, 0);
-		lesetl(&d->stateb, A_STATE_ALLOCATED);
-		if (legetl(c->dsalist.head) == 0)
-			lesetl(c->dsalist.head, DMASEG(d));	/* ATOMIC?!? */
-		else
-			lesetl(c->dsalist.tail->next, DMASEG(d));	/* ATOMIC?!? */
-		c->dsalist.tail = d;
-	}
-	else {
-		if (DEBUG(1)) {
-			KPRINT(PRINTPREFIX "%d/%d: reused dsa %lux\n", target, lun, (ulong)d);
-		}
-		c->dsalist.freechain = d->freechain;
-		lesetl(&d->stateb, A_STATE_ALLOCATED);
+	if ((d = c->dsalist.freechain) != 0) {
+		if (DEBUG(1))
+			IPRINT(PRINTPREFIX "%d/%d: reused dsa %lux\n", target, lun, (ulong)d);
+	} else {	
+		d = dsaallocnew(c);
+		if (DEBUG(1))
+			IPRINT(PRINTPREFIX "%d/%d: allocated dsa %lux\n", target, lun, (ulong)d);
 	}
 	}
+	c->dsalist.freechain = d->freechain;
+	lesetl(&d->stateb, A_STATE_ALLOCATED);
 	iunlock(&c->dsalist);
 	iunlock(&c->dsalist);
 	d->target = target;
 	d->target = target;
 	d->lun = lun;
 	d->lun = lun;
@@ -425,11 +444,50 @@ dsafree(Controller *c, Dsa *d)
 	iunlock(&c->dsalist);
 	iunlock(&c->dsalist);
 }
 }
 
 
+static void
+dsadump(Controller *c)
+{
+	Dsa *d;
+	u32int *a;
+	
+	iprint("dsa controller list: c=%p head=%.8lux\n", c, legetl(c->dsalist.head));
+	for(d=KPTR(legetl(c->dsalist.head)); d != dsaend; d=KPTR(legetl(d->next))){
+		if(d == (void*)-1){
+			iprint("\t dsa %p\n", d);
+			break;
+		}
+		a = (u32int*)d;
+		iprint("\tdsa %p %.8ux %.8ux %.8ux %.8ux %.8ux %.8ux\n", a, a[0], a[1], a[2], a[3], a[4], a[5]);
+	}
+
+/*
+	a = KPTR(c->scriptpa+E_dsa_addr);
+	iprint("dsa_addr: %.8ux %.8ux %.8ux %.8ux %.8ux\n",
+		a[0], a[1], a[2], a[3], a[4]);
+	a = KPTR(c->scriptpa+E_issue_addr);
+	iprint("issue_addr: %.8ux %.8ux %.8ux %.8ux %.8ux\n",
+		a[0], a[1], a[2], a[3], a[4]);
+
+	a = KPTR(c->scriptpa+E_issue_test_begin);
+	e = KPTR(c->scriptpa+E_issue_test_end);
+	iprint("issue_test code (at offset %.8ux):\n", E_issue_test_begin);
+	
+	i = 0;
+	for(; a<e; a++){
+		iprint(" %.8ux", *a);
+		if(++i%8 == 0)
+			iprint("\n");
+	}
+	if(i%8)
+		iprint("\n");
+*/
+}
+
 static Dsa *
 static Dsa *
 dsafind(Controller *c, uchar target, uchar lun, uchar state)
 dsafind(Controller *c, uchar target, uchar lun, uchar state)
 {
 {
 	Dsa *d;
 	Dsa *d;
-	for (d = KPTR(legetl(c->dsalist.head)); d; d = KPTR(legetl(d->next))) {
+	for (d = KPTR(legetl(c->dsalist.head)); d != dsaend; d = KPTR(legetl(d->next))) {
 		if (d->target != 0xff && d->target != target)
 		if (d->target != 0xff && d->target != target)
 			continue;
 			continue;
 		if (lun != 0xff && d->lun != lun)
 		if (lun != 0xff && d->lun != lun)
@@ -764,6 +822,7 @@ start(Controller *c, long entry)
 	c->running = 1;
 	c->running = 1;
 	p = c->scriptpa + entry;
 	p = c->scriptpa + entry;
 	lesetl(c->n->dsp, p);
 	lesetl(c->n->dsp, p);
+	coherence();
 	if (c->ssm)
 	if (c->ssm)
 		c->n->dcntl |= 0x4;		/* start DMA in SSI mode */
 		c->n->dcntl |= 0x4;		/* start DMA in SSI mode */
 }
 }
@@ -775,6 +834,7 @@ ncrcontinue(Controller *c)
 		panic(PRINTPREFIX "ncrcontinue called while running");
 		panic(PRINTPREFIX "ncrcontinue called while running");
 	/* set the start DMA bit to continue execution */
 	/* set the start DMA bit to continue execution */
 	c->running = 1;
 	c->running = 1;
+	coherence();
 	c->n->dcntl |= 0x4;
 	c->n->dcntl |= 0x4;
 }
 }
 
 
@@ -1126,6 +1186,7 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 	int wakeme = 0;
 	int wakeme = 0;
 	int cont = -1;
 	int cont = -1;
 	Dsa *dsa;
 	Dsa *dsa;
+	ulong dsapa;
 	Controller *c = a;
 	Controller *c = a;
 	Ncr *n = c->n;
 	Ncr *n = c->n;
 
 
@@ -1143,7 +1204,7 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 		}
 		}
 		n->istat = Intf;
 		n->istat = Intf;
 		/* search for structures in A_STATE_DONE */
 		/* search for structures in A_STATE_DONE */
-		for (d = KPTR(legetl(c->dsalist.head)); d; d = KPTR(legetl(d->next))) {
+		for (d = KPTR(legetl(c->dsalist.head)); d != dsaend; d = KPTR(legetl(d->next))) {
 			if (d->stateb == A_STATE_DONE) {
 			if (d->stateb == A_STATE_DONE) {
 				d->p9status = d->status;
 				d->p9status = d->status;
 				if (DEBUG(1)) {
 				if (DEBUG(1)) {
@@ -1168,7 +1229,25 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 
 
 	sist = (n->sist1<<8)|n->sist0;	/* BUG? can two-byte read be inconsistent? */
 	sist = (n->sist1<<8)|n->sist0;	/* BUG? can two-byte read be inconsistent? */
 	dstat = n->dstat;
 	dstat = n->dstat;
-	dsa = (Dsa *)DMASEG_TO_KADDR(legetl(n->dsa));
+	dsapa = legetl(n->dsa);
+
+	/*
+	 * Can't compute dsa until we know that dsapa is valid.
+	 */
+	if(dsapa < -KZERO)
+		dsa = (Dsa*)DMASEG_TO_KADDR(dsapa);
+	else{
+		dsa = nil;
+		/*
+		 * happens at startup on some cards but we 
+		 * don't actually deref dsa because none of the
+		 * flags we are about are set.
+		 * still, print in case that changes and we're
+		 * about to dereference nil.
+		 */
+		iprint("sd53c8xxinterrupt: dsa=%.8lux istat=%ux sist=%ux dstat=%ux\n", dsapa, istat, sist, dstat);
+	}
+
 	c->running = 0;
 	c->running = 0;
 	if (istat & Sip) {
 	if (istat & Sip) {
 		if (DEBUG(1)) {
 		if (DEBUG(1)) {
@@ -1315,6 +1394,7 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 			}
 			}
 			dsa->p9status = SDtimeout;
 			dsa->p9status = SDtimeout;
 			dsa->stateb = A_STATE_DONE;
 			dsa->stateb = A_STATE_DONE;
+			coherence();
 			softreset(c);
 			softreset(c);
 			cont = E_issue_check;
 			cont = E_issue_check;
 			wakeme = 1;
 			wakeme = 1;
@@ -1336,8 +1416,7 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 			IPRINT("dstat = %.2x\n", dstat);
 			IPRINT("dstat = %.2x\n", dstat);
 		}
 		}
 		/*else*/ if (dstat & Ssi) {
 		/*else*/ if (dstat & Ssi) {
-			ulong *p = DMASEG_TO_KADDR(legetl(n->dsp));
-			ulong w = (uchar *)p - (uchar *)c->script;
+			ulong w = legetl(n->dsp) - c->scriptpa;
 			IPRINT("[%lux]", w);
 			IPRINT("[%lux]", w);
 			USED(w);
 			USED(w);
 			cont = -2;	/* restart */
 			cont = -2;	/* restart */
@@ -1375,6 +1454,15 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 				dumpncrregs(c, 1);
 				dumpncrregs(c, 1);
 				wakeme = 1;
 				wakeme = 1;
 				break;
 				break;
+			case A_SIR_NOTIFY_LOAD_STATE:
+				IPRINT(PRINTPREFIX ": load_state dsa=%p\n", dsa);
+				if (dsa == (void*)KZERO || dsa == (void*)-1) {
+					dsadump(c);
+					dumpncrregs(c, 1);
+					panic("bad dsa in load_state");
+				}
+				cont = -2;
+				break;
 			case A_SIR_NOTIFY_MSG_IN:
 			case A_SIR_NOTIFY_MSG_IN:
 				IPRINT(PRINTPREFIX "%d/%d: msg_in %d\n",
 				IPRINT(PRINTPREFIX "%d/%d: msg_in %d\n",
 				    dsa->target, dsa->lun, n->sfbr);
 				    dsa->target, dsa->lun, n->sfbr);
@@ -1431,7 +1519,7 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 				cont = -2;
 				cont = -2;
 				break;
 				break;
 			case A_SIR_NOTIFY_ISSUE:
 			case A_SIR_NOTIFY_ISSUE:
-				IPRINT(PRINTPREFIX "%d/%d: issue:", dsa->target, dsa->lun);
+				IPRINT(PRINTPREFIX "%d/%d: issue dsa=%p end=%p:", dsa->target, dsa->lun, dsa, dsaend);
 			dsadump:
 			dsadump:
 				IPRINT(" tgt=%d", dsa->target);
 				IPRINT(" tgt=%d", dsa->target);
 				IPRINT(" time=%ld", TK2MS(m->ticks));
 				IPRINT(" time=%ld", TK2MS(m->ticks));
@@ -1447,7 +1535,7 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 				cont = -2;
 				cont = -2;
 				break;
 				break;
 			case A_SIR_NOTIFY_DUMP_NEXT_CODE: {
 			case A_SIR_NOTIFY_DUMP_NEXT_CODE: {
-				ulong *dsp = DMASEG_TO_KADDR(legetl(n->dsp));
+				ulong *dsp = c->script + (legetl(n->dsp)-c->scriptpa)/4;
 				int x;
 				int x;
 				IPRINT(PRINTPREFIX "code at %lux", dsp - c->script);
 				IPRINT(PRINTPREFIX "code at %lux", dsp - c->script);
 				for (x = 0; x < 6; x++) {
 				for (x = 0; x < 6; x++) {
@@ -1475,9 +1563,9 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 				cont = -2;
 				cont = -2;
 				break;
 				break;
 			case A_error_reselected:		/* dsa isn't valid here */
 			case A_error_reselected:		/* dsa isn't valid here */
-				print(PRINTPREFIX "reselection error\n");
+				iprint(PRINTPREFIX "reselection error\n");
 				dumpncrregs(c, 1);
 				dumpncrregs(c, 1);
-				for (dsa = KPTR(legetl(c->dsalist.head)); dsa; dsa = KPTR(legetl(dsa->next))) {
+				for (dsa = KPTR(legetl(c->dsalist.head)); dsa != dsaend; dsa = KPTR(legetl(dsa->next))) {
 					IPRINT(PRINTPREFIX "dsa target %d lun %d state %d\n", dsa->target, dsa->lun, dsa->stateb);
 					IPRINT(PRINTPREFIX "dsa target %d lun %d state %d\n", dsa->target, dsa->lun, dsa->stateb);
 				}
 				}
 				break;
 				break;
@@ -1489,15 +1577,40 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
 			}
 			}
 		}
 		}
 		/*else*/ if (dstat & Iid) {
 		/*else*/ if (dstat & Iid) {
-			ulong addr = legetl(n->dsp);
-			ulong dbc = (n->dbc[2]<<16)|(n->dbc[1]<<8)|n->dbc[0];
+			int i, target, lun;
+			ulong addr, dbc, *v;
+			
+			addr = legetl(n->dsp);
+			if(dsa){
+				target = dsa->target;
+				lun = dsa->lun;
+			}else{
+				target = -1;
+				lun = -1;
+			}
+			dbc = (n->dbc[2]<<16)|(n->dbc[1]<<8)|n->dbc[0];
+
+		//	if(dsa == nil)
+				idebug++;
 			IPRINT(PRINTPREFIX "%d/%d: Iid pa=%.8lux sa=%.8lux dbc=%lux\n",
 			IPRINT(PRINTPREFIX "%d/%d: Iid pa=%.8lux sa=%.8lux dbc=%lux\n",
-			    dsa->target, dsa->lun,
+			    target, lun,
 			    addr, addr - c->scriptpa, dbc);
 			    addr, addr - c->scriptpa, dbc);
-			addr = (ulong)DMASEG_TO_KADDR(addr);
-			IPRINT("%.8lux %.8lux %.8lux\n",
-			    *(ulong *)(addr - 12), *(ulong *)(addr - 8), *(ulong *)(addr - 4));
+			addr = (ulong)c->script + addr - c->scriptpa;
+			addr -= 64;
+			addr &= ~63;
+			v = (ulong*)addr;
+			for(i=0; i<8; i++){
+				IPRINT("%.8lux: %.8lux %.8lux %.8lux %.8lux\n", 
+					addr, v[0], v[1], v[2], v[3]);
+				addr += 4*4;
+				v += 4;
+			}
 			USED(addr, dbc);
 			USED(addr, dbc);
+			if(dsa == nil){
+				dsadump(c);
+				dumpncrregs(c, 1);
+				panic("bad dsa");
+			}
 			dsa->p9status = SDeio;
 			dsa->p9status = SDeio;
 			wakeme = 1;
 			wakeme = 1;
 		}
 		}
@@ -1634,6 +1747,7 @@ sd53c8xxrio(SDreq* r)
 
 
 	if((target = r->unit->subno) == 0x07)
 	if((target = r->unit->subno) == 0x07)
 		return r->status = SDtimeout;	/* assign */
 		return r->status = SDtimeout;	/* assign */
+
 	c = r->unit->dev->ctlr;
 	c = r->unit->dev->ctlr;
 
 
 	check = 0;
 	check = 0;
@@ -1702,7 +1816,7 @@ docheck:
 
 
 	setmovedata(&d->msg_out_buf, DMASEG(d->msg_out), bc);
 	setmovedata(&d->msg_out_buf, DMASEG(d->msg_out), bc);
 	setmovedata(&d->cmd_buf, DMASEG(r->cmd), r->clen);
 	setmovedata(&d->cmd_buf, DMASEG(r->cmd), r->clen);
-	calcblockdma(d, DMASEG(r->data), r->dlen);
+	calcblockdma(d, r->data ? DMASEG(r->data) : 0, r->dlen);
 
 
 	if (DEBUG(0)) {
 	if (DEBUG(0)) {
 		KPRINT(PRINTPREFIX "%d/%d: exec: ", target, r->lun);
 		KPRINT(PRINTPREFIX "%d/%d: exec: ", target, r->lun);
@@ -1722,14 +1836,15 @@ docheck:
 
 
 	d->p9status = SDnostatus;
 	d->p9status = SDnostatus;
 	d->parityerror = 0;
 	d->parityerror = 0;
-
+	coherence();
 	d->stateb = A_STATE_ISSUE;		/* start operation */
 	d->stateb = A_STATE_ISSUE;		/* start operation */
+	coherence();
 
 
 	ilock(c);
 	ilock(c);
 	if (c->ssm)
 	if (c->ssm)
-		c->n->dcntl |= 0x10;		/* SSI */
+		c->n->dcntl |= 0x10;		/* single step */
 	if (c->running) {
 	if (c->running) {
-		c->n->istat |= Sigp;
+		c->n->istat = Sigp;
 	}
 	}
 	else {
 	else {
 		start(c, E_issue_check);
 		start(c, E_issue_check);
@@ -1802,6 +1917,7 @@ docheck:
 		 * so the Dsa can be re-used.
 		 * so the Dsa can be re-used.
 		 */
 		 */
 		lesetl(&d->stateb, A_STATE_ALLOCATED);
 		lesetl(&d->stateb, A_STATE_ALLOCATED);
+		coherence();
 		goto docheck;
 		goto docheck;
 	}
 	}
 	qunlock(&c->q[target]);
 	qunlock(&c->q[target]);
@@ -1825,12 +1941,14 @@ docheck:
 	return r->status = status;
 	return r->status = status;
 }
 }
 
 
+#define	vpt ((ulong*)VPT)
+#define	VPTX(va)		(((ulong)(va))>>12)
 static void
 static void
 cribbios(Controller *c)
 cribbios(Controller *c)
 {
 {
 	c->bios.scntl3 = c->n->scntl3;
 	c->bios.scntl3 = c->n->scntl3;
 	c->bios.stest2 = c->n->stest2;
 	c->bios.stest2 = c->n->stest2;
-	KPRINT(PRINTPREFIX "bios scntl3(%.2x) stest2(%.2x)\n", c->bios.scntl3, c->bios.stest2);
+	print(PRINTPREFIX "bios scntl3(%.2x) stest2(%.2x)\n", c->bios.scntl3, c->bios.stest2);
 }
 }
 
 
 static int
 static int
@@ -1879,8 +1997,6 @@ static Variant variant[] = {
 { SYM_1011_DID,   0xff, "SYM53C1010",	Burst128, 16, 64, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 },
 { SYM_1011_DID,   0xff, "SYM53C1010",	Burst128, 16, 64, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 },
 };
 };
 
 
-#define offsetof(s, t) ((ulong)&((s *)0)->t)
-
 static int
 static int
 xfunc(Controller *c, enum na_external x, unsigned long *v)
 xfunc(Controller *c, enum na_external x, unsigned long *v)
 {
 {
@@ -1968,6 +2084,7 @@ sd53c8xxpnp(void)
 	Controller *ctlr;
 	Controller *ctlr;
 	SDev *sdev, *head, *tail;
 	SDev *sdev, *head, *tail;
 	ulong regpa, *script, scriptpa;
 	ulong regpa, *script, scriptpa;
+	void *regva, *scriptva;
 
 
 	if(cp = getconf("*maxsd53c8xx"))
 	if(cp = getconf("*maxsd53c8xx"))
 		nctlr = strtoul(cp, 0, 0);
 		nctlr = strtoul(cp, 0, 0);
@@ -1995,23 +2112,27 @@ sd53c8xxpnp(void)
 				continue;
 				continue;
 			ba++;
 			ba++;
 		}
 		}
-		regpa = upamalloc(regpa & ~0x0F, p->mem[1].size, 0);
 		if(regpa == 0)
 		if(regpa == 0)
+			print("regpa 0\n");
+		regpa &= ~0xF;
+		regva = vmap(regpa, p->mem[1].size);
+		if(regva == 0)
 			continue;
 			continue;
 
 
 		script = nil;
 		script = nil;
 		scriptpa = 0;
 		scriptpa = 0;
+		scriptva = nil;
 		scriptma = nil;
 		scriptma = nil;
 		if((v->feature & LocalRAM) && sizeof(na_script) <= 4096){
 		if((v->feature & LocalRAM) && sizeof(na_script) <= 4096){
 			scriptpa = p->mem[ba].bar;
 			scriptpa = p->mem[ba].bar;
 			if((scriptpa & 0x04) && p->mem[ba+1].bar){
 			if((scriptpa & 0x04) && p->mem[ba+1].bar){
-				upafree(regpa, p->mem[1].size);
+				vunmap(regva, p->mem[1].size);
 				continue;
 				continue;
 			}
 			}
-			scriptpa = upamalloc(scriptpa & ~0x0F,
-					p->mem[ba].size, 0);
-			if(scriptpa)
-				script = KADDR(scriptpa);
+			scriptpa &= ~0x0F;
+			scriptva = vmap(scriptpa, p->mem[ba].size);
+			if(scriptva)
+				script = scriptva;
 		}
 		}
 		if(scriptpa == 0){
 		if(scriptpa == 0){
 			/*
 			/*
@@ -2020,7 +2141,7 @@ sd53c8xxpnp(void)
 			 */
 			 */
 			scriptma = malloc(sizeof(na_script));
 			scriptma = malloc(sizeof(na_script));
 			if(scriptma == nil){
 			if(scriptma == nil){
-				upafree(regpa, p->mem[1].size);
+				vunmap(regva, p->mem[1].size);
 				continue;
 				continue;
 			}
 			}
 			scriptpa = DMASEG(scriptma);
 			scriptpa = DMASEG(scriptma);
@@ -2037,13 +2158,23 @@ buggery:
 				free(sdev);
 				free(sdev);
 			if(scriptma)
 			if(scriptma)
 				free(scriptma);
 				free(scriptma);
-			else
-				upafree(scriptpa, p->mem[ba].size);
-			upafree(regpa, p->mem[1].size);
+			else if(scriptva)
+				vunmap(scriptva, p->mem[ba].size);
+			if(regva)
+				vunmap(regva, p->mem[1].size);
 			continue;
 			continue;
 		}
 		}
 
 
-		ctlr->n = KADDR(regpa);
+		if(dsaend == nil)
+			dsaend = xalloc(sizeof *dsaend);
+		lesetl(&dsaend->stateb, A_STATE_END);
+	//	lesetl(dsaend->next, DMASEG(dsaend));
+		coherence();
+		lesetl(ctlr->dsalist.head, DMASEG(dsaend));
+		coherence();
+		ctlr->dsalist.freechain = 0;
+
+		ctlr->n = regva;
 		ctlr->v = v;
 		ctlr->v = v;
 		ctlr->script = script;
 		ctlr->script = script;
 		memmove(ctlr->script, na_script, sizeof(na_script));
 		memmove(ctlr->script, na_script, sizeof(na_script));
@@ -2062,19 +2193,17 @@ buggery:
 		}
 		}
 		swabl(ctlr->script, ctlr->script, sizeof(na_script));
 		swabl(ctlr->script, ctlr->script, sizeof(na_script));
 
 
-		ctlr->dsalist.freechain = 0;
-		lesetl(ctlr->dsalist.head, 0);
-
 		ctlr->pcidev = p;
 		ctlr->pcidev = p;
 
 
 		sdev->ifc = &sd53c8xxifc;
 		sdev->ifc = &sd53c8xxifc;
 		sdev->ctlr = ctlr;
 		sdev->ctlr = ctlr;
+		sdev->idno = '0';
 		if(!(v->feature & Wide))
 		if(!(v->feature & Wide))
 			sdev->nunit = 8;
 			sdev->nunit = 8;
 		else
 		else
 			sdev->nunit = MAXTARGET;
 			sdev->nunit = MAXTARGET;
 		ctlr->sdev = sdev;
 		ctlr->sdev = sdev;
-
+		
 		if(head != nil)
 		if(head != nil)
 			tail->next = sdev;
 			tail->next = sdev;
 		else
 		else
@@ -2087,12 +2216,6 @@ buggery:
 	return head;
 	return head;
 }
 }
 
 
-static SDev*
-sd53c8xxid(SDev* sdev)
-{
-	return scsiid(sdev, &sd53c8xxifc);
-}
-
 static int
 static int
 sd53c8xxenable(SDev* sdev)
 sd53c8xxenable(SDev* sdev)
 {
 {
@@ -2104,13 +2227,13 @@ sd53c8xxenable(SDev* sdev)
 	pcidev = ctlr->pcidev;
 	pcidev = ctlr->pcidev;
 
 
 	pcisetbme(pcidev);
 	pcisetbme(pcidev);
-	snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name);
-	intrenable(pcidev->intl, sd53c8xxinterrupt, ctlr, pcidev->tbdf, name);
 
 
 	ilock(ctlr);
 	ilock(ctlr);
 	synctabinit(ctlr);
 	synctabinit(ctlr);
 	cribbios(ctlr);
 	cribbios(ctlr);
 	reset(ctlr);
 	reset(ctlr);
+	snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name);
+	intrenable(pcidev->intl, sd53c8xxinterrupt, ctlr, pcidev->tbdf, name);
 	iunlock(ctlr);
 	iunlock(ctlr);
 
 
 	return 1;
 	return 1;
@@ -2121,7 +2244,6 @@ SDifc sd53c8xxifc = {
 
 
 	sd53c8xxpnp,			/* pnp */
 	sd53c8xxpnp,			/* pnp */
 	nil,				/* legacy */
 	nil,				/* legacy */
-	sd53c8xxid,			/* id */
 	sd53c8xxenable,			/* enable */
 	sd53c8xxenable,			/* enable */
 	nil,				/* disable */
 	nil,				/* disable */
 
 

+ 0 - 773
sys/src/9/pc/sd53c8xx.i

@@ -1,773 +0,0 @@
-unsigned long na_script[] = {
-			/*	extern	scsi_id_buf */
-			/*	extern	msg_out_buf */
-			/*	extern	cmd_buf */
-			/*	extern	data_buf */
-			/*	extern	status_buf */
-			/*	extern	msgin_buf */
-			/*	extern	dsa_0 */
-			/*	extern  dsa_1 */
-			/*	extern	dsa_head */
-			/*	extern	ssid_mask */
-			/*	SIR_MSG_IO_COMPLETE = 0 */
-			/*	error_not_cmd_complete = 1 */
-			/*	error_disconnected = 2 */
-			/*	error_reselected = 3 */
-			/*	error_unexpected_phase = 4 */
-			/*	error_weird_message = 5 */
-			/*	SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT = 6 */
-			/*	error_not_identify_after_reselect = 7 */
-			/*	error_too_much_data = 8 */
-			/*	error_too_little_data = 9 */
-			/*	SIR_MSG_REJECT = 10 */
-			/*	SIR_MSG_SDTR = 11 */
-			/*	SIR_EV_RESPONSE_OK = 12 */
-			/*	error_sigp_set = 13 */
-			/*	SIR_EV_PHASE_SWITCH_AFTER_ID = 14 */
-			/*	SIR_MSG_WDTR = 15 */
-			/*	SIR_MSG_IGNORE_WIDE_RESIDUE = 16 */
-			/*	SIR_NOTIFY_DISC = 100 */
-			/*	SIR_NOTIFY_RESELECT = 101 */
-			/*	SIR_NOTIFY_MSG_IN = 102 */
-			/*	SIR_NOTIFY_STATUS = 103 */
-			/*	SIR_NOTIFY_DUMP = 104 */
-			/*	SIR_NOTIFY_DUMP2 = 105 */
-			/*	SIR_NOTIFY_SIGP = 106 */
-			/*	SIR_NOTIFY_ISSUE = 107 */
-			/*	SIR_NOTIFY_WAIT_RESELECT = 108 */
-			/*	SIR_NOTIFY_ISSUE_CHECK = 109 */
-			/*	SIR_NOTIFY_DUMP_NEXT_CODE = 110 */
-			/*	SIR_NOTIFY_COMMAND = 111 */
-			/*	SIR_NOTIFY_DATA_IN = 112 */
-			/*	SIR_NOTIFY_DATA_OUT = 113 */
-			/*	SIR_NOTIFY_BLOCK_DATA_IN = 114 */
-			/*	SIR_NOTIFY_WSR = 115 */
-			/*	SIR_NOTIFY_LOAD_SYNC = 116 */
-			/*	SIR_NOTIFY_RESELECTED_ON_SELECT = 117 */
-			/*	STATE_FREE = 0 */
-			/*	STATE_ALLOCATED = 1 */
-			/*	STATE_ISSUE = 2 */
-			/*	STATE_DISCONNECTED = 3 */
-			/*	STATE_DONE = 4 */
-			/*	RESULT_OK = 0 */
-			/*	MSG_IDENTIFY = 0x80 */
-			/*	MSG_DISCONNECT = 0x04 */
-			/*	MSG_SAVE_DATA_POINTER = 0x02 */
-			/*	MSG_RESTORE_POINTERS = 0x03 */
-			/*	MSG_IGNORE_WIDE_RESIDUE = 0x23 */
-			/*	X_MSG = 0x01 */
-			/*	X_MSG_SDTR = 0x01 */
-			/*	X_MSG_WDTR = 0x03 */
-			/*	MSG_REJECT = 0x07 */
-			/*	BSIZE = 512 */
-/* 0000 */ 0x80880000L, /*		jump	wait_for_reselection */
-/* 0004 */ 0x00000514L,
-/* 0008 */ 0x88880000L, /*		call	load_sync */
-/* 000c */ 0x0000074cL,
-/* 0010 */ 0x60000200L, /*		clear	target */
-/* 0014 */ 0x00000000L,
-/* 0018 */ 0x47000000L, /*		select	atn from scsi_id_buf, reselected_on_select */
-/* 001c */ 0x000004ecL,
-/* 0020 */ 0x878b0000L, /*		jump	start1, when msg_in */
-/* 0024 */ 0x00000000L,
-/* 0028 */ 0x1e000000L, /*		move	from msg_out_buf, when msg_out */
-/* 002c */ 0x00000001L,
-/* 0030 */ 0x868b0000L, /*		jump	start1, when msg_out */
-/* 0034 */ 0x00fffff0L,
-/* 0038 */ 0x82830000L, /*		jump	to_decisions, when not cmd */
-/* 003c */ 0x000005f0L,
-/* 0040 */ 0x60000008L, /*		clear	atn */
-/* 0044 */ 0x00000000L,
-/* 0048 */ 0x1a000000L, /*		move	from cmd_buf, when cmd */
-/* 004c */ 0x00000002L,
-/* 0050 */ 0x81830000L, /*		jump	to_decisions, when not data_in */
-/* 0054 */ 0x000005d8L,
-/* 0058 */ 0xc0000004L, /*		move	memory 4, state, scratcha */
-/* 005c */ 0x00000678L,
-/* 0060 */ 0x00000034L,
-/* 0064 */ 0xc0000004L, /*		move	memory 4, dmaaddr, scratchb */
-/* 0068 */ 0x0000067cL,
-/* 006c */ 0x0000005cL,
-/* 0070 */ 0x72360000L, /*		move	scratcha2 to sfbr */
-/* 0074 */ 0x00000000L,
-/* 0078 */ 0x808c0000L, /*		jump	data_in_normal, if 0 */
-/* 007c */ 0x00000078L,
-/* 0080 */ 0x29000200L, /*		move	BSIZE, ptr dmaaddr, when data_in */
-/* 0084 */ 0x0000067cL,
-/* 0088 */ 0x7e5d0200L, /*		move	scratchb1 + BSIZE / 256 to scratchb1 */
-/* 008c */ 0x00000000L,
-/* 0090 */ 0x7f5e0000L, /*		move	scratchb2 + 0 to scratchb2 with carry */
-/* 0094 */ 0x00000000L,
-/* 0098 */ 0x7f5f0000L, /*		move	scratchb3 + 0 to scratchb3 with carry */
-/* 009c */ 0x00000000L,
-/* 00a0 */ 0x7e36ff00L, /*		move	scratcha2 + 255 to scratcha2 */
-/* 00a4 */ 0x00000000L,
-/* 00a8 */ 0xc0000004L, /*		move	memory 4, scratchb, dmaaddr */
-/* 00ac */ 0x0000005cL,
-/* 00b0 */ 0x0000067cL,
-/* 00b4 */ 0x818b0000L, /*		jump	data_in_block_loop, when data_in */
-/* 00b8 */ 0x00ffffb4L,
-/* 00bc */ 0xc0000004L, /*		move	memory 4, scratcha, state */
-/* 00c0 */ 0x00000034L,
-/* 00c4 */ 0x00000678L,
-/* 00c8 */ 0x88880000L, /*		call	save_state */
-/* 00cc */ 0x000005e0L,
-/* 00d0 */ 0x80880000L, /*		jump	to_decisions */
-/* 00d4 */ 0x00000558L,
-/* 00d8 */ 0xc0000004L, /*		move	memory 4, scratchb, dmaaddr */
-/* 00dc */ 0x0000005cL,
-/* 00e0 */ 0x0000067cL,
-/* 00e4 */ 0xc0000004L, /*		move	memory 4, scratcha, state */
-/* 00e8 */ 0x00000034L,
-/* 00ec */ 0x00000678L,
-/* 00f0 */ 0x80880000L, /*		jump	to_decisions */
-/* 00f4 */ 0x00000538L,
-/* 00f8 */ 0x72370000L, /*		move	scratcha3 to sfbr */
-/* 00fc */ 0x00000000L,
-/* 0100 */ 0x98040000L, /*		int	error_too_much_data, if not 0 */
-/* 0104 */ 0x00000008L,
-/* 0108 */ 0x19000000L, /*		move	from data_buf, when data_in */
-/* 010c */ 0x00000003L,
-/* 0110 */ 0x78370200L, /*		move	2 to scratcha3 */
-/* 0114 */ 0x00000000L,
-/* 0118 */ 0xc0000004L, /*		move	memory 4, scratcha, state */
-/* 011c */ 0x00000034L,
-/* 0120 */ 0x00000678L,
-/* 0124 */ 0x88880000L, /*		call	save_state */
-/* 0128 */ 0x00000584L,
-/* 012c */ 0x80880000L, /*		jump	post_data_to_decisions */
-/* 0130 */ 0x0000052cL,
-/* 0134 */ 0xc0000004L, /*		move	memory 4, state, scratcha */
-/* 0138 */ 0x00000678L,
-/* 013c */ 0x00000034L,
-/* 0140 */ 0xc0000004L, /*		move	memory 4, dmaaddr, scratchb */
-/* 0144 */ 0x0000067cL,
-/* 0148 */ 0x0000005cL,
-/* 014c */ 0x72360000L, /*		move	scratcha2 to sfbr */
-/* 0150 */ 0x00000000L,
-/* 0154 */ 0x808c0000L, /*		jump	data_out_normal, if 0 */
-/* 0158 */ 0x0000005cL,
-/* 015c */ 0xc0000004L, /*		move	memory 4, dmaaddr, scratchb */
-/* 0160 */ 0x0000067cL,
-/* 0164 */ 0x0000005cL,
-/* 0168 */ 0x28000200L, /*		move	BSIZE, ptr dmaaddr, when data_out */
-/* 016c */ 0x0000067cL,
-/* 0170 */ 0x7e5d0200L, /*		move	scratchb1 + BSIZE / 256 to scratchb1 */
-/* 0174 */ 0x00000000L,
-/* 0178 */ 0x7f5e0000L, /*		move	scratchb2 + 0 to scratchb2 with carry */
-/* 017c */ 0x00000000L,
-/* 0180 */ 0x7f5f0000L, /*		move	scratchb3 + 0 to scratchb3 with carry */
-/* 0184 */ 0x00000000L,
-/* 0188 */ 0x7e36ff00L, /*		move	scratcha2 + 255 to scratcha2 */
-/* 018c */ 0x00000000L,
-/* 0190 */ 0xc0000004L, /*		move	memory 4, scratchb, dmaaddr */
-/* 0194 */ 0x0000005cL,
-/* 0198 */ 0x0000067cL,
-/* 019c */ 0x808b0000L, /*		jump	data_out_block_loop, when data_out */
-/* 01a0 */ 0x00ffffa8L,
-/* 01a4 */ 0xc0000004L, /*		move	memory 4, scratcha, state */
-/* 01a8 */ 0x00000034L,
-/* 01ac */ 0x00000678L,
-/* 01b0 */ 0x80880000L, /*		jump	to_decisions */
-/* 01b4 */ 0x00000478L,
-/* 01b8 */ 0x72370000L, /*		move	scratcha3 to sfbr */
-/* 01bc */ 0x00000000L,
-/* 01c0 */ 0x98040000L, /*		int	error_too_little_data, if not 0 */
-/* 01c4 */ 0x00000009L,
-/* 01c8 */ 0x18000000L, /*		move	from data_buf, when data_out */
-/* 01cc */ 0x00000003L,
-/* 01d0 */ 0x78370200L, /*		move	2 to scratcha3 */
-/* 01d4 */ 0x00000000L,
-/* 01d8 */ 0xc0000004L, /*		move	memory 4, scratcha, state */
-/* 01dc */ 0x00000034L,
-/* 01e0 */ 0x00000678L,
-/* 01e4 */ 0x88880000L, /*		call	save_state */
-/* 01e8 */ 0x000004c4L,
-/* 01ec */ 0x80880000L, /*		jump	post_data_to_decisions */
-/* 01f0 */ 0x0000046cL,
-/* 01f4 */ 0x1b000000L, /*		move	from status_buf, when status */
-/* 01f8 */ 0x00000004L,
-/* 01fc */ 0x9f030000L, /*		int	error_unexpected_phase, when not msg_in */
-/* 0200 */ 0x00000004L,
-/* 0204 */ 0x0f000001L, /*		move	1, scratcha, when msg_in */
-/* 0208 */ 0x00000034L,
-/* 020c */ 0x808c0007L, /*		jump	rejected, if MSG_REJECT */
-/* 0210 */ 0x00000088L,
-/* 0214 */ 0x808c0004L, /*		jump	disconnected, if MSG_DISCONNECT */
-/* 0218 */ 0x00000298L,
-/* 021c */ 0x808c0002L, /*		jump	msg_in_skip, if MSG_SAVE_DATA_POINTER */
-/* 0220 */ 0x00000090L,
-/* 0224 */ 0x808c0003L, /*		jump	msg_in_skip, if MSG_RESTORE_POINTERS */
-/* 0228 */ 0x00000088L,
-/* 022c */ 0x808c0023L, /*		jump	ignore_wide, if MSG_IGNORE_WIDE_RESIDUE */
-/* 0230 */ 0x000001f0L,
-/* 0234 */ 0x808c0001L, /*		jump	extended, if X_MSG */
-/* 0238 */ 0x00000088L,
-/* 023c */ 0x98040000L, /*		int	error_not_cmd_complete, if not 0 */
-/* 0240 */ 0x00000001L,
-/* 0244 */ 0x7c027e00L, /*		move	scntl2&0x7e to scntl2 */
-/* 0248 */ 0x00000000L,
-/* 024c */ 0x60000040L, /*		clear	ack */
-/* 0250 */ 0x00000000L,
-/* 0254 */ 0x48000000L, /*		wait	disconnect */
-/* 0258 */ 0x00000000L,
-/* 025c */ 0xc0000004L, /*		move	memory 4, state, scratcha */
-/* 0260 */ 0x00000678L,
-/* 0264 */ 0x00000034L,
-/* 0268 */ 0x78340400L, /*		move	STATE_DONE to scratcha0 */
-/* 026c */ 0x00000000L,
-/* 0270 */ 0x78350000L, /*		move	RESULT_OK to scratcha1 */
-/* 0274 */ 0x00000000L,
-/* 0278 */ 0xc0000004L, /*		move	memory 4, scratcha, state */
-/* 027c */ 0x00000034L,
-/* 0280 */ 0x00000678L,
-/* 0284 */ 0x88880000L, /*		call	save_state */
-/* 0288 */ 0x00000424L,
-/* 028c */ 0x98180000L, /*		intfly	0 */
-/* 0290 */ 0x00000000L,
-/* 0294 */ 0x80880000L, /*		jump	issue_check */
-/* 0298 */ 0x0000043cL,
-/* 029c */ 0x98080000L, /*		int	SIR_MSG_REJECT */
-/* 02a0 */ 0x0000000aL,
-/* 02a4 */ 0x60000040L, /*		clear	ack */
-/* 02a8 */ 0x00000000L,
-/* 02ac */ 0x80880000L, /*		jump	to_decisions */
-/* 02b0 */ 0x0000037cL,
-/* 02b4 */ 0x60000040L, /*		clear	ack */
-/* 02b8 */ 0x00000000L,
-/* 02bc */ 0x80880000L, /*		jump	to_decisions */
-/* 02c0 */ 0x0000036cL,
-/* 02c4 */ 0x60000040L, /*		clear	ack */
-/* 02c8 */ 0x00000000L,
-/* 02cc */ 0x9f030000L, /*		int	error_unexpected_phase, when not msg_in */
-/* 02d0 */ 0x00000004L,
-/* 02d4 */ 0x0f000001L, /*		move	1, scratcha1, when msg_in */
-/* 02d8 */ 0x00000035L,
-/* 02dc */ 0x808c0003L, /*		jump	ext_3, if 3 */
-/* 02e0 */ 0x00000030L,
-/* 02e4 */ 0x808c0002L, /*		jump	ext_2, if 2 */
-/* 02e8 */ 0x00000098L,
-/* 02ec */ 0x98040001L, /*		int	error_weird_message, if not 1 */
-/* 02f0 */ 0x00000005L,
-/* 02f4 */ 0x60000040L, /*		clear	ack */
-/* 02f8 */ 0x00000000L,
-/* 02fc */ 0x9f030000L, /*		int	error_unexpected_phase, when not msg_in */
-/* 0300 */ 0x00000004L,
-/* 0304 */ 0x0f000001L, /*		move	1, scratcha1, when msg_in */
-/* 0308 */ 0x00000035L,
-/* 030c */ 0x80880000L, /*		jump	ext_done */
-/* 0310 */ 0x000000c8L,
-/* 0314 */ 0x60000040L, /*	ext_3:	clear	ack */
-/* 0318 */ 0x00000000L,
-/* 031c */ 0x9f030000L, /*		int	error_unexpected_phase, when not msg_in */
-/* 0320 */ 0x00000004L,
-/* 0324 */ 0x0f000001L, /*		move	1, scratcha1, when msg_in */
-/* 0328 */ 0x00000035L,
-/* 032c */ 0x60000040L, /*		clear	ack */
-/* 0330 */ 0x00000000L,
-/* 0334 */ 0x9f030000L, /*		int	error_unexpected_phase, when not msg_in */
-/* 0338 */ 0x00000004L,
-/* 033c */ 0x0f000001L, /*		move	1, scratcha2, when msg_in */
-/* 0340 */ 0x00000036L,
-/* 0344 */ 0x60000040L, /*		clear	ack */
-/* 0348 */ 0x00000000L,
-/* 034c */ 0x9f030000L, /*		int	error_unexpected_phase, when not msg_in */
-/* 0350 */ 0x00000004L,
-/* 0354 */ 0x0f000001L, /*		move	1, scratcha3, when msg_in */
-/* 0358 */ 0x00000037L,
-/* 035c */ 0x72350000L, /*		move	scratcha1 to sfbr */
-/* 0360 */ 0x00000000L,
-/* 0364 */ 0x80840001L, /*		jump	ext_done, if not X_MSG_SDTR */
-/* 0368 */ 0x00000070L,
-/* 036c */ 0x98080000L, /*	sdtr:	int	SIR_MSG_SDTR */
-/* 0370 */ 0x0000000bL,
-/* 0374 */ 0x60000040L, /*		clear	ack */
-/* 0378 */ 0x00000000L,
-/* 037c */ 0x80880000L, /*		jump	to_decisions */
-/* 0380 */ 0x000002acL,
-/* 0384 */ 0x60000040L, /*	ext_2:	clear	ack */
-/* 0388 */ 0x00000000L,
-/* 038c */ 0x9f030000L, /*		int	error_unexpected_phase, when not msg_in */
-/* 0390 */ 0x00000004L,
-/* 0394 */ 0x0f000001L, /*		move	1, scratcha1, when msg_in */
-/* 0398 */ 0x00000035L,
-/* 039c */ 0x60000040L, /*		clear	ack */
-/* 03a0 */ 0x00000000L,
-/* 03a4 */ 0x9f030000L, /*		int	error_unexpected_phase, when not msg_in */
-/* 03a8 */ 0x00000004L,
-/* 03ac */ 0x0f000001L, /*		move	1, scratcha2, when msg_in */
-/* 03b0 */ 0x00000036L,
-/* 03b4 */ 0x72350000L, /*		move	scratcha1 to sfbr */
-/* 03b8 */ 0x00000000L,
-/* 03bc */ 0x80840003L, /*		jump	ext_done, if not X_MSG_WDTR */
-/* 03c0 */ 0x00000018L,
-/* 03c4 */ 0x98080000L, /*	wdtr:	int	SIR_MSG_WDTR */
-/* 03c8 */ 0x0000000fL,
-/* 03cc */ 0x60000040L, /*		clear	ack */
-/* 03d0 */ 0x00000000L,
-/* 03d4 */ 0x80880000L, /*		jump	to_decisions */
-/* 03d8 */ 0x00000254L,
-/* 03dc */ 0x58000008L, /*		set	atn */
-/* 03e0 */ 0x00000000L,
-/* 03e4 */ 0x60000040L, /*		clear	ack */
-/* 03e8 */ 0x00000000L,
-/* 03ec */ 0x78340700L, /*		move	MSG_REJECT to scratcha */
-/* 03f0 */ 0x00000000L,
-/* 03f4 */ 0x9e030000L, /*		int	error_unexpected_phase, when not msg_out */
-/* 03f8 */ 0x00000004L,
-/* 03fc */ 0x60000008L, /*		clear	atn */
-/* 0400 */ 0x00000000L,
-/* 0404 */ 0x0e000001L, /*		move	1, scratcha, when msg_out */
-/* 0408 */ 0x00000034L,
-/* 040c */ 0x60000040L, /*		clear	ack */
-/* 0410 */ 0x00000000L,
-/* 0414 */ 0x868b0000L, /*		jump	reject, when msg_out */
-/* 0418 */ 0x00ffffc0L,
-/* 041c */ 0x80880000L, /*		jump	to_decisions */
-/* 0420 */ 0x0000020cL,
-/* 0424 */ 0x60000040L, /*		clear	ack */
-/* 0428 */ 0x00000000L,
-/* 042c */ 0x9f030000L, /*		int	error_unexpected_phase, when not msg_in */
-/* 0430 */ 0x00000004L,
-/* 0434 */ 0x0f000001L, /*		move	1, scratcha1, when msg_in */
-/* 0438 */ 0x00000035L,
-/* 043c */ 0x98080000L, /*		int	SIR_MSG_IGNORE_WIDE_RESIDUE */
-/* 0440 */ 0x00000010L,
-/* 0444 */ 0x60000040L, /*		clear	ack */
-/* 0448 */ 0x00000000L,
-/* 044c */ 0x80880000L, /*		jump	to_decisions */
-/* 0450 */ 0x000001dcL,
-/* 0454 */ 0x58000008L, /*		set	atn */
-/* 0458 */ 0x00000000L,
-/* 045c */ 0x60000040L, /*		clear	ack */
-/* 0460 */ 0x00000000L,
-/* 0464 */ 0x9e030000L, /*		int	error_unexpected_phase, when not msg_out */
-/* 0468 */ 0x00000004L,
-/* 046c */ 0x1e000000L, /*		move	from msg_out_buf, when msg_out */
-/* 0470 */ 0x00000001L,
-/* 0474 */ 0x868b0000L, /*		jump	response_repeat, when msg_out */
-/* 0478 */ 0x00fffff0L,
-/* 047c */ 0x878b0000L, /*		jump	response_msg_in, when msg_in */
-/* 0480 */ 0x00000010L,
-/* 0484 */ 0x98080000L, /*		int	SIR_EV_RESPONSE_OK */
-/* 0488 */ 0x0000000cL,
-/* 048c */ 0x80880000L, /*		jump	to_decisions */
-/* 0490 */ 0x0000019cL,
-/* 0494 */ 0x0f000001L, /*		move	1, scratcha, when msg_in */
-/* 0498 */ 0x00000034L,
-/* 049c */ 0x808c0007L, /*		jump	rejected, if MSG_REJECT */
-/* 04a0 */ 0x00fffdf8L,
-/* 04a4 */ 0x98080000L, /*		int	SIR_EV_RESPONSE_OK */
-/* 04a8 */ 0x0000000cL,
-/* 04ac */ 0x80880000L, /*		jump	msg_in_not_reject */
-/* 04b0 */ 0x00fffd60L,
-/* 04b4 */ 0x7c027e00L, /*		move	scntl2&0x7e to scntl2 */
-/* 04b8 */ 0x00000000L,
-/* 04bc */ 0x60000040L, /*		clear 	ack */
-/* 04c0 */ 0x00000000L,
-/* 04c4 */ 0x48000000L, /*		wait	disconnect */
-/* 04c8 */ 0x00000000L,
-/* 04cc */ 0xc0000004L, /*		move	memory 4, state, scratcha */
-/* 04d0 */ 0x00000678L,
-/* 04d4 */ 0x00000034L,
-/* 04d8 */ 0x78340300L, /*		move	STATE_DISCONNECTED to scratcha0 */
-/* 04dc */ 0x00000000L,
-/* 04e0 */ 0xc0000004L, /*		move	memory 4, scratcha, state */
-/* 04e4 */ 0x00000034L,
-/* 04e8 */ 0x00000678L,
-/* 04ec */ 0x88880000L, /*		call	save_state */
-/* 04f0 */ 0x000001bcL,
-/* 04f4 */ 0x74020100L, /*		move	scntl2&0x01 to sfbr */
-/* 04f8 */ 0x00000000L,
-/* 04fc */ 0x98040000L, /*		int	SIR_NOTIFY_WSR, if not 0 */
-/* 0500 */ 0x00000073L,
-/* 0504 */ 0x80880000L, /*		jump	issue_check */
-/* 0508 */ 0x000001ccL,
-/* 050c */ 0x98080000L, /*		int	SIR_NOTIFY_RESELECTED_ON_SELECT */
-/* 0510 */ 0x00000075L,
-/* 0514 */ 0x80880000L, /*		jump	reselected */
-/* 0518 */ 0x00000008L,
-/* 051c */ 0x54000000L, /*		wait reselect sigp_set */
-/* 0520 */ 0x000001acL,
-/* 0524 */ 0x60000200L, /*		clear	target */
-/* 0528 */ 0x00000000L,
-/* 052c */ 0x9f030000L, /*		int	SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT, when not msg_in */
-/* 0530 */ 0x00000006L,
-/* 0534 */ 0x0f000001L, /*		move	1, scratchb, when msg_in */
-/* 0538 */ 0x0000005cL,
-/* 053c */ 0x98041f80L, /*		int	error_not_identify_after_reselect, if not MSG_IDENTIFY and mask 0x1f */
-/* 0540 */ 0x00000007L,
-/* 0544 */ 0xc0000004L, /*	 	move	memory 4, dsa_head, dsa */
-/* 0548 */ 0x00000008L,
-/* 054c */ 0x00000010L,
-/* 0550 */ 0x72100000L, /*		move	dsa0 to sfbr */
-/* 0554 */ 0x00000000L,
-/* 0558 */ 0x80840000L, /*		jump	find_dsa_1, if not 0 */
-/* 055c */ 0x00000030L,
-/* 0560 */ 0x72110000L, /*		move	dsa1 to sfbr */
-/* 0564 */ 0x00000000L,
-/* 0568 */ 0x80840000L, /*		jump	find_dsa_1, if not 0 */
-/* 056c */ 0x00000020L,
-/* 0570 */ 0x72120000L, /*		move	dsa2 to sfbr */
-/* 0574 */ 0x00000000L,
-/* 0578 */ 0x80840000L, /*		jump	find_dsa_1, if not 0 */
-/* 057c */ 0x00000010L,
-/* 0580 */ 0x72130000L, /*		move	dsa3 to sfbr */
-/* 0584 */ 0x00000000L,
-/* 0588 */ 0x980c0000L, /*		int	error_reselected, if 0 */
-/* 058c */ 0x00000003L,
-/* 0590 */ 0x88880000L, /*		call	load_state */
-/* 0594 */ 0x000000f8L,
-/* 0598 */ 0xc0000004L, /*		move	memory 4, state, scratcha */
-/* 059c */ 0x00000678L,
-/* 05a0 */ 0x00000034L,
-/* 05a4 */ 0x72340000L, /*		move	scratcha0 to sfbr */
-/* 05a8 */ 0x00000000L,
-/* 05ac */ 0x80840003L, /*		jump	find_dsa_next, if not STATE_DISCONNECTED */
-/* 05b0 */ 0x00000038L,
-/* 05b4 */ 0x740a0900L, /*		move	ssid & ssid_mask to sfbr */
-/* 05b8 */ 0x00000000L,
-/* 05bc */ 0xc0000001L, /*		move	memory 1, targ, find_dsa_smc1 */
-/* 05c0 */ 0x00000680L,
-/* 05c4 */ 0x000005c8L,
-/* 05c8 */ 0x808400ffL, /*		jump	find_dsa_next, if not 255 */
-/* 05cc */ 0x0000001cL,
-/* 05d0 */ 0xc0000001L, /*		move	memory 1, lun, find_dsa_smc2 */
-/* 05d4 */ 0x00000684L,
-/* 05d8 */ 0x000005e4L,
-/* 05dc */ 0x725c0000L, /*		move	scratchb0 to sfbr */
-/* 05e0 */ 0x00000000L,
-/* 05e4 */ 0x808cf8ffL, /*		jump	reload_sync, if 255 and mask ~7 */
-/* 05e8 */ 0x00000034L,
-/* 05ec */ 0xc0000004L, /*		move	memory 4, next, dsa */
-/* 05f0 */ 0x0000068cL,
-/* 05f4 */ 0x00000010L,
-/* 05f8 */ 0x80880000L, /*		jump	find_dsa_loop */
-/* 05fc */ 0x00ffff50L,
-/* 0600 */ 0x60000008L, /*		clear	atn */
-/* 0604 */ 0x00000000L,
-/* 0608 */ 0x878b0000L, /*	        jump    msg_in_phase, when msg_in */
-/* 060c */ 0x00fffbf4L,
-/* 0610 */ 0x98080000L, /*	        int     SIR_MSG_REJECT */
-/* 0614 */ 0x0000000aL,
-/* 0618 */ 0x80880000L, /*	        jump    to_decisions */
-/* 061c */ 0x00000010L,
-/* 0620 */ 0x88880000L, /*		call	load_sync */
-/* 0624 */ 0x00000134L,
-/* 0628 */ 0x60000040L, /*		clear	ack */
-/* 062c */ 0x00000000L,
-/* 0630 */ 0x818b0000L, /*		jump	data_in_phase, when data_in */
-/* 0634 */ 0x00fffa20L,
-/* 0638 */ 0x828a0000L, /*		jump	cmd_phase, if cmd */
-/* 063c */ 0x00fffa00L,
-/* 0640 */ 0x808a0000L, /*		jump	data_out_phase, if data_out */
-/* 0644 */ 0x00fffaecL,
-/* 0648 */ 0x838a0000L, /*		jump	status_phase, if status */
-/* 064c */ 0x00fffba4L,
-/* 0650 */ 0x878a0000L, /*		jump	msg_in_phase, if msg_in */
-/* 0654 */ 0x00fffbacL,
-/* 0658 */ 0x98080000L, /*		int	error_unexpected_phase */
-/* 065c */ 0x00000004L,
-/* 0660 */ 0x838b0000L, /*		jump	status_phase, when status */
-/* 0664 */ 0x00fffb8cL,
-/* 0668 */ 0x878a0000L, /*		jump	msg_in_phase, if msg_in */
-/* 066c */ 0x00fffb94L,
-/* 0670 */ 0x98080000L, /*		int	error_unexpected_phase */
-/* 0674 */ 0x00000004L,
-/* 0678 */ 0x00000000L, /*	state:	defw	0 */
-/* 067c */ 0x00000000L, /*	dmaaddr: defw	0 */
-/* 0680 */ 0x00000000L, /*	targ:	defw	0 */
-/* 0684 */ 0x00000000L, /*	lun:	defw	0 */
-/* 0688 */ 0x00000000L, /*	sync:	defw	0 */
-/* 068c */ 0x00000000L, /*	next:	defw	0 */
-			/*	dsa_load_len = dsa_load_end - dsa_copy */
-			/*	dsa_save_len = dsa_save_end - dsa_copy */
-/* 0690 */ 0xc0000004L, /*		move	memory 4, dsa, load_state_smc0 + 4 */
-/* 0694 */ 0x00000010L,
-/* 0698 */ 0x000006a0L,
-/* 069c */ 0xc0000018L, /*		move	memory dsa_load_len, 0, dsa_copy */
-/* 06a0 */ 0x00000000L,
-/* 06a4 */ 0x00000678L,
-/* 06a8 */ 0x90080000L, /*		return */
-/* 06ac */ 0x00000000L,
-/* 06b0 */ 0xc0000004L, /*		move	memory 4, dsa, save_state_smc0 + 8 */
-/* 06b4 */ 0x00000010L,
-/* 06b8 */ 0x000006c4L,
-/* 06bc */ 0xc0000008L, /*		move	memory dsa_save_len, dsa_copy, 0 */
-/* 06c0 */ 0x00000678L,
-/* 06c4 */ 0x00000000L,
-/* 06c8 */ 0x90080000L, /*		return */
-/* 06cc */ 0x00000000L,
-/* 06d0 */ 0x721a0000L, /*		move	ctest2 to sfbr */
-/* 06d4 */ 0x00000000L,
-/* 06d8 */ 0xc0000004L, /*		move	memory 4, dsa_head, dsa */
-/* 06dc */ 0x00000008L,
-/* 06e0 */ 0x00000010L,
-/* 06e4 */ 0x72100000L, /*		move	dsa0 to sfbr */
-/* 06e8 */ 0x00000000L,
-/* 06ec */ 0x80840000L, /*		jump	issue_check_1, if not 0 */
-/* 06f0 */ 0x00000030L,
-/* 06f4 */ 0x72110000L, /*		move	dsa1 to sfbr */
-/* 06f8 */ 0x00000000L,
-/* 06fc */ 0x80840000L, /*		jump	issue_check_1, if not 0 */
-/* 0700 */ 0x00000020L,
-/* 0704 */ 0x72120000L, /*		move	dsa2 to sfbr */
-/* 0708 */ 0x00000000L,
-/* 070c */ 0x80840000L, /*		jump	issue_check_1, if not 0 */
-/* 0710 */ 0x00000010L,
-/* 0714 */ 0x72130000L, /*		move	dsa3 to sfbr */
-/* 0718 */ 0x00000000L,
-/* 071c */ 0x808c0000L, /*		jump	wait_for_reselection, if 0 */
-/* 0720 */ 0x00fffdf8L,
-/* 0724 */ 0x88880000L, /*	 	call	load_state */
-/* 0728 */ 0x00ffff64L,
-/* 072c */ 0xc0000004L, /*		move	memory 4, state, scratcha */
-/* 0730 */ 0x00000678L,
-/* 0734 */ 0x00000034L,
-/* 0738 */ 0x72340000L, /*		move	scratcha0 to sfbr */
-/* 073c */ 0x00000000L,
-/* 0740 */ 0x808c0002L, /*		jump	start, if STATE_ISSUE */
-/* 0744 */ 0x00fff8c0L,
-/* 0748 */ 0xc0000004L, /*		move	memory 4, next, dsa */
-/* 074c */ 0x0000068cL,
-/* 0750 */ 0x00000010L,
-/* 0754 */ 0x80880000L, /*		jump	issue_check_loop */
-/* 0758 */ 0x00ffff88L,
-/* 075c */ 0xc0000004L, /*		move	memory 4, sync, scratcha */
-/* 0760 */ 0x00000688L,
-/* 0764 */ 0x00000034L,
-/* 0768 */ 0x72340000L, /*		move	scratcha0 to sfbr */
-/* 076c */ 0x00000000L,
-/* 0770 */ 0x6a030000L, /*		move	sfbr to scntl3 */
-/* 0774 */ 0x00000000L,
-/* 0778 */ 0x72350000L, /*		move	scratcha1 to sfbr */
-/* 077c */ 0x00000000L,
-/* 0780 */ 0x6a050000L, /*		move	sfbr to sxfer */
-/* 0784 */ 0x00000000L,
-/* 0788 */ 0x90080000L, /*		return */
-/* 078c */ 0x00000000L,
-};
-
-#define NA_SCRIPT_SIZE 484
-
-struct na_patch na_patches[] = {
-	{ 0x0006, 5 }, /* 00000018 */
-	{ 0x000b, 4 }, /* 0000002c */
-	{ 0x0013, 4 }, /* 0000004c */
-	{ 0x0017, 1 }, /* 0000005c */
-	{ 0x0018, 2 }, /* 00000060 */
-	{ 0x001a, 1 }, /* 00000068 */
-	{ 0x001b, 2 }, /* 0000006c */
-	{ 0x0021, 1 }, /* 00000084 */
-	{ 0x002b, 2 }, /* 000000ac */
-	{ 0x002c, 1 }, /* 000000b0 */
-	{ 0x0030, 2 }, /* 000000c0 */
-	{ 0x0031, 1 }, /* 000000c4 */
-	{ 0x0037, 2 }, /* 000000dc */
-	{ 0x0038, 1 }, /* 000000e0 */
-	{ 0x003a, 2 }, /* 000000e8 */
-	{ 0x003b, 1 }, /* 000000ec */
-	{ 0x0043, 4 }, /* 0000010c */
-	{ 0x0047, 2 }, /* 0000011c */
-	{ 0x0048, 1 }, /* 00000120 */
-	{ 0x004e, 1 }, /* 00000138 */
-	{ 0x004f, 2 }, /* 0000013c */
-	{ 0x0051, 1 }, /* 00000144 */
-	{ 0x0052, 2 }, /* 00000148 */
-	{ 0x0058, 1 }, /* 00000160 */
-	{ 0x0059, 2 }, /* 00000164 */
-	{ 0x005b, 1 }, /* 0000016c */
-	{ 0x0065, 2 }, /* 00000194 */
-	{ 0x0066, 1 }, /* 00000198 */
-	{ 0x006a, 2 }, /* 000001a8 */
-	{ 0x006b, 1 }, /* 000001ac */
-	{ 0x0073, 4 }, /* 000001cc */
-	{ 0x0077, 2 }, /* 000001dc */
-	{ 0x0078, 1 }, /* 000001e0 */
-	{ 0x007e, 4 }, /* 000001f8 */
-	{ 0x0082, 2 }, /* 00000208 */
-	{ 0x0098, 1 }, /* 00000260 */
-	{ 0x0099, 2 }, /* 00000264 */
-	{ 0x009f, 2 }, /* 0000027c */
-	{ 0x00a0, 1 }, /* 00000280 */
-	{ 0x00b6, 2 }, /* 000002d8 */
-	{ 0x00c2, 2 }, /* 00000308 */
-	{ 0x00ca, 2 }, /* 00000328 */
-	{ 0x00d0, 2 }, /* 00000340 */
-	{ 0x00d6, 2 }, /* 00000358 */
-	{ 0x00e6, 2 }, /* 00000398 */
-	{ 0x00ec, 2 }, /* 000003b0 */
-	{ 0x0102, 2 }, /* 00000408 */
-	{ 0x010e, 2 }, /* 00000438 */
-	{ 0x011c, 4 }, /* 00000470 */
-	{ 0x0126, 2 }, /* 00000498 */
-	{ 0x0134, 1 }, /* 000004d0 */
-	{ 0x0135, 2 }, /* 000004d4 */
-	{ 0x0139, 2 }, /* 000004e4 */
-	{ 0x013a, 1 }, /* 000004e8 */
-	{ 0x014e, 2 }, /* 00000538 */
-	{ 0x0152, 4 }, /* 00000548 */
-	{ 0x0153, 2 }, /* 0000054c */
-	{ 0x0167, 1 }, /* 0000059c */
-	{ 0x0168, 2 }, /* 000005a0 */
-	{ 0x016d, 3 }, /* 000005b4 */
-	{ 0x0170, 1 }, /* 000005c0 */
-	{ 0x0171, 1 }, /* 000005c4 */
-	{ 0x0175, 1 }, /* 000005d4 */
-	{ 0x0176, 1 }, /* 000005d8 */
-	{ 0x017c, 1 }, /* 000005f0 */
-	{ 0x017d, 2 }, /* 000005f4 */
-	{ 0x01a5, 2 }, /* 00000694 */
-	{ 0x01a6, 1 }, /* 00000698 */
-	{ 0x01a9, 1 }, /* 000006a4 */
-	{ 0x01ad, 2 }, /* 000006b4 */
-	{ 0x01ae, 1 }, /* 000006b8 */
-	{ 0x01b0, 1 }, /* 000006c0 */
-	{ 0x01b7, 4 }, /* 000006dc */
-	{ 0x01b8, 2 }, /* 000006e0 */
-	{ 0x01cc, 1 }, /* 00000730 */
-	{ 0x01cd, 2 }, /* 00000734 */
-	{ 0x01d3, 1 }, /* 0000074c */
-	{ 0x01d4, 2 }, /* 00000750 */
-	{ 0x01d8, 1 }, /* 00000760 */
-	{ 0x01d9, 2 }, /* 00000764 */
-};
-#define NA_PATCHES 80
-
-enum na_external {
-	X_scsi_id_buf,
-	X_msg_out_buf,
-	X_cmd_buf,
-	X_data_buf,
-	X_status_buf,
-	X_msgin_buf,
-	X_dsa_0,
-	X_dsa_1,
-	X_dsa_head,
-	X_ssid_mask,
-};
-
-enum {
-	E_issue_check_next = 1864,
-	E_issue_check_1 = 1828,
-	E_issue_check_loop = 1764,
-	E_save_state_smc0 = 1724,
-	E_load_state_smc0 = 1692,
-	E_dsa_load_end = 1680,
-	E_sync = 1672,
-	E_dsa_save_end = 1664,
-	E_dsa_copy = 1656,
-	E_id_out_mismatch_recover = 1536,
-	E_next = 1676,
-	E_reload_sync = 1568,
-	E_find_dsa_smc2 = 1508,
-	E_lun = 1668,
-	E_find_dsa_smc1 = 1480,
-	E_targ = 1664,
-	E_find_dsa_next = 1516,
-	E_load_state = 1680,
-	E_find_dsa_1 = 1424,
-	E_find_dsa_loop = 1360,
-	E_find_dsa = 1348,
-	E_sigp_set = 1744,
-	E_reselected = 1316,
-	E_wsr_check = 1268,
-	E_response_msg_in = 1172,
-	E_response_repeat = 1132,
-	E_response = 1108,
-	E_reject = 988,
-	E_wdtr = 964,
-	E_sdtr = 876,
-	E_ext_done = 988,
-	E_ext_1 = 756,
-	E_ext_2 = 900,
-	E_ext_3 = 788,
-	E_issue_check = 1752,
-	E_extended = 708,
-	E_ignore_wide = 1060,
-	E_msg_in_skip = 692,
-	E_disconnected = 1204,
-	E_msg_in_not_reject = 532,
-	E_rejected = 668,
-	E_msg_in_phase = 516,
-	E_status_phase = 500,
-	E_data_out_mismatch = 464,
-	E_data_out_block_mismatch = 368,
-	E_data_out_normal = 440,
-	E_data_out_block_loop = 332,
-	E_data_out_phase = 308,
-	E_post_data_to_decisions = 1632,
-	E_data_in_mismatch = 272,
-	E_data_mismatch_recover = 228,
-	E_data_block_mismatch_recover = 216,
-	E_save_state = 1712,
-	E_data_in_block_mismatch = 136,
-	E_data_in_normal = 248,
-	E_data_in_block_loop = 112,
-	E_dmaaddr = 1660,
-	E_state = 1656,
-	E_data_in_phase = 88,
-	E_cmd_out_mismatch = 80,
-	E_cmd_phase = 64,
-	E_to_decisions = 1584,
-	E_id_out_mismatch = 48,
-	E_start1 = 40,
-	E_reselected_on_select = 1292,
-	E_load_sync = 1884,
-	E_start = 8,
-	E_wait_for_reselection = 1308,
-	E_idle = 0,
-};
-#define A_dsa_save_len 8
-#define A_dsa_load_len 24
-#define A_BSIZE 512
-#define A_MSG_REJECT 7
-#define A_X_MSG_WDTR 3
-#define A_X_MSG_SDTR 1
-#define A_X_MSG 1
-#define A_MSG_IGNORE_WIDE_RESIDUE 35
-#define A_MSG_RESTORE_POINTERS 3
-#define A_MSG_SAVE_DATA_POINTER 2
-#define A_MSG_DISCONNECT 4
-#define A_MSG_IDENTIFY 128
-#define A_RESULT_OK 0
-#define A_STATE_DONE 4
-#define A_STATE_DISCONNECTED 3
-#define A_STATE_ISSUE 2
-#define A_STATE_ALLOCATED 1
-#define A_STATE_FREE 0
-#define A_SIR_NOTIFY_RESELECTED_ON_SELECT 117
-#define A_SIR_NOTIFY_LOAD_SYNC 116
-#define A_SIR_NOTIFY_WSR 115
-#define A_SIR_NOTIFY_BLOCK_DATA_IN 114
-#define A_SIR_NOTIFY_DATA_OUT 113
-#define A_SIR_NOTIFY_DATA_IN 112
-#define A_SIR_NOTIFY_COMMAND 111
-#define A_SIR_NOTIFY_DUMP_NEXT_CODE 110
-#define A_SIR_NOTIFY_ISSUE_CHECK 109
-#define A_SIR_NOTIFY_WAIT_RESELECT 108
-#define A_SIR_NOTIFY_ISSUE 107
-#define A_SIR_NOTIFY_SIGP 106
-#define A_SIR_NOTIFY_DUMP2 105
-#define A_SIR_NOTIFY_DUMP 104
-#define A_SIR_NOTIFY_STATUS 103
-#define A_SIR_NOTIFY_MSG_IN 102
-#define A_SIR_NOTIFY_RESELECT 101
-#define A_SIR_NOTIFY_DISC 100
-#define A_SIR_MSG_IGNORE_WIDE_RESIDUE 16
-#define A_SIR_MSG_WDTR 15
-#define A_SIR_EV_PHASE_SWITCH_AFTER_ID 14
-#define A_error_sigp_set 13
-#define A_SIR_EV_RESPONSE_OK 12
-#define A_SIR_MSG_SDTR 11
-#define A_SIR_MSG_REJECT 10
-#define A_error_too_little_data 9
-#define A_error_too_much_data 8
-#define A_error_not_identify_after_reselect 7
-#define A_SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT 6
-#define A_error_weird_message 5
-#define A_error_unexpected_phase 4
-#define A_error_reselected 3
-#define A_error_disconnected 2
-#define A_error_not_cmd_complete 1
-#define A_SIR_MSG_IO_COMPLETE 0

+ 36 - 25
sys/src/9/pc/sd53c8xx.n

@@ -54,12 +54,14 @@ SIR_NOTIFY_BLOCK_DATA_IN = 114
 SIR_NOTIFY_WSR = 115
 SIR_NOTIFY_WSR = 115
 SIR_NOTIFY_LOAD_SYNC = 116
 SIR_NOTIFY_LOAD_SYNC = 116
 SIR_NOTIFY_RESELECTED_ON_SELECT = 117
 SIR_NOTIFY_RESELECTED_ON_SELECT = 117
+SIR_NOTIFY_LOAD_STATE = 118
 
 
 STATE_FREE = 0
 STATE_FREE = 0
 STATE_ALLOCATED = 1
 STATE_ALLOCATED = 1
 STATE_ISSUE = 2
 STATE_ISSUE = 2
 STATE_DISCONNECTED = 3
 STATE_DISCONNECTED = 3
 STATE_DONE = 4
 STATE_DONE = 4
+STATE_END = 5
 
 
 RESULT_OK = 0
 RESULT_OK = 0
 	
 	
@@ -76,7 +78,7 @@ MSG_REJECT = 0x07
 BSIZE = 512
 BSIZE = 512
 //BSIZE=4096
 //BSIZE=4096
 
 
-idle:
+ // idle:
 	jump	wait_for_reselection	
 	jump	wait_for_reselection	
 start:
 start:
 	call	load_sync
 	call	load_sync
@@ -84,7 +86,7 @@ start:
 //	int	SIR_NOTIFY_ISSUE
 //	int	SIR_NOTIFY_ISSUE
 	clear	target
 	clear	target
 	select	atn from scsi_id_buf, reselected_on_select // do I need to clear ATN here?
 	select	atn from scsi_id_buf, reselected_on_select // do I need to clear ATN here?
-	jump	start1, when msg_in
+	jump	start1, when msg_in	// why is this here?
 start1:
 start1:
 //	move	14 to ctest0
 //	move	14 to ctest0
 	move	from msg_out_buf, when msg_out
 	move	from msg_out_buf, when msg_out
@@ -320,21 +322,13 @@ find_dsa:
  	move	memory 4, dsa_head, dsa
  	move	memory 4, dsa_head, dsa
 find_dsa_loop:
 find_dsa_loop:
 //	move	7 to ctest0
 //	move	7 to ctest0
-	move	dsa0 to sfbr
-	jump	find_dsa_1, if not 0
-	move	dsa1 to sfbr
-	jump	find_dsa_1, if not 0
-	move	dsa2 to sfbr
-	jump	find_dsa_1, if not 0
-	move	dsa3 to sfbr
-	int	error_reselected, if 0			// couldn't match dsa (panic)
-find_dsa_1:
 //	move	8 to ctest0
 //	move	8 to ctest0
 	// load state from DSA into dsa_copy
 	// load state from DSA into dsa_copy
 	call	load_state
 	call	load_state
 	move	memory 4, state, scratcha		// get dsastate in scratcha
 	move	memory 4, state, scratcha		// get dsastate in scratcha
 	move	scratcha0 to sfbr			// and state variable in sfbr
 	move	scratcha0 to sfbr			// and state variable in sfbr
 	jump	find_dsa_next, if not STATE_DISCONNECTED // wrong state
 	jump	find_dsa_next, if not STATE_DISCONNECTED // wrong state
+	int	error_reselected, if STATE_END
 	move	ssid & ssid_mask to sfbr			// get target ID
 	move	ssid & ssid_mask to sfbr			// get target ID
 	move	memory 1, targ, find_dsa_smc1		// forge target comparison instruction
 	move	memory 1, targ, find_dsa_smc1		// forge target comparison instruction
 find_dsa_smc1:
 find_dsa_smc1:
@@ -350,6 +344,7 @@ find_dsa_next:
 // id_out terminated early
 // id_out terminated early
 // most likely the message wasn't recognised
 // most likely the message wasn't recognised
 // clear ATN and accept the message in
 // clear ATN and accept the message in
+// called from sd53c8xx.c directly
 id_out_mismatch_recover:
 id_out_mismatch_recover:
 	clear	atn
 	clear	atn
         jump    msg_in_phase, when msg_in
         jump    msg_in_phase, when msg_in
@@ -374,6 +369,7 @@ to_decisions:
 	jump	status_phase, if status
 	jump	status_phase, if status
 	jump	msg_in_phase, if msg_in
 	jump	msg_in_phase, if msg_in
 	int	error_unexpected_phase
 	int	error_unexpected_phase
+
 post_data_to_decisions:
 post_data_to_decisions:
 	jump	status_phase, when status
 	jump	status_phase, when status
 	jump	msg_in_phase, if msg_in
 	jump	msg_in_phase, if msg_in
@@ -398,6 +394,30 @@ dsa_load_len = dsa_load_end - dsa_copy
 dsa_save_len = dsa_save_end - dsa_copy
 dsa_save_len = dsa_save_end - dsa_copy
 
 
 load_state:
 load_state:
+//	int	SIR_NOTIFY_LOAD_STATE
+	jump load_state_okay
+
+	move	dsa0 to sfbr
+	jump load_state_okay, if not 0
+	move	dsa1 to sfbr
+	jump load_state_okay, if not 0
+	move	dsa2 to sfbr
+	jump load_state_okay, if not 0
+	move	dsa3 to sfbr
+	jump load_state_okay, if not 0
+	// dsa is 0
+	move	memory 4, dsa, dmaaddr
+	move	memory 4, dsa, targ
+	move	memory 4, dsa, lun
+	move	memory 4, dsa, sync
+	move	memory 4, dsa, next
+	move	memory 4, dsa, scratcha
+	move	STATE_END to sfbr
+	move	sfbr to scratcha0
+	move	memory 4, scratcha, state
+	return
+
+load_state_okay:
 	// load state from DSA into dsa_copy
 	// load state from DSA into dsa_copy
 //	move	9 to ctest0
 //	move	9 to ctest0
 	move	memory 4, dsa, load_state_smc0 + 4
 	move	memory 4, dsa, load_state_smc0 + 4
@@ -419,30 +439,21 @@ issue_check:
 //	move	1 to ctest0
 //	move	1 to ctest0
 	move	memory 4, dsa_head, dsa
 	move	memory 4, dsa_head, dsa
 issue_check_loop:
 issue_check_loop:
-//	move	2 to ctest0
-	move	dsa0 to sfbr
-	jump	issue_check_1, if not 0
-	move	dsa1 to sfbr
-	jump	issue_check_1, if not 0
-	move	dsa2 to sfbr
-	jump	issue_check_1, if not 0
-	move	dsa3 to sfbr
-	jump	wait_for_reselection, if 0		// nothing to do
-issue_check_1:
-//	move	3 to ctest0
  	call	load_state
  	call	load_state
 	move	memory 4, state, scratcha		// get dsastate in scratcha
 	move	memory 4, state, scratcha		// get dsastate in scratcha
 	move	scratcha0 to sfbr			// and state variable in sfbr
 	move	scratcha0 to sfbr			// and state variable in sfbr
 	jump	start, if STATE_ISSUE			// right state
 	jump	start, if STATE_ISSUE			// right state
-issue_check_next:
-//	move	4 to ctest0
+	jump	wait_for_reselection, if STATE_END
+ //	move	4 to ctest0
 	move	memory 4, next, dsa			// find next
 	move	memory 4, next, dsa			// find next
 	jump	issue_check_loop
 	jump	issue_check_loop
+
+
 load_sync:
 load_sync:
 	move	memory 4, sync, scratcha		// load the sync stuff
 	move	memory 4, sync, scratcha		// load the sync stuff
 	move	scratcha0 to sfbr			// assuming load_state has been called
 	move	scratcha0 to sfbr			// assuming load_state has been called
 	move	sfbr to scntl3
 	move	sfbr to scntl3
 	move	scratcha1 to sfbr
 	move	scratcha1 to sfbr
 	move	sfbr to sxfer
 	move	sfbr to sxfer
-//	int	SIR_NOTIFY_LOAD_SYNC
+ //	int	SIR_NOTIFY_LOAD_SYNC
 	return
 	return

+ 103 - 91
sys/src/9/pc/sdata.c

@@ -9,6 +9,9 @@
 
 
 #include "../port/sd.h"
 #include "../port/sd.h"
 
 
+#define	HOWMANY(x, y)	(((x)+((y)-1))/(y))
+#define ROUNDUP(x, y)	(HOWMANY((x), (y))*(y))
+
 extern SDifc sdataifc;
 extern SDifc sdataifc;
 
 
 enum {
 enum {
@@ -254,14 +257,15 @@ enum {					/* bit masks for supported/enabled features */
 typedef struct Ctlr Ctlr;
 typedef struct Ctlr Ctlr;
 typedef struct Drive Drive;
 typedef struct Drive Drive;
 
 
-typedef struct Prd {
+typedef struct Prd {			/* Physical Region Descriptor */
 	ulong	pa;			/* Physical Base Address */
 	ulong	pa;			/* Physical Base Address */
 	int	count;
 	int	count;
 } Prd;
 } Prd;
 
 
 enum {
 enum {
-	PRDmaxio	= 32*1024,	/* must be power of 2 <= 64*1024 */
-	Nprd		= SDmaxio/PRDmaxio+2,
+	BMspan		= 64*1024,	/* must be power of 2 <= 64*1024 */
+
+	Nprd		= SDmaxio/BMspan+2,
 };
 };
 
 
 typedef struct Ctlr {
 typedef struct Ctlr {
@@ -270,6 +274,8 @@ typedef struct Ctlr {
 	int	irq;
 	int	irq;
 	int	tbdf;
 	int	tbdf;
 	int	bmiba;			/* bus master interface base address */
 	int	bmiba;			/* bus master interface base address */
+	int	maxio;			/* sector count transfer maximum */
+	int	span;			/* don't span this boundary with dma */
 
 
 	Pcidev*	pcidev;
 	Pcidev*	pcidev;
 	void	(*ienable)(Ctlr*);
 	void	(*ienable)(Ctlr*);
@@ -734,7 +740,8 @@ ataprobe(int cmdport, int ctlport, int irq)
 	SDev *sdev;
 	SDev *sdev;
 	Drive *drive;
 	Drive *drive;
 	int dev, error, rhi, rlo;
 	int dev, error, rhi, rlo;
-
+	static int nonlegacy = 'C';
+	
 	if(ioalloc(cmdport, 8, 0, "atacmd") < 0) {
 	if(ioalloc(cmdport, 8, 0, "atacmd") < 0) {
 		print("ataprobe: Cannot allocate %X\n", cmdport);
 		print("ataprobe: Cannot allocate %X\n", cmdport);
 		return nil;
 		return nil;
@@ -877,7 +884,20 @@ tryedd1:
 	ctlr->irq = irq;
 	ctlr->irq = irq;
 	ctlr->tbdf = BUSUNKNOWN;
 	ctlr->tbdf = BUSUNKNOWN;
 	ctlr->command = Cedd;		/* debugging */
 	ctlr->command = Cedd;		/* debugging */
-
+	
+	switch(cmdport){
+	default:
+		sdev->idno = nonlegacy;
+		break;
+	case 0x1F0:
+		sdev->idno = 'C';
+		nonlegacy = 'E';
+		break;
+	case 0x170:
+		sdev->idno = 'D';
+		nonlegacy = 'E';
+		break;
+	}
 	sdev->ifc = &sdataifc;
 	sdev->ifc = &sdataifc;
 	sdev->ctlr = ctlr;
 	sdev->ctlr = ctlr;
 	sdev->nunit = 2;
 	sdev->nunit = 2;
@@ -921,12 +941,26 @@ atastat(SDev *sdev, char *p, char *e)
 static SDev*
 static SDev*
 ataprobew(DevConf *cf)
 ataprobew(DevConf *cf)
 {
 {
+	char *p;
+	ISAConf isa;
+	
 	if (cf->nports != 2)
 	if (cf->nports != 2)
 		error(Ebadarg);
 		error(Ebadarg);
 
 
+	memset(&isa, 0, sizeof isa);
+	isa.port = cf->ports[0].port;
+	isa.irq = cf->intnum;
+	if((p=strchr(cf->type, '/')) == nil || pcmspecial(p+1, &isa) < 0)
+		error("cannot find controller");
+
 	return ataprobe(cf->ports[0].port, cf->ports[1].port, cf->intnum);
 	return ataprobe(cf->ports[0].port, cf->ports[1].port, cf->intnum);
 }
 }
 
 
+/*
+ * These are duplicated with sdsetsense, etc., in devsd.c, but
+ * those assume that the disk is not SCSI while in fact here
+ * ata drives are not SCSI but ATAPI ones kind of are.
+ */
 static int
 static int
 atasetsense(Drive* drive, int status, int key, int asc, int ascq)
 atasetsense(Drive* drive, int status, int key, int asc, int ascq)
 {
 {
@@ -937,6 +971,33 @@ atasetsense(Drive* drive, int status, int key, int asc, int ascq)
 	return status;
 	return status;
 }
 }
 
 
+static int
+atamodesense(Drive* drive, uchar* cmd)
+{
+	int len;
+
+	/*
+	 * Fake a vendor-specific request with page code 0,
+	 * return the drive info.
+	 */
+	if((cmd[2] & 0x3F) != 0 && (cmd[2] & 0x3F) != 0x3F)
+		return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
+	len = (cmd[7]<<8)|cmd[8];
+	if(len == 0)
+		return SDok;
+	if(len < 8+sizeof(drive->info))
+		return atasetsense(drive, SDcheck, 0x05, 0x1A, 0);
+	if(drive->data == nil || drive->dlen < len)
+		return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
+	memset(drive->data, 0, 8);
+	drive->data[0] = sizeof(drive->info)>>8;
+	drive->data[1] = sizeof(drive->info);
+	memmove(drive->data+8, drive->info, sizeof(drive->info));
+	drive->data += 8+sizeof(drive->info);
+
+	return SDok;
+}
+
 static int
 static int
 atastandby(Drive* drive, int period)
 atastandby(Drive* drive, int period)
 {
 {
@@ -959,7 +1020,7 @@ atastandby(Drive* drive, int period)
 
 
 	while(waserror())
 	while(waserror())
 		;
 		;
-	tsleep(ctlr, atadone, ctlr, 30*1000);
+	tsleep(ctlr, atadone, ctlr, 60*1000);
 	poperror();
 	poperror();
 
 
 	done = ctlr->done;
 	done = ctlr->done;
@@ -970,33 +1031,6 @@ atastandby(Drive* drive, int period)
 	return SDok;
 	return SDok;
 }
 }
 
 
-static int
-atamodesense(Drive* drive, uchar* cmd)
-{
-	int len;
-
-	/*
-	 * Fake a vendor-specific request with page code 0,
-	 * return the drive info.
-	 */
-	if((cmd[2] & 0x3F) != 0 && (cmd[2] & 0x3F) != 0x3F)
-		return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
-	len = (cmd[7]<<8)|cmd[8];
-	if(len == 0)
-		return SDok;
-	if(len < 8+sizeof(drive->info))
-		return atasetsense(drive, SDcheck, 0x05, 0x1A, 0);
-	if(drive->data == nil || drive->dlen < len)
-		return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
-	memset(drive->data, 0, 8);
-	drive->data[0] = sizeof(drive->info)>>8;
-	drive->data[1] = sizeof(drive->info);
-	memmove(drive->data+8, drive->info, sizeof(drive->info));
-	drive->data += 8+sizeof(drive->info);
-
-	return SDok;
-}
-
 static void
 static void
 atanop(Drive* drive, int subcommand)
 atanop(Drive* drive, int subcommand)
 {
 {
@@ -1055,29 +1089,32 @@ atadmasetup(Drive* drive, int len)
 	Prd *prd;
 	Prd *prd;
 	ulong pa;
 	ulong pa;
 	Ctlr *ctlr;
 	Ctlr *ctlr;
-	int bmiba, bmisx, count;
+	int bmiba, bmisx, count, i, span;
 
 
+	ctlr = drive->ctlr;
 	pa = PCIWADDR(drive->data);
 	pa = PCIWADDR(drive->data);
 	if(pa & 0x03)
 	if(pa & 0x03)
 		return -1;
 		return -1;
-	ctlr = drive->ctlr;
-	prd = ctlr->prdt;
 
 
 	/*
 	/*
 	 * Sometimes drives identify themselves as being DMA capable
 	 * Sometimes drives identify themselves as being DMA capable
 	 * although they are not on a busmastering controller.
 	 * although they are not on a busmastering controller.
 	 */
 	 */
+	prd = ctlr->prdt;
 	if(prd == nil){
 	if(prd == nil){
 		drive->dmactl = 0;
 		drive->dmactl = 0;
 		print("disabling dma: not on a busmastering controller\n");
 		print("disabling dma: not on a busmastering controller\n");
 		return -1;
 		return -1;
 	}
 	}
 
 
-	for(;;){
+	for(i = 0; len && i < Nprd; i++){
 		prd->pa = pa;
 		prd->pa = pa;
-		count = PRDmaxio - (pa & (PRDmaxio-1));
+		span = ROUNDUP(pa, ctlr->span);
+		if(span == pa)
+			span += ctlr->span;
+		count = span - pa;
 		if(count >= len){
 		if(count >= len){
-			prd->count = PrdEOT|(len & (PRDmaxio-1));
+			prd->count = PrdEOT|len;
 			break;
 			break;
 		}
 		}
 		prd->count = count;
 		prd->count = count;
@@ -1085,6 +1122,8 @@ atadmasetup(Drive* drive, int len)
 		pa += count;
 		pa += count;
 		prd++;
 		prd++;
 	}
 	}
+	if(i == Nprd)
+		(prd-1)->count |= PrdEOT;
 
 
 	bmiba = ctlr->bmiba;
 	bmiba = ctlr->bmiba;
 	outl(bmiba+Bmidtpx, PCIWADDR(ctlr->prdt));
 	outl(bmiba+Bmidtpx, PCIWADDR(ctlr->prdt));
@@ -1271,7 +1310,7 @@ atapktio(Drive* drive, uchar* cmd, int clen)
 			break;
 			break;
 		ilock(ctlr);
 		ilock(ctlr);
 		atadmainterrupt(drive, 0);
 		atadmainterrupt(drive, 0);
-		if(!drive->error && timeo > 10){
+		if(!drive->error && timeo > 20){
 			ataabort(drive, 0);
 			ataabort(drive, 0);
 			atadmastop(ctlr);
 			atadmastop(ctlr);
 			drive->dmactl = 0;
 			drive->dmactl = 0;
@@ -1389,7 +1428,8 @@ atageniostart(Drive* drive, vlong lba)
 	case Cws:
 	case Cws:
 	case Cwsm:
 	case Cwsm:
 		microdelay(1);
 		microdelay(1);
-		as = ataready(cmdport, ctlport, 0, Bsy, Drq|Err, 1000);
+		/* 10*1000 for flash ide drives - maybe detect them? */
+		as = ataready(cmdport, ctlport, 0, Bsy, Drq|Err, 10*1000);
 		if(as < 0 || (as & Err)){
 		if(as < 0 || (as & Err)){
 			iunlock(ctlr);
 			iunlock(ctlr);
 			return -1;
 			return -1;
@@ -1430,8 +1470,8 @@ atagenio(Drive* drive, uchar* cmd, int)
 {
 {
 	uchar *p;
 	uchar *p;
 	Ctlr *ctlr;
 	Ctlr *ctlr;
-	int count, max;
 	vlong lba, len;
 	vlong lba, len;
+	int count, maxio;
 
 
 	/*
 	/*
 	 * Map SCSI commands into ATA commands for discs.
 	 * Map SCSI commands into ATA commands for discs.
@@ -1522,7 +1562,7 @@ atagenio(Drive* drive, uchar* cmd, int)
 		*p++ = len>>16;
 		*p++ = len>>16;
 		*p++ = len>>8;
 		*p++ = len>>8;
 		*p = len;
 		*p = len;
-		drive->data += 8;
+		drive->data += 12;
 		return SDok;
 		return SDok;
 
 
 	case 0x28:			/* read */
 	case 0x28:			/* read */
@@ -1541,10 +1581,15 @@ atagenio(Drive* drive, uchar* cmd, int)
 	if(drive->dlen < count*drive->secsize)
 	if(drive->dlen < count*drive->secsize)
 		count = drive->dlen/drive->secsize;
 		count = drive->dlen/drive->secsize;
 	qlock(ctlr);
 	qlock(ctlr);
+	if(ctlr->maxio)
+		maxio = ctlr->maxio;
+	else if(drive->flags & Lba48)
+		maxio = 65536;
+	else
+		maxio = 256;
 	while(count){
 	while(count){
-		max = (drive->flags&Lba48) ? 65536 : 256;
-		if(count > max)
-			drive->count = max;
+		if(count > maxio)
+			drive->count = maxio;
 		else
 		else
 			drive->count = count;
 			drive->count = count;
 		if(atageniostart(drive, lba)){
 		if(atageniostart(drive, lba)){
@@ -1557,7 +1602,7 @@ atagenio(Drive* drive, uchar* cmd, int)
 
 
 		while(waserror())
 		while(waserror())
 			;
 			;
-		tsleep(ctlr, atadone, ctlr, 30*1000);
+		tsleep(ctlr, atadone, ctlr, 60*1000);
 		poperror();
 		poperror();
 		if(!ctlr->done){
 		if(!ctlr->done){
 			/*
 			/*
@@ -1797,8 +1842,8 @@ atapnp(void)
 {
 {
 	Ctlr *ctlr;
 	Ctlr *ctlr;
 	Pcidev *p;
 	Pcidev *p;
-	int channel, ispc87415, pi, r;
 	SDev *legacy[2], *sdev, *head, *tail;
 	SDev *legacy[2], *sdev, *head, *tail;
+	int channel, ispc87415, maxio, pi, r, span;
 
 
 	legacy[0] = legacy[1] = head = tail = nil;
 	legacy[0] = legacy[1] = head = tail = nil;
 	if(sdev = ataprobe(0x1F0, 0x3F4, IrqATA0)){
 	if(sdev = ataprobe(0x1F0, 0x3F4, IrqATA0)){
@@ -1839,6 +1884,8 @@ atapnp(void)
 			continue;
 			continue;
 		pi = p->ccrp;
 		pi = p->ccrp;
 		ispc87415 = 0;
 		ispc87415 = 0;
+		maxio = 0;
+		span = BMspan;
 
 
 		switch((p->did<<16)|p->vid){
 		switch((p->did<<16)|p->vid){
 		default:
 		default:
@@ -1868,8 +1915,11 @@ atapnp(void)
 		case (0x4D69<<16)|0x105A:	/* Promise Ultra/133 TX2 */
 		case (0x4D69<<16)|0x105A:	/* Promise Ultra/133 TX2 */
 		case (0x3373<<16)|0x105A:	/* Promise 20378 RAID */
 		case (0x3373<<16)|0x105A:	/* Promise 20378 RAID */
 		case (0x3149<<16)|0x1106:	/* VIA VT8237 SATA/RAID */
 		case (0x3149<<16)|0x1106:	/* VIA VT8237 SATA/RAID */
-		case (0x3112<<16)|0x1095:   	/* SiL 3112 SATA (DMA busted?) */
-		case (0x3114<<16)|0x1095:	/* SiL 3114 SATA/RAID */
+		case (0x3112<<16)|0x1095:   	/* SiI 3112 SATA/RAID */
+			maxio = 15;
+			span = 8*1024;
+			/*FALLTHROUGH*/
+		case (0x3114<<16)|0x1095:	/* SiI 3114 SATA/RAID */
 			pi = 0x85;
 			pi = 0x85;
 			break;
 			break;
 		case (0x0004<<16)|0x1103:	/* HighPoint HPT366 */
 		case (0x0004<<16)|0x1103:	/* HighPoint HPT366 */
@@ -1932,6 +1982,7 @@ atapnp(void)
 				r &= ~0x2000;
 				r &= ~0x2000;
 				pcicfgw32(sb, 0x64, r);
 				pcicfgw32(sb, 0x64, r);
 			}
 			}
+			span = 32*1024;
 			break;
 			break;
 		case (0x5513<<16)|0x1039:	/* SiS 962 */
 		case (0x5513<<16)|0x1039:	/* SiS 962 */
 		case (0x0646<<16)|0x1095:	/* CMD 646 */
 		case (0x0646<<16)|0x1095:	/* CMD 646 */
@@ -1979,6 +2030,8 @@ atapnp(void)
 				ctlr = sdev->ctlr;
 				ctlr = sdev->ctlr;
 
 
 			ctlr->pcidev = p;
 			ctlr->pcidev = p;
+			ctlr->maxio = maxio;
+			ctlr->span = span;
 			if(!(pi & 0x80))
 			if(!(pi & 0x80))
 				continue;
 				continue;
 			ctlr->bmiba = (p->mem[4].bar & ~0x01) + channel*8;
 			ctlr->bmiba = (p->mem[4].bar & ~0x01) + channel*8;
@@ -2030,46 +2083,6 @@ atalegacy(int port, int irq)
 	return ataprobe(port, port+0x204, irq);
 	return ataprobe(port, port+0x204, irq);
 }
 }
 
 
-static SDev*
-ataid(SDev* sdev)
-{
-	int i;
-	Ctlr *ctlr;
-	char name[32];
-
-	/*
-	 * Legacy controllers are always 'C' and 'D' and if
-	 * they exist and have drives will be first in the list.
-	 * If there are no active legacy controllers, native
-	 * controllers start at 'C'.
-	 */
-	if(sdev == nil)
-		return nil;
-	ctlr = sdev->ctlr;
-	if(ctlr->cmdport == 0x1F0 || ctlr->cmdport == 0x170)
-		i = 2;
-	else
-		i = 0;
-	while(sdev){
-		if(sdev->ifc == &sdataifc){
-			ctlr = sdev->ctlr;
-			if(ctlr->cmdport == 0x1F0)
-				sdev->idno = 'C';
-			else if(ctlr->cmdport == 0x170)
-				sdev->idno = 'D';
-			else{
-				sdev->idno = 'C'+i;
-				i++;
-			}
-			snprint(name, sizeof(name), "sd%c", sdev->idno);
-			kstrdup(&sdev->name, name);
-		}
-		sdev = sdev->next;
-	}
-
-	return nil;
-}
-
 static int
 static int
 ataenable(SDev* sdev)
 ataenable(SDev* sdev)
 {
 {
@@ -2230,7 +2243,6 @@ SDifc sdataifc = {
 
 
 	atapnp,				/* pnp */
 	atapnp,				/* pnp */
 	atalegacy,			/* legacy */
 	atalegacy,			/* legacy */
-	ataid,				/* id */
 	ataenable,			/* enable */
 	ataenable,			/* enable */
 	atadisable,			/* disable */
 	atadisable,			/* disable */
 
 

+ 1346 - 0
sys/src/9/pc/sdmv50xx.c

@@ -0,0 +1,1346 @@
+/*
+ * Marvell 88SX5040, 5041, 5080, 5081 driver
+ * This is a heavily-modified version of a driver written by Coraid, Inc.
+ * The original copyright notice appears at the end of this file.
+ */
+ 
+#include	"u.h"
+#include	"../port/lib.h"
+#include	"mem.h"
+#include	"dat.h"
+#include	"fns.h"
+#include 	"io.h"
+#include	"../port/error.h"
+
+#include	"../port/sd.h"
+
+#define DPRINT	if(0)iprint
+
+enum {
+	SrbRing = 32,
+	
+	/* Addresses of ATA register */
+	ARcmd		= 027,
+	ARdev		= 026,
+	ARerr		= 021,
+	ARfea		= 021,
+	ARlba2		= 025,
+	ARlba1		= 024,
+	ARlba0		= 023,
+	ARseccnt		= 022,
+	ARstat		= 027,
+	
+	ATAerr	= (1<<0),
+	ATAdrq	= (1<<3),
+	ATAdf 	= (1<<5),
+	ATAdrdy 	= (1<<6),
+	ATAbusy 	= (1<<7),
+	ATAabort	= (1<<2),
+	ATAeIEN	= (1<<1),
+	ATAsrst	= (1<<2),
+	ATAhob	= (1<<7),
+
+	SFdone = (1<<0),
+	SFerror = (1<<1),
+
+	SRBident = 0,
+	SRBread,
+	SRBwrite,
+	SRBsmart,
+
+	SRBnodata = 0,
+	SRBdatain,
+	SRBdataout,
+	
+	RQread	= 1,			/* data coming IN from device */
+	
+	PRDeot	= (1<<15),
+	
+	/* EDMA interrupt error cause register */
+
+	ePrtDataErr	= (1<<0),
+	ePrtPRDErr	= (1<<1),
+	eDevErr		= (1<<2),
+	eDevDis		= (1<<3),
+	eDevCon		= (1<<4),
+	eOverrun		= (1<<5),
+	eUnderrun	= (1<<6),
+	eSelfDis		= (1<<8),
+	ePrtCRQBErr	= (1<<9),
+	ePrtCRPBErr	= (1<<10),
+	ePrtIntErr		= (1<<11),
+	eIORdyErr		= (1<<12),
+
+	/* EDMA Command Register */
+
+	eEnEDMA		= (1<<0),
+	eDsEDMA 	= (1<<1),
+	eAtaRst 		= (1<<2),
+
+	/* Interrupt mask for errors we care about */
+	IEM			= (eDevDis | eDevCon | eSelfDis),
+	
+	Dnull = 0,
+	Dnew,
+	Dident,
+	Dready,
+	Derror,
+	Dmissing,
+	Dunconfig,
+
+	Dext	 	= (1<<0),		/* use ext commands */
+	Dpio		= (1<<1),		/* doing pio */
+	Dwanted	= (1<<2),		/* someone wants an srb entry */
+	Dedma	= (1<<3),		/* device in edma mode */
+	Dpiowant	= (1<<4),		/* some wants to use the pio mode */
+};
+
+static char* diskstates[] =
+{
+	"null",
+	"new",
+	"ident",
+	"ready",
+	"error",
+	"missing",
+	"unconfigured",
+};
+
+extern SDifc sdmv50xxifc;
+
+typedef struct Arb Arb;
+typedef struct Bridge Bridge;
+typedef struct Chip Chip;
+typedef struct Ctlr Ctlr;
+typedef struct Drive Drive;
+typedef struct Edma Edma;
+typedef struct Prd Prd;
+typedef struct Rx Rx;
+typedef struct Srb Srb;
+typedef struct Tx Tx;
+
+struct Chip	/* pointers to per-Chip mmio */
+{
+	Arb		*arb;
+	Edma	*edma;	/* array of 4 */
+};
+
+struct Drive	/* a single disk */
+{
+	Lock;
+
+	Ctlr		*ctlr;
+	SDunit	*unit;
+	int		subno;
+	char		name[10];
+
+	Bridge	*bridge;
+	Edma	*edma;
+	Chip		*chip;
+	int		chipx;
+	
+	int		state;
+	int		flag;
+	uvlong	sectors;
+
+	char		serial[20+1];
+	char		firmware[8+1];
+	char		model[40+1];
+
+	ushort	info[256];
+	
+	Srb		*srb[SrbRing-1];
+	int		nsrb;
+	Prd		*prd;
+	Tx		*tx;
+	Rx		*rx;
+	
+	Srb		*srbhead;
+	Srb		*srbtail;
+};
+
+struct Ctlr		/* a single PCI card */
+{
+	Lock;
+
+	int		irq;
+	int		tbdf;
+	SDev		*sdev;
+	Pcidev	*pcidev;
+
+	uchar	*mmio;
+	Chip		chip[2];
+	int		nchip;
+	Drive	drive[8];
+	int		ndrive;
+};
+
+struct Srb		/* request buffer */
+{
+	Lock;
+	Rendez;
+	Srb		*next;
+
+	Drive	*drive;
+	uvlong	blockno;
+	int		count;
+	int		req;
+	int		flag;
+	uchar	*data;
+	
+	uchar	cmd;
+	uchar	lba[6];
+	uchar	sectors;
+	int		sta;
+	int		err;
+};
+
+/*
+ * Memory-mapped I/O registers in many forms.
+ */
+struct Bridge	/* memory-mapped per-Drive registers */
+{
+	ulong	status;
+	ulong	serror;
+	ulong	sctrl;
+	ulong	phyctrl;
+	char		fill1[0x2c];
+	ulong	ctrl;
+	char		fill2[0x34];
+	ulong	phymode;
+	char		fill3[0x88];	/* pad to 0x100 in length */
+};
+
+struct Arb		/* memory-mapped per-Chip registers */
+{
+	ulong	fill0;
+	ulong	rqop;	/* request queue out-pointer */
+	ulong	rqip;		/* response queue in pointer */
+	ulong	ict;		/* inerrupt caolescing threshold */
+	ulong	itt;		/* interrupt timer threshold */
+	ulong	ic;		/* interrupt cause */
+	ulong	btc;		/* bridges test control */
+	ulong	bts;		/* bridges test status */
+	ulong	bpc;		/* bridges pin configuration */
+	char		fill1[0xdc];
+	Bridge	bridge[4];
+};
+
+struct Edma	/* memory-mapped per-Drive DMA-related registers */
+{
+	ulong		config;		/* configuration register */
+	ulong		timer;
+	ulong		iec;			/* interrupt error cause */
+	ulong		iem;			/* interrupt error mask */
+
+	ulong		txbasehi;		/* request queue base address high */
+	ulong		txi;			/* request queue in pointer */
+	ulong		txo;			/* request queue out pointer */
+
+	ulong		rxbasehi;		/* response queue base address high */
+	ulong		rxi;			/* response queue in pointer */
+	ulong		rxo;			/* response queue out pointer */
+	
+	ulong		ctl;			/* command register */
+	ulong		testctl;		/* test control */
+	ulong		status;
+	ulong		iordyto;		/* IORDY timeout */
+	char			fill[0xc8];
+	ushort		pio;			/* data register */
+	char			pad0[2];
+	uchar		err;			/* features and error */
+	char			pad1[3];
+	uchar		seccnt;		/* sector count */
+	char			pad2[3];
+	uchar		lba0;
+	char			pad3[3];
+	uchar		lba1;
+	char			pad4[3];
+	uchar		lba2;
+	char			pad5[3];
+	uchar		lba3;
+	char			pad6[3];
+	uchar		cmdstat;		/* cmd/status */
+	char			pad7[3];
+	uchar		altstat;		/* alternate status */
+	char			fill2[0x1edc];	/* pad to 0x2000 bytes */
+};
+
+/*
+ * Memory structures shared with card.
+ */
+struct Prd		/* physical region descriptor */
+{
+	ulong	pa;		/* byte address of physical memory */
+	ushort	count;		/* byte count (bit0 must be 0) */
+	ushort	flag;
+	ulong	zero;			/* high long of 64 bit address */
+	ulong	reserved;
+};
+
+struct Tx		/* command request block */
+{
+	ulong	prdpa;		/* physical region descriptor table structures */
+	ulong	zero;			/* must be zero (high long of prd address) */
+	ushort	flag;			/* control flags */
+	ushort	regs[11];
+};
+
+struct Rx		/* command response block */
+{
+	ushort	cid;			/* cID of response */
+	uchar	cEdmaSts;		/* EDMA status */
+	uchar	cDevSts;		/* status from disk */
+	ulong	ts;			/* time stamp */
+};
+
+/*
+ * Little-endian parsing for drive data.
+ */
+static ushort
+lhgets(void *p)
+{
+	uchar *a = p;
+	return ((ushort) a[1] << 8) | a[0];
+}
+
+static ulong
+lhgetl(void *p)
+{
+	uchar *a = p;
+	return ((ulong) lhgets(a+2) << 16) | lhgets(a);
+}
+
+static uvlong
+lhgetv(void *p)
+{
+	uchar *a = p;
+	return ((uvlong) lhgetl(a+4) << 32) | lhgetl(a);
+}
+
+static void
+idmove(char *p, ushort *a, int n)
+{
+	char *op;
+	int i;
+	
+	op = p;
+	for(i=0; i<n/2; i++){
+		*p++ = a[i]>>8;
+		*p++ = a[i];
+	}
+	while(p>op && *--p == ' ')
+		*p = 0;
+}
+
+/*
+ * Request buffers.
+ */
+struct 
+{
+	Lock;
+	Srb *freechain;
+	int nalloc;
+} srblist;
+
+static Srb*
+allocsrb(void)
+{
+	Srb *p;
+	
+	ilock(&srblist);
+	if((p = srblist.freechain) == nil){
+		srblist.nalloc++;
+		iunlock(&srblist);
+		p = smalloc(sizeof *p);
+	}else{
+		srblist.freechain = p->next;
+		iunlock(&srblist);
+	}
+	return p;
+}
+
+static void
+freesrb(Srb *p)
+{
+	ilock(&srblist);
+	p->next = srblist.freechain;
+	srblist.freechain = p;
+	iunlock(&srblist);
+}
+
+/*
+ * Wait for a byte to be a particular value.
+ */
+static int
+satawait(uchar *p, uchar mask, uchar v, int ms)
+{
+	int i;
+
+//	DPRINT("satawait %p %#x %#x %d...", p, mask, v, ms);
+//	DPRINT("!%#x...", *p);
+	for(i=0; i<ms && (*p & mask) != v; i++){
+		if(i%1000 == 0)
+			DPRINT("!%#x", *p);
+		microdelay(1000);
+	}
+	return (*p & mask) == v;
+}
+
+/*
+ * Drive initialization
+ */
+static int
+configdrive(Ctlr *ctlr, Drive *d, SDunit *unit)
+{
+	int i;
+	ulong *r;
+	
+	DPRINT("%s: configdrive\n", unit->name);
+	d->unit = unit;
+	d->ctlr = ctlr;
+	d->chipx = unit->subno%4;
+	d->chip = &ctlr->chip[unit->subno/4];
+	d->bridge = &d->chip->arb->bridge[d->chipx];
+	d->edma = &d->chip->edma[d->chipx];
+
+	if(d->tx == nil){
+		d->tx = mallocalign(32*sizeof(Tx), 1024, 0, 0);
+		d->rx = mallocalign(32*sizeof(Rx), 256, 0, 0);
+		d->prd = mallocalign(32*sizeof(Prd), 32, 0, 0);
+		if(d->tx == nil || d->rx == nil || d->prd == nil){
+			iprint("%s: out of memory allocating ring buffers\n",
+				unit->name);
+			free(d->tx);
+			d->tx = nil;
+			free(d->rx);
+			d->rx = nil;
+			free(d->prd);
+			d->prd = nil;
+			d->state = Dunconfig;
+			return 0;
+		}
+		for(i=0; i<32; i++)
+			d->tx[i].prdpa = PADDR(&d->prd[i]);
+		coherence();
+	}
+	
+	/* leave disk interrupts turned off until we use it ... */
+	d->edma->iem = 0;
+	
+	/* ... but enable them on the controller */
+	r = (ulong*)(d->ctlr->mmio + 0x1D64);
+	if(d->unit->subno < 4)
+		*r |= 3 << (d->chipx*2);
+	else
+		*r |= 3 << (d->chipx*2+9);
+
+	return 1;
+}
+
+static int
+enabledrive(Drive *d)
+{
+	Edma *edma;
+	
+	DPRINT("%s: enabledrive\n", d->unit->name);
+
+	if((d->bridge->status & 0xF) != 0x3){	/* Det */
+		DPRINT("%s: not present\n", d->unit->name);
+		d->state = Dmissing;
+		return 0;
+	}
+	edma = d->edma;
+	if(satawait(&edma->cmdstat, ATAbusy, 0, 10*1000) == 0){
+		print("%s: busy timeout\n", d->unit->name);
+		d->state = Dmissing;
+		return 0;
+	}
+
+	edma->iec = 0;
+	d->chip->arb->ic &= ~(0x101 << d->chipx);
+	edma->config = 0x11F;
+	edma->txi = PADDR(d->tx);
+	edma->txo = (ulong)d->tx & 0x3E0;
+	edma->rxi = (ulong)d->rx & 0xF8;
+	edma->rxo = PADDR(d->rx);
+	edma->ctl |= 1;		/* enable dma */
+
+	DPRINT("%s: enable interrupts\n", d->unit->name);
+	if(d->bridge->status = 0x113)
+		d->state = Dnew;
+	d->edma->iem = IEM;
+	return 1;
+}
+
+static void
+disabledrive(Drive *d)
+{
+	int i;
+	ulong *r;
+
+	DPRINT("%s: disabledrive\n", d->unit->name);
+
+	if(d->tx == nil)	/* never enabled */
+		return;
+
+	d->edma->ctl = 0;
+	d->edma->iem = 0;
+
+	r = (ulong*)(d->ctlr->mmio + 0x1D64);
+	i = d->chipx;
+	if(d->chipx < 4)
+		*r &= ~(3 << (i*2));
+	else
+		*r |= ~(3 << (i*2+9));
+}
+
+static int
+setudmamode(Drive *d, uchar mode)
+{
+	Edma *edma;
+	
+	DPRINT("%s: setudmamode %d\n", d->unit->name, mode);
+
+	edma = d->edma;
+	if(satawait(&edma->cmdstat, ATAerr|ATAdrq|ATAdf|ATAdrdy|ATAbusy, ATAdrdy, 15*1000) == 0){
+		iprint("%s: cmdstat 0x%.2ux ready timeout\n",
+			d->unit->name, edma->cmdstat);
+		return 0;
+	}
+	edma->altstat = ATAeIEN;
+	edma->err = 3;
+	edma->seccnt = 0x40 | mode;
+	edma->cmdstat = 0xEF;
+	microdelay(1);
+	if(satawait(&edma->cmdstat, ATAbusy, 0, 15*1000) == 0){
+		iprint("%s: cmdstat 0x%.2ux busy timeout\n", 
+			d->unit->name, edma->cmdstat);
+		return 0;
+	}
+	return 1;
+}
+
+static void
+identifydrive(Drive *d)
+{
+	int i;
+	ushort *id;
+	Edma *edma;
+	SDunit *unit;
+	
+	DPRINT("%s: identifydrive\n", d->unit->name);
+
+	if(setudmamode(d, 5) == 0)	/* do all SATA support 5? */
+		goto Error;
+
+	id = d->info;
+	memset(d->info, 0, sizeof d->info);
+	edma = d->edma;
+	if(satawait(&edma->cmdstat, 0xE9, 0x40, 15*1000) == 0)
+		goto Error;
+
+	edma->altstat = ATAeIEN;	/* no interrupts */
+	edma->cmdstat = 0xEC;
+	microdelay(1);
+	if(satawait(&edma->cmdstat, ATAbusy, 0, 15*1000) == 0)
+		goto Error;
+	for(i=0; i<256; i++)
+		id[i] = edma->pio;
+	if(edma->cmdstat & (ATAerr|ATAdf))
+		goto Error;
+	i = lhgets(id+83) | lhgets(id+86);
+	if(i & (1<<10)){
+		d->flag |= Dext;
+		d->sectors = lhgetv(id+100);
+	}else{
+		d->flag &= ~Dext;
+		d->sectors = lhgetl(id+60);
+	}
+	idmove(d->serial, id+10, 20);
+	idmove(d->firmware, id+23, 8);
+	idmove(d->model, id+27, 40);
+	
+	unit = d->unit;
+	memset(unit->inquiry, 0, sizeof unit->inquiry);
+	unit->inquiry[2] = 2;
+	unit->inquiry[3] = 2;
+	unit->inquiry[4] = sizeof(unit->inquiry)-4;
+	idmove((char*)unit->inquiry+8, id+27, 40);
+
+	if(enabledrive(d))
+		d->state = Dready;
+	else
+		d->state = Derror;
+	return;
+
+Error:
+	DPRINT("error...");
+	d->state = Derror;
+}
+
+static void abortallsrb(Drive*);
+
+static void
+updatedrive(Drive *d, ulong cause)
+{
+	int x;
+	Edma *edma;
+	
+	if(cause == 0)
+		return;
+
+	DPRINT("%s: updatedrive %#lux\n", d->unit->name, cause);
+
+	edma = d->edma;
+	if(cause & eDevDis){
+		d->state = Dmissing;
+		edma->ctl |= eAtaRst;
+		microdelay(25);
+		edma->ctl &= ~eAtaRst;
+		microdelay(25);
+	}
+	if(cause & eDevCon){
+		d->bridge->sctrl = (d->bridge->sctrl & ~0xF) | 1;
+		d->state = Dnew;
+	}
+	if(cause & eSelfDis)
+		d->state = Derror;
+	edma->iec = 0;
+	d->sectors = 0;
+	d->unit->sectors = 0;
+	abortallsrb(d);
+	x = edma->cmdstat;
+	USED(x);
+}
+
+/*
+ * Requests
+ */
+static Srb*
+srbrw(int req, Drive *d, uchar *data, uint sectors, uvlong lba)
+{
+	int i;
+	Srb *srb;
+	static uchar cmd[2][2] = { 0xC8, 0x25, 0xCA, 0x35 };
+
+	switch(req){
+	case SRBread:
+	case SRBwrite:
+		break;
+	default:
+		return nil;
+	}
+	
+	srb = allocsrb();
+	srb->req = req;
+	srb->drive = d;
+	srb->blockno = lba;
+	srb->sectors = sectors;
+	srb->count = sectors*512;
+	srb->flag = 0;
+	srb->data = data;
+
+	for(i=0; i<6; i++)
+		srb->lba[i] = lba >> (8*i);
+	srb->cmd = cmd[srb->req!=SRBread][(d->flag&Dext)!=0];
+	return srb;
+}
+
+static uintptr
+advance(uintptr pa, int shift)
+{
+	int n, mask;
+	
+	mask = 0x1F<<shift;
+	n = (pa & mask) + (1<<shift);
+	return (pa & ~mask) | (n & mask);
+}
+
+#define CMD(r, v) (((r)<<8) | ((v)&0xFF))
+static void
+atarequest(ushort *cmd, Srb *srb, int ext)
+{
+	*cmd++ = CMD(ARseccnt, 0);
+	*cmd++ = CMD(ARseccnt, srb->sectors);
+	*cmd++ = CMD(ARfea, 0);
+	if(ext){
+		*cmd++ = CMD(ARlba0, srb->lba[3]);
+		*cmd++ = CMD(ARlba0, srb->lba[0]);
+		*cmd++ = CMD(ARlba1, srb->lba[4]);
+		*cmd++ = CMD(ARlba1, srb->lba[1]);
+		*cmd++ = CMD(ARlba2, srb->lba[5]);
+		*cmd++ = CMD(ARlba2, srb->lba[2]);
+		*cmd++ = CMD(ARdev, 0xE0);
+	}else{
+		*cmd++ = CMD(ARlba0, srb->lba[0]);
+		*cmd++ = CMD(ARlba1, srb->lba[1]);
+		*cmd++ = CMD(ARlba2, srb->lba[2]);
+		*cmd++ = CMD(ARdev, srb->lba[3] | 0xE0);
+	}
+	*cmd++ = CMD(ARcmd, srb->cmd) | (1<<15);
+	USED(cmd);
+}
+
+static void
+startsrb(Drive *d, Srb *srb)
+{
+	int i;
+	Edma *edma;
+	Prd *prd;
+	Tx *tx;
+	
+	if(d->nsrb >= nelem(d->srb)){
+		srb->next = nil;
+		if(d->srbhead)
+			d->srbtail->next = srb;
+		else
+			d->srbhead = srb;
+		d->srbtail = srb;
+		return;
+	}
+	
+	d->nsrb++;
+	for(i=0; i<nelem(d->srb); i++)
+		if(d->srb[i] == nil)
+			break;
+	if(i == nelem(d->srb))
+		panic("sdmv50xx: no free srbs");
+	d->srb[i] = srb;
+	edma = d->edma;
+	tx = (Tx*)KADDR(edma->txi);
+	tx->flag = (i<<1) | (srb->req == SRBread);
+	prd = KADDR(tx->prdpa);
+	prd->pa = PADDR(srb->data);
+	prd->count = srb->count;
+	prd->flag = PRDeot;
+	atarequest(tx->regs, srb, d->flag&Dext);
+	coherence();
+	edma->txi = advance(edma->txi, 5);
+}
+
+static void
+completesrb(Drive *d)
+{
+	Edma *edma;
+	Rx *rx;
+	Srb *srb;
+	
+	edma = d->edma;
+	if((edma->ctl & eEnEDMA) == 0)
+		return;
+	
+	while((edma->rxo & (0x1F<<3)) != (edma->rxi & (0x1F<<3))){
+		rx = (Rx*)KADDR(edma->rxo);
+		if(srb = d->srb[rx->cid]){
+			d->srb[rx->cid] = nil;
+			d->nsrb--;
+			if(rx->cDevSts & (ATAerr|ATAdf))
+				srb->flag |= SFerror;
+			srb->flag |= SFdone;
+			srb->sta = rx->cDevSts;
+			wakeup(srb);
+		}else
+			iprint("srb missing\n");
+		edma->rxo = advance(edma->rxo, 3);
+		if(srb = d->srbhead){
+			d->srbhead = srb->next;
+			startsrb(d, srb);
+		}
+	}
+}
+			
+static void
+abortallsrb(Drive *d)
+{
+	int i;
+	Srb *srb;
+
+	for(i=0; i<nelem(d->srb); i++){
+		if(srb = d->srb[i]){
+			d->srb[i] = nil;
+			d->nsrb--;
+			srb->flag |= SFerror|SFdone;
+			wakeup(srb);
+		}
+	}
+	while(srb = d->srbhead){
+		d->srbhead = srb->next;
+		srb->flag |= SFerror|SFdone;
+		wakeup(srb);
+	}	
+}
+
+static int
+srbdone(void *v)
+{
+	Srb *srb;
+	
+	srb = v;
+	return srb->flag & SFdone;
+}
+
+/*
+ * Interrupts
+ */
+static void
+mv50interrupt(Ureg*, void *a)
+{
+	int i;
+	ulong cause;
+	Ctlr *ctlr;
+	Drive *drive;
+	
+	ctlr = a;
+	ilock(ctlr);
+	cause = *(ulong*)(ctlr->mmio + 0x1D60);
+	DPRINT("sd%c: mv50interrupt: 0x%lux\n", ctlr->sdev->idno, cause);
+	for(i=0; i<ctlr->ndrive; i++){
+		if(cause & (3<<(i*2+i/4))){
+			drive = &ctlr->drive[i];
+			ilock(drive);
+			updatedrive(drive, drive->edma->iec);
+			while(ctlr->chip[i/4].arb->ic & (0x0101 << (i%4))){
+				ctlr->chip[i/4].arb->ic = ~(0x101 << (i%4));
+				completesrb(drive);
+			}
+			iunlock(drive);
+		}
+	}
+	iunlock(ctlr);
+}
+
+/*
+ * Device discovery
+ */
+static SDev*
+mv50pnp(void)
+{
+	int i, nunit;
+	uchar *base;
+	ulong io;
+	void *mem;
+	Ctlr *ctlr;
+	Pcidev *p;
+	SDev *head, *tail, *sdev;
+
+	DPRINT("mv50pnp\n");
+
+	p = nil;
+	head = nil;
+	tail = nil;
+	while((p = pcimatch(p, 0x11AB, 0)) != nil){
+		switch(p->did){
+		case 0x5041:
+			nunit = 4;
+			break;
+		case 0x5081:
+			nunit = 8;
+			break;
+		default:
+			continue;
+		}
+		if((sdev = malloc(sizeof(SDev))) == nil)
+			continue;
+		if((ctlr = malloc(sizeof(Ctlr))) == nil){
+			free(sdev);
+			continue;
+		}
+		io = p->mem[0].bar & ~0x0F;
+		mem = vmap(io, p->mem[0].size);
+		if(mem == 0){
+			print("sdmv50xx: address 0x%luX in use\n", io);
+			free(sdev);
+			free(ctlr);
+			continue;
+		}
+		sdev->ifc = &sdmv50xxifc;
+		sdev->ctlr = ctlr;
+		sdev->nunit = nunit;
+		sdev->idno = 'E';
+		ctlr->sdev = sdev;
+		ctlr->irq = p->intl;
+		ctlr->tbdf = p->tbdf;
+		ctlr->pcidev = p;
+		ctlr->mmio = mem;
+		ctlr->nchip = (nunit+3)/4;
+		ctlr->ndrive = nunit;
+		for(i=0; i<ctlr->nchip; i++){
+			base = ctlr->mmio+0x20000+0x10000*i;
+			ctlr->chip[i].arb = (Arb*)base;
+			ctlr->chip[i].edma = (Edma*)(base + 0x2000);
+		}
+		if(head)
+			tail->next = sdev;
+		else
+			head = sdev;
+		tail = sdev;
+	}
+	return head;
+}
+
+/*
+ * Enable the controller.  Each disk has its own interrupt mask,
+ * and those get enabled as the disks are brought online.
+ */
+static int
+mv50enable(SDev *sdev)
+{
+	char name[32];
+	Ctlr *ctlr;
+
+	DPRINT("sd%c: enable\n", sdev->idno);
+
+	ctlr = sdev->ctlr;
+	snprint(name, sizeof name, "%s (%s)", sdev->name, sdev->ifc->name);
+	intrenable(ctlr->irq, mv50interrupt, ctlr, ctlr->tbdf, name);
+	return 1;
+}
+
+/*
+ * Disable the controller.
+ */
+static int
+mv50disable(SDev *sdev)
+{
+	char name[32];
+	int i;
+	Ctlr *ctlr;
+	Drive *drive;
+	
+	DPRINT("sd%c: disable\n", sdev->idno);
+
+	ctlr = sdev->ctlr;
+	ilock(ctlr);
+	for(i=0; i<ctlr->sdev->nunit; i++){
+		drive = &ctlr->drive[i];
+		ilock(drive);
+		disabledrive(drive);
+		iunlock(drive);
+	}
+	iunlock(ctlr);
+	snprint(name, sizeof name, "%s (%s)", sdev->name, sdev->ifc->name);
+	intrdisable(ctlr->irq, mv50interrupt, ctlr, ctlr->tbdf, name);
+	return 0;
+}
+
+/*
+ * Clean up all disk structures.  Already disabled.
+ * Could keep count of number of allocated controllers
+ * and free the srblist when it drops to zero.
+ */
+static void
+mv50clear(SDev *sdev)
+{
+	int i;
+	Ctlr *ctlr;
+	Drive *d;
+
+	DPRINT("sd%c: clear\n", sdev->idno);
+
+	ctlr = sdev->ctlr;
+	for(i=0; i<ctlr->ndrive; i++){
+		d = &ctlr->drive[i];
+		free(d->tx);
+		free(d->rx);
+		free(d->prd);
+	}
+	free(ctlr);
+}
+
+/*
+ * Check that there is a disk or at least a hot swap bay in the drive.
+ */
+static int
+mv50verify(SDunit *unit)
+{
+	Ctlr *ctlr;
+	Drive *drive;
+
+	DPRINT("%s: verify\n", unit->name);
+
+	/*
+	 * First access of unit.
+	 */
+
+	ctlr = unit->dev->ctlr;
+	drive = &ctlr->drive[unit->subno];
+	ilock(ctlr);
+	ilock(drive);
+
+	if(!configdrive(ctlr, drive, unit) || !enabledrive(drive)){
+		iunlock(drive);
+		iunlock(ctlr);
+		return 0;
+	}
+	/*
+	 * Need to reset the drive before the first call to 
+	 * identifydrive, or else the satawait in setudma will 
+	 * freeze the machine when accessing edma->cmdstat.
+	 * I do not understand this.		-rsc
+	 */
+	updatedrive(drive, eDevDis);
+
+	iunlock(drive);
+	iunlock(ctlr);
+
+	return 1;
+}
+
+/*
+ * Check whether the disk is online.
+ */
+static int
+mv50online(SDunit *unit)
+{
+	Ctlr *ctlr;
+	Drive *drive;
+
+	ctlr = unit->dev->ctlr;
+	drive = &ctlr->drive[unit->subno];
+	ilock(drive);
+	if(drive->state == Dready){
+		unit->sectors = drive->sectors;
+		unit->secsize = 512;
+		iunlock(drive);
+		return 1;
+	}
+
+	DPRINT("%s: online %s\n", unit->name, diskstates[drive->state]);
+
+	if(drive->state == Dnew){
+		identifydrive(drive);
+		if(drive->state == Dready){
+			unit->sectors = drive->sectors;
+			unit->secsize = 512;
+			iunlock(drive);
+			return 2;	/* media changed */
+		}
+	}
+	iunlock(drive);
+	return 0;
+}
+
+/*
+ * Register dumps
+ */
+typedef struct Regs Regs;
+struct Regs
+{
+	ulong offset;
+	char *name;
+};
+
+static Regs regsctlr[] =
+{
+	0x0C28, "pci serr# mask",
+	0x1D40, "pci err addr low",
+	0x1D44, "pci err addr hi",
+	0x1D48, "pci err attr",
+	0x1D50, "pci err cmd",
+	0x1D58, "pci intr cause",
+	0x1D5C, "pci mask cause",
+	0x1D60, "device micr",
+	0x1D64, "device mimr",
+};
+
+static Regs regsarb[] =
+{
+	0x0004,	"arb rqop",
+	0x0008,	"arb rqip",
+	0x000C,	"arb ict",
+	0x0010,	"arb itt",
+	0x0014,	"arb ic",
+	0x0018,	"arb btc",
+	0x001C,	"arb bts",
+	0x0020,	"arb bpc",
+};
+
+static Regs regsbridge[] =
+{
+	0x0000,	"bridge status",
+	0x0004,	"bridge serror",
+	0x0008,	"bridge sctrl",
+	0x000C,	"bridge phyctrl",
+	0x003C,	"bridge ctrl",
+	0x0074,	"bridge phymode",
+};
+
+static Regs regsedma[] =
+{
+	0x0000,	"edma config",
+	0x0004,	"edma timer",
+	0x0008,	"edma iec",
+	0x000C,	"edma iem",
+	0x0010,	"edma txbasehi",
+	0x0014,	"edma txi",
+	0x0018,	"edma txo",
+	0x001C,	"edma rxbasehi",
+	0x0020,	"edma rxi",
+	0x0024,	"edma rxo",
+	0x0028,	"edma c",
+	0x002C,	"edma tc",
+	0x0030,	"edma status",
+	0x0034,	"edma iordyto",
+/*	0x0100,	"edma pio",
+	0x0104,	"edma err",
+	0x0108,	"edma sectors",
+	0x010C,	"edma lba0",
+	0x0110,	"edma lba1",
+	0x0114,	"edma lba2",
+	0x0118,	"edma lba3",
+	0x011C,	"edma cmdstat",
+	0x0120,	"edma altstat",
+*/
+};
+
+static char*
+rdregs(char *p, char *e, void *base, Regs *r, int n, char *prefix)
+{
+	int i;
+	
+	for(i=0; i<n; i++)
+		p = seprint(p, e, "%s%s%-19s %.8ux\n", 
+			prefix ? prefix : "", prefix ? ": " : "",
+			r[i].name, *(u32int*)((uchar*)base+r[i].offset));
+	return p;
+}
+
+static char*
+rdinfo(char *p, char *e, ushort *info)
+{
+	int i;
+	
+	p = seprint(p, e, "info");
+	for(i=0; i<256; i++){
+		p = seprint(p, e, "%s%.4ux%s", 
+			i%8==0 ? "\t" : "",
+			info[i], 
+			i%8==7 ? "\n" : "");
+	}
+	return p;
+}
+
+static int
+mv50rctl(SDunit *unit, char *p, int l)
+{
+	char *e, *op;
+	Ctlr *ctlr;
+	Drive *drive;
+	
+	if((ctlr = unit->dev->ctlr) == nil)
+		return 0;
+	drive = &ctlr->drive[unit->subno];
+	
+	e = p+l;
+	op = p;
+	if(drive->state == Dready){
+		p = seprint(p, e, "model    %s\n", drive->model);
+		p = seprint(p, e, "serial   %s\n", drive->serial);
+		p = seprint(p, e, "firmware %s\n", drive->firmware);
+	}else
+		p = seprint(p, e, "no disk present\n");
+	p = seprint(p, e, "geometry %llud 512\n", drive->sectors);
+	p = rdinfo(p, e, drive->info);
+	
+	p = rdregs(p, e, drive->chip->arb, regsarb, nelem(regsarb), nil);
+	p = rdregs(p, e, drive->bridge, regsbridge, nelem(regsbridge), nil);
+	p = rdregs(p, e, drive->edma, regsedma, nelem(regsedma), nil);
+
+	return p-op;
+}
+
+static int
+mv50wctl(SDunit *unit, Cmdbuf *cb)
+{
+	Ctlr *ctlr;
+	Drive *drive;
+	
+	USED(unit);
+	if(strcmp(cb->f[0], "reset") == 0){
+		ctlr = unit->dev->ctlr;
+		drive = &ctlr->drive[unit->subno];
+		ilock(drive);
+		updatedrive(drive, eDevDis);
+		iunlock(drive);
+		return 0;
+	}
+	cmderror(cb, Ebadctl);
+	return -1;
+}
+
+static char*
+mv50rtopctl(SDev *sdev, char *p, char *e)
+{
+	char name[10];
+	Ctlr *ctlr;
+	
+	ctlr = sdev->ctlr;
+	if(ctlr == nil)
+		return p;
+
+	snprint(name, sizeof name, "sd%c", sdev->idno);
+	p = rdregs(p, e, ctlr->mmio, regsctlr, nelem(regsctlr), name);
+	/* info for first disk */
+	p = rdregs(p, e, ctlr->chip[0].arb, regsarb, nelem(regsarb), name);
+	p = rdregs(p, e, &ctlr->chip[0].arb->bridge[0], regsbridge, nelem(regsbridge), name);
+	p = rdregs(p, e, &ctlr->chip[0].edma[0], regsedma, nelem(regsedma), name);
+	
+	return p;
+}
+
+static int
+mv50rio(SDreq *r)
+{
+	int count, max, n, status;
+	uchar *cmd, *data;
+	uvlong lba;
+	Ctlr *ctlr;
+	Drive *drive;
+	SDunit *unit;
+	Srb *srb;
+	
+	unit = r->unit;
+	ctlr = unit->dev->ctlr;
+	drive = &ctlr->drive[unit->subno];
+	cmd = r->cmd;
+	
+	if((status = sdfakescsi(r, drive->info, sizeof drive->info)) != SDnostatus){
+		/* XXX check for SDcheck here */
+		r->status = status;
+		return status;
+	}
+
+	switch(cmd[0]){
+	case 0x28:	/* read */
+	case 0x2A:	/* write */
+		break;
+	default:
+		print("sdmv50xx: bad cmd 0x%.2ux\n", cmd[0]);
+		r->status = SDcheck;
+		return SDcheck;
+	}
+	
+	lba = (cmd[2]<<24)|(cmd[3]<<16)|(cmd[4]<<8)|cmd[5];
+	count = (cmd[7]<<8)|cmd[8];
+	if(r->data == nil)
+		return SDok;
+	if(r->dlen < count*unit->secsize)
+		count = r->dlen/unit->secsize;
+	
+	/* 
+	 * Could arrange here to have an Srb always outstanding:
+	 *
+	 *	lsrb = nil;
+	 *	while(count > 0 || lsrb != nil){
+	 *		srb = nil;
+	 *		if(count > 0){
+	 *			srb = issue next srb;
+	 *		}
+	 *		if(lsrb){
+	 *			sleep on lsrb and handle it
+	 *		}
+	 *	}
+	 *
+	 * On the disks I tried, this didn't help.  If anything,
+	 * it's a little slower.		-rsc
+	 */
+	data = r->data;
+	while(count > 0){
+		/*
+		 * Max is 128 sectors (64kB) because prd->count is 16 bits.
+		 */
+		max = 128;
+		n = count;
+		if(n > max)
+			n = max;
+		srb = srbrw(cmd[0]==0x28 ? SRBread : SRBwrite, drive, data, n, lba);
+		ilock(drive);
+		startsrb(drive, srb);
+		iunlock(drive);
+
+		/*
+		 * Cannot let user interrupt the DMA.
+		 */
+		while(waserror())
+			;
+		tsleep(srb, srbdone, srb, 60*1000);
+		poperror();
+		
+		if(!(srb->flag & SFdone)){
+			ilock(drive);
+			if(!(srb->flag & SFdone)){
+				/*
+				 * DMA didn't finish but we have to let go of
+				 * the data buffer.  Reset the drive to (try to) keep it
+				 * from using the buffer after we're gone.
+				 */
+				iprint("%s: i/o timeout\n", unit->name);
+				updatedrive(drive, eDevDis);
+				enabledrive(drive);
+				freesrb(srb);
+				iunlock(drive);
+				error("i/o timeout");
+			}
+			iunlock(drive);
+		}
+
+		if(srb->flag & SFerror){
+			freesrb(srb);
+			error("i/o error");
+		}
+		freesrb(srb);
+		count -= n;
+		lba += n;
+		data += n*unit->secsize;
+	}
+	r->rlen = data - (uchar*)r->data;
+	return SDok;	
+}
+
+SDifc sdmv50xxifc = {
+	"mv50xx",				/* name */
+
+	mv50pnp,			/* pnp */
+	nil,				/* legacy */
+	mv50enable,		/* enable */
+	mv50disable,		/* disable */
+
+	mv50verify,			/* verify */
+	mv50online,			/* online */
+	mv50rio,				/* rio */
+	mv50rctl,			/* rctl */
+	mv50wctl,			/* wctl */
+
+	scsibio,			/* bio */
+	nil,			/* probe */
+	mv50clear,			/* clear */
+	mv50rtopctl,			/* rtopctl */
+};
+
+/*
+ * The original driver on which this one is based came with the 
+ * following notice:
+ *
+ * Copyright 2005
+ * Coraid, Inc.
+ *
+ * This software is provided `as-is,' without any express or implied
+ * warranty.  In no event will the author be held liable for any damages
+ * arising from the use of this software.
+ * 
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ * 
+ * 1.  The origin of this software must not be misrepresented; you must
+ * not claim that you wrote the original software.  If you use this
+ * software in a product, an acknowledgment in the product documentation
+ * would be appreciated but is not required.
+ * 
+ * 2.  Altered source versions must be plainly marked as such, and must
+ * not be misrepresented as being the original software.
+ * 
+ * 3.  This notice may not be removed or altered from any source
+ * distribution.
+ */

+ 1 - 7
sys/src/9/pc/sdmylex.c

@@ -1012,6 +1012,7 @@ buggery:
 		goto buggery;
 		goto buggery;
 	sdev->ifc = &sdmylexifc;
 	sdev->ifc = &sdmylexifc;
 	sdev->ctlr = ctlr;
 	sdev->ctlr = ctlr;
+	sdev->idno = '0';
 	ctlr->sdev = sdev;
 	ctlr->sdev = sdev;
 	if(!ctlr->wide)
 	if(!ctlr->wide)
 		sdev->nunit = 8;
 		sdev->nunit = 8;
@@ -1089,12 +1090,6 @@ mylexpnp(void)
 	return head;
 	return head;
 }
 }
 
 
-static SDev*
-mylexid(SDev* sdev)
-{
-	return scsiid(sdev, &sdmylexifc);
-}
-
 static int
 static int
 mylex24enable(Ctlr* ctlr)
 mylex24enable(Ctlr* ctlr)
 {
 {
@@ -1232,7 +1227,6 @@ SDifc sdmylexifc = {
 
 
 	mylexpnp,			/* pnp */
 	mylexpnp,			/* pnp */
 	nil,				/* legacy */
 	nil,				/* legacy */
-	mylexid,			/* id */
 	mylexenable,			/* enable */
 	mylexenable,			/* enable */
 	nil,				/* disable */
 	nil,				/* disable */
 
 

+ 0 - 20
sys/src/9/pc/sdscsi.c

@@ -372,23 +372,3 @@ again:
 	return rlen;
 	return rlen;
 }
 }
 
 
-SDev*
-scsiid(SDev* sdev, SDifc* ifc)
-{
-	char name[32];
-	static char idno[16] = "0123456789abcdef";
-	static char *p = idno;
-
-	while(sdev){
-		if(sdev->ifc == ifc){
-			sdev->idno = *p++;
-			snprint(name, sizeof(name), "sd%c", sdev->idno);
-			kstrdup(&sdev->name, name);
-			if(p >= &idno[sizeof(idno)])
-				break;
-		}
-		sdev = sdev->next;
-	}
-
-	return nil;
-}

+ 39 - 10
sys/src/9/pc/trap.c

@@ -9,6 +9,8 @@
 #include	"../port/error.h"
 #include	"../port/error.h"
 #include	<trace.h>
 #include	<trace.h>
 
 
+static int trapinited;
+
 void	noted(Ureg*, ulong);
 void	noted(Ureg*, ulong);
 
 
 static void debugbpt(Ureg*, void*);
 static void debugbpt(Ureg*, void*);
@@ -175,8 +177,13 @@ nmienable(void)
 	outb(0x61, x);
 	outb(0x61, x);
 }
 }
 
 
+/*
+ * Minimal trap setup.  Just enough so that we can panic
+ * on traps (bugs) during kernel initialization.  
+ * Called very early - malloc is not yet available.
+ */
 void
 void
-trapinit(void)
+trapinit0(void)
 {
 {
 	int d1, v;
 	int d1, v;
 	ulong vaddr;
 	ulong vaddr;
@@ -204,7 +211,11 @@ trapinit(void)
 		idt[v].d1 = d1;
 		idt[v].d1 = d1;
 		vaddr += 6;
 		vaddr += 6;
 	}
 	}
+}
 
 
+void
+trapinit(void)
+{
 	/*
 	/*
 	 * Special traps.
 	 * Special traps.
 	 * Syscall() is called directly without going through trap().
 	 * Syscall() is called directly without going through trap().
@@ -216,6 +227,7 @@ trapinit(void)
 	nmienable();
 	nmienable();
 
 
 	addarchfile("irqalloc", 0444, irqallocread, nil);
 	addarchfile("irqalloc", 0444, irqallocread, nil);
+	trapinited = 1;
 }
 }
 
 
 static char* excname[32] = {
 static char* excname[32] = {
@@ -306,6 +318,13 @@ trap(Ureg* ureg)
 	Vctl *ctl, *v;
 	Vctl *ctl, *v;
 	Mach *mach;
 	Mach *mach;
 
 
+	if(!trapinited){
+		/* fault386 can give a better error message */
+		if(ureg->trap == VectorPF)
+			fault386(ureg, nil);
+		panic("trap %lud: not ready", ureg->trap);
+	}
+
 	m->perf.intrts = perfticks();
 	m->perf.intrts = perfticks();
 	user = (ureg->cs & 0xFFFF) == UESEL;
 	user = (ureg->cs & 0xFFFF) == UESEL;
 	if(user){
 	if(user){
@@ -507,7 +526,7 @@ _dumpstack(Ureg *ureg)
 	iprint("dumpstack\n");
 	iprint("dumpstack\n");
 
 
 	x = 0;
 	x = 0;
-	x += print("ktrace /kernel/path %.8lux %.8lux\n", ureg->pc, ureg->sp);
+	x += print("ktrace /kernel/path %.8lux %.8lux <<EOF\n", ureg->pc, ureg->sp);
 	i = 0;
 	i = 0;
 	if(up
 	if(up
 	&& (ulong)&l >= (ulong)up->kstack
 	&& (ulong)&l >= (ulong)up->kstack
@@ -522,7 +541,7 @@ _dumpstack(Ureg *ureg)
 
 
 	for(l=(ulong)&l; l<estack; l+=4){
 	for(l=(ulong)&l; l<estack; l+=4){
 		v = *(ulong*)l;
 		v = *(ulong*)l;
-		if((KTZERO < v && v < (ulong)&etext) || estack-l<256){
+		if((KTZERO < v && v < (ulong)&etext) || estack-l<32){
 			/*
 			/*
 			 * we could Pick off general CALL (((uchar*)v)[-5] == 0xE8)
 			 * we could Pick off general CALL (((uchar*)v)[-5] == 0xE8)
 			 * and CALL indirect through AX (((uchar*)v)[-2] == 0xFF && ((uchar*)v)[-2] == 0xD0),
 			 * and CALL indirect through AX (((uchar*)v)[-2] == 0xFF && ((uchar*)v)[-2] == 0xD0),
@@ -538,6 +557,7 @@ _dumpstack(Ureg *ureg)
 	}
 	}
 	if(i)
 	if(i)
 		print("\n");
 		print("\n");
+	print("EOF\n");
 }
 }
 
 
 void
 void
@@ -571,8 +591,6 @@ unexpected(Ureg* ureg, void*)
 	print("unexpected trap %lud; ignoring\n", ureg->trap);
 	print("unexpected trap %lud; ignoring\n", ureg->trap);
 }
 }
 
 
-extern void checkpages(void);
-
 static void
 static void
 fault386(Ureg* ureg, void*)
 fault386(Ureg* ureg, void*)
 {
 {
@@ -581,12 +599,20 @@ fault386(Ureg* ureg, void*)
 	char buf[ERRMAX];
 	char buf[ERRMAX];
 
 
 	addr = getcr2();
 	addr = getcr2();
-	user = (ureg->cs & 0xFFFF) == UESEL;
-	if(!user && mmukmapsync(addr))
-		return;
 	read = !(ureg->ecode & 2);
 	read = !(ureg->ecode & 2);
+
+	user = (ureg->cs & 0xFFFF) == UESEL;
+	if(!user){
+		if(vmapsync(addr))
+			return;
+		if(addr >= USTKTOP)
+			panic("kernel fault: bad address pc=0x%.8lux addr=0x%.8lux", ureg->pc, addr);
+		if(up == nil)
+			panic("kernel fault: no user process pc=0x%.8lux addr=0x%.8lux", ureg->pc, addr);
+	}
 	if(up == nil)
 	if(up == nil)
-		panic("fault but up is zero; pc 0x%8.8lux addr 0x%8.8lux\n", ureg->pc, addr);
+		panic("user fault: up=0 pc=0x%.8lux addr=0x%.8lux", ureg->pc, addr);
+
 	insyscall = up->insyscall;
 	insyscall = up->insyscall;
 	up->insyscall = 1;
 	up->insyscall = 1;
 	n = fault(addr, read);
 	n = fault(addr, read);
@@ -597,7 +623,7 @@ fault386(Ureg* ureg, void*)
 		}
 		}
 		checkpages();
 		checkpages();
 		sprint(buf, "sys: trap: fault %s addr=0x%lux",
 		sprint(buf, "sys: trap: fault %s addr=0x%lux",
-			read? "read" : "write", addr);
+			read ? "read" : "write", addr);
 		postnote(up, 1, buf, NDebug);
 		postnote(up, 1, buf, NDebug);
 	}
 	}
 	up->insyscall = insyscall;
 	up->insyscall = insyscall;
@@ -888,6 +914,9 @@ execregs(ulong entry, ulong ssize, ulong nargs)
 	ulong *sp;
 	ulong *sp;
 	Ureg *ureg;
 	Ureg *ureg;
 
 
+	up->fpstate = FPinit;
+	fpoff();
+
 	sp = (ulong*)(USTKTOP - ssize);
 	sp = (ulong*)(USTKTOP - ssize);
 	*--sp = nargs;
 	*--sp = nargs;
 
 

+ 12 - 3
sys/src/9/pc/vga.c

@@ -3,6 +3,7 @@
 #include "mem.h"
 #include "mem.h"
 #include "dat.h"
 #include "dat.h"
 #include "fns.h"
 #include "fns.h"
+#include "io.h"
 #include "../port/error.h"
 #include "../port/error.h"
 
 
 #define	Image	IMAGE
 #define	Image	IMAGE
@@ -18,7 +19,7 @@ static Point curpos;
 static Rectangle window;
 static Rectangle window;
 static int *xp;
 static int *xp;
 static int xbuf[256];
 static int xbuf[256];
-static Lock vgascreenlock;
+Lock vgascreenlock;
 int drawdebug;
 int drawdebug;
 
 
 void
 void
@@ -136,7 +137,7 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
 static void
 static void
 vgascreenputs(char* s, int n)
 vgascreenputs(char* s, int n)
 {
 {
-	int i;
+	int i, gotdraw;
 	Rune r;
 	Rune r;
 	char buf[4];
 	char buf[4];
 	VGAscr *scr;
 	VGAscr *scr;
@@ -155,6 +156,12 @@ vgascreenputs(char* s, int n)
 	else
 	else
 		lock(&vgascreenlock);
 		lock(&vgascreenlock);
 
 
+	/*
+	 * Be nice to hold this, but not going to deadlock
+	 * waiting for it.  Just try and see.
+	 */
+	gotdraw = canqlock(&drawlock);
+
 	flushr = Rect(10000, 10000, -10000, -10000);
 	flushr = Rect(10000, 10000, -10000, -10000);
 
 
 	while(n > 0){
 	while(n > 0){
@@ -172,6 +179,8 @@ vgascreenputs(char* s, int n)
 	}
 	}
 	flushmemscreen(flushr);
 	flushmemscreen(flushr);
 
 
+	if(gotdraw)
+		qunlock(&drawlock);
 	unlock(&vgascreenlock);
 	unlock(&vgascreenlock);
 }
 }
 
 
@@ -241,7 +250,7 @@ cornerstring(char *s)
 	Point p;
 	Point p;
 
 
 	scr = &vgascreen[0];
 	scr = &vgascreen[0];
-	if(scr->aperture == 0 || screenputs != vgascreenputs)
+	if(scr->vaddr == nil || screenputs != vgascreenputs)
 		return;
 		return;
 	p = memsubfontwidth(scr->memdefont, s);
 	p = memsubfontwidth(scr->memdefont, s);
 	w = p.x;
 	w = p.x;

+ 23 - 80
sys/src/9/pc/vga3dfx.c

@@ -28,66 +28,13 @@ enum {
 	hwCur		= 0x5C,
 	hwCur		= 0x5C,
 };
 };
 
 
-static ulong
-tdfxlinear(VGAscr* scr, int* size, int* align)
-{
-	Pcidev *p;
-	int oapsize, wasupamem;
-	ulong aperture, oaperture;
-
-	oaperture = scr->aperture;
-	oapsize = scr->apsize;
-	wasupamem = scr->isupamem;
-
-	aperture = 0;
-	if(p = pcimatch(nil, 0x121A, 0)){
-		switch(p->did){
-		case 0x0003:		/* Banshee */
-		case 0x0005:		/* Avenger (a.k.a. Voodoo3) */
-		case 0x0009:		/* Voodoo5 */
-			aperture = p->mem[1].bar & ~0x0F;
-			*size = p->mem[1].size;
-			break;
-		default:
-			break;
-		}
-	}
-
-	if(wasupamem){
-		if(oaperture == aperture)
-			return oaperture;
-		upafree(oaperture, oapsize);
-	}
-	scr->isupamem = 0;
-
-	aperture = upamalloc(aperture, *size, *align);
-	if(aperture == 0){
-		if(wasupamem && upamalloc(oaperture, oapsize, 0)){
-			aperture = oaperture;
-			scr->isupamem = 1;
-		}
-		else
-			scr->isupamem = 0;
-	}
-	else
-		scr->isupamem = 1;
-
-	return aperture;
-}
-
 static void
 static void
 tdfxenable(VGAscr* scr)
 tdfxenable(VGAscr* scr)
 {
 {
 	Pcidev *p;
 	Pcidev *p;
-	ulong aperture;
-	int align, i, *mmio, size;
+	int i, *mmio;
 
 
-	/*
-	 * Only once, can't be disabled for now.
-	 * scr->io holds the physical address of
-	 * the MMIO registers.
-	 */
-	if(scr->io)
+	if(scr->mmio)
 		return;
 		return;
 	if(p = pcimatch(nil, 0x121A, 0)){
 	if(p = pcimatch(nil, 0x121A, 0)){
 		switch(p->did){
 		switch(p->did){
@@ -100,20 +47,16 @@ tdfxenable(VGAscr* scr)
 	}
 	}
 	else
 	else
 		return;
 		return;
-	scr->io = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
-	if(scr->io == 0)
+	
+	scr->mmio = vmap(p->mem[0].bar&~0x0F, p->mem[0].size);
+	if(scr->mmio == nil)
 		return;
 		return;
-
-	addvgaseg("3dfxmmio", (ulong)scr->io, p->mem[0].size);
-
-	size = p->mem[1].size;
-	align = 0;
-	aperture = tdfxlinear(scr, &size, &align);
-	if(aperture){
-		scr->aperture = aperture;
-		scr->apsize = size;
-		addvgaseg("3dfxscreen", aperture, size);
-	}
+	scr->pci = p;
+	
+	addvgaseg("3dfxmmio", p->mem[0].bar&~0x0F, p->mem[0].size);
+	vgalinearpci(scr);
+	if(scr->apsize)
+		addvgaseg("3dfxscreen", scr->paddr, scr->apsize);
 
 
 	/*
 	/*
 	 * Find a place for the cursor data in display memory.
 	 * Find a place for the cursor data in display memory.
@@ -123,7 +66,7 @@ tdfxenable(VGAscr* scr)
 	 * 8 of them.
 	 * 8 of them.
 	 * Use the last 1KB of the framebuffer.
 	 * Use the last 1KB of the framebuffer.
 	 */
 	 */
-	mmio = KADDR(scr->io + dramInit0);
+	mmio = (void*)((uchar*)scr->mmio+dramInit0);
 	if(*(mmio+1) & 0x40000000)
 	if(*(mmio+1) & 0x40000000)
 		i = 16*1024*1024;
 		i = 16*1024*1024;
 	else{
 	else{
@@ -144,9 +87,9 @@ tdfxcurdisable(VGAscr* scr)
 {
 {
 	Cursor3dfx *cursor3dfx;
 	Cursor3dfx *cursor3dfx;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
-	cursor3dfx = KADDR(scr->io+hwCur);
+	cursor3dfx = (void*)((uchar*)scr->mmio+hwCur);
 	cursor3dfx->vidProcCfg &= ~0x08000000;
 	cursor3dfx->vidProcCfg &= ~0x08000000;
 }
 }
 
 
@@ -157,9 +100,9 @@ tdfxcurload(VGAscr* scr, Cursor* curs)
 	uchar *p;
 	uchar *p;
 	Cursor3dfx *cursor3dfx;
 	Cursor3dfx *cursor3dfx;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
-	cursor3dfx = KADDR(scr->io+hwCur);
+	cursor3dfx = (void*)((uchar*)scr->mmio+hwCur);
 
 
 	/*
 	/*
 	 * Disable the cursor then load the new image in
 	 * Disable the cursor then load the new image in
@@ -177,7 +120,7 @@ tdfxcurload(VGAscr* scr, Cursor* curs)
 	 * transparent.
 	 * transparent.
 	 */
 	 */
 	cursor3dfx->vidProcCfg &= ~0x08000000;
 	cursor3dfx->vidProcCfg &= ~0x08000000;
-	p = KADDR(scr->aperture + scr->storage);
+	p = (uchar*)scr->vaddr + scr->storage;
 	for(y = 0; y < 16; y++){
 	for(y = 0; y < 16; y++){
 		*p++ = curs->clr[2*y]|curs->set[2*y];
 		*p++ = curs->clr[2*y]|curs->set[2*y];
 		*p++ = curs->clr[2*y+1]|curs->set[2*y+1];
 		*p++ = curs->clr[2*y+1]|curs->set[2*y+1];
@@ -201,9 +144,9 @@ tdfxcurmove(VGAscr* scr, Point p)
 {
 {
 	Cursor3dfx *cursor3dfx;
 	Cursor3dfx *cursor3dfx;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return 1;
 		return 1;
-	cursor3dfx = KADDR(scr->io+hwCur);
+	cursor3dfx = (void*)((uchar*)scr->mmio+hwCur);
 
 
 	cursor3dfx->hwCurLoc = ((p.y+scr->offset.y)<<16)|(p.x+scr->offset.x);
 	cursor3dfx->hwCurLoc = ((p.y+scr->offset.y)<<16)|(p.x+scr->offset.x);
 
 
@@ -216,9 +159,9 @@ tdfxcurenable(VGAscr* scr)
 	Cursor3dfx *cursor3dfx;
 	Cursor3dfx *cursor3dfx;
 
 
 	tdfxenable(scr);
 	tdfxenable(scr);
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
-	cursor3dfx = KADDR(scr->io+hwCur);
+	cursor3dfx = (void*)((uchar*)scr->mmio+hwCur);
 
 
 	/*
 	/*
 	 * Cursor colours.
 	 * Cursor colours.
@@ -230,7 +173,7 @@ tdfxcurenable(VGAscr* scr)
 	 * Initialise the 64x64 cursor to be transparent (X11 mode).
 	 * Initialise the 64x64 cursor to be transparent (X11 mode).
 	 */
 	 */
 	cursor3dfx->hwCurPatAddr = scr->storage;
 	cursor3dfx->hwCurPatAddr = scr->storage;
-	memset(KADDR(scr->aperture + scr->storage), 0, 64*16);
+	memset((uchar*)scr->vaddr + scr->storage, 0, 64*16);
 
 
 	/*
 	/*
 	 * Load, locate and enable the 64x64 cursor in X11 mode.
 	 * Load, locate and enable the 64x64 cursor in X11 mode.
@@ -246,7 +189,7 @@ VGAdev vga3dfxdev = {
 	tdfxenable,
 	tdfxenable,
 	nil,
 	nil,
 	nil,
 	nil,
-	tdfxlinear,
+	nil,
 };
 };
 
 
 VGAcur vga3dfxcur = {
 VGAcur vga3dfxcur = {

+ 2 - 1
sys/src/9/pc/vgaark2000pv.c

@@ -3,6 +3,7 @@
 #include "mem.h"
 #include "mem.h"
 #include "dat.h"
 #include "dat.h"
 #include "fns.h"
 #include "fns.h"
+#include "io.h"
 #include "../port/error.h"
 #include "../port/error.h"
 
 
 #define	Image	IMAGE
 #define	Image	IMAGE
@@ -90,7 +91,7 @@ ark2000pvload(VGAscr* scr, Cursor* curs)
 	 */
 	 */
 	seq10 = vgaxi(Seqx, 0x10);
 	seq10 = vgaxi(Seqx, 0x10);
 	opage = 0;
 	opage = 0;
-	p = KADDR(scr->aperture);
+	p = scr->vaddr;
 	if(!(seq10 & 0x10)){
 	if(!(seq10 & 0x10)){
 		lock(&scr->devlock);
 		lock(&scr->devlock);
 		opage = ark2000pvpageset(scr, scr->storage>>16);
 		opage = ark2000pvpageset(scr, scr->storage>>16);

+ 1 - 0
sys/src/9/pc/vgabt485.c

@@ -3,6 +3,7 @@
 #include "mem.h"
 #include "mem.h"
 #include "dat.h"
 #include "dat.h"
 #include "fns.h"
 #include "fns.h"
+#include "io.h"
 #include "../port/error.h"
 #include "../port/error.h"
 
 
 #define	Image	IMAGE
 #define	Image	IMAGE

+ 4 - 30
sys/src/9/pc/vgaclgd542x.c

@@ -41,36 +41,10 @@ clgd542xpage(VGAscr* scr, int page)
 	unlock(&scr->devlock);
 	unlock(&scr->devlock);
 }
 }
 
 
-static ulong
-clgd542xlinear(VGAscr* scr, int* size, int* align)
+static void
+clgd542xlinear(VGAscr* scr, int, int)
 {
 {
-	ulong aperture, oaperture;
-	int oapsize, wasupamem;
-	Pcidev *p;
-
-	oaperture = scr->aperture;
-	oapsize = scr->apsize;
-	wasupamem = scr->isupamem;
-	if(wasupamem)
-		upafree(oaperture, oapsize);
-	scr->isupamem = 0;
-
-	if(p = pcimatch(nil, 0x1013, 0)){
-		aperture = p->mem[0].bar & ~0x0F;
-		*size = p->mem[0].size;
-	}
-	else
-		aperture = 0;
-
-	aperture = upamalloc(aperture, *size, *align);
-	if(aperture == 0){
-		if(wasupamem && upamalloc(oaperture, oapsize, 0))
-			scr->isupamem = 1;
-	}
-	else
-		scr->isupamem = 1;
-
-	return aperture;
+	vgalinearpciid(scr, 0x1013, 0);
 }
 }
 
 
 static void
 static void
@@ -171,7 +145,7 @@ clgd542xinitcursor(VGAscr* scr, int xo, int yo, int index)
 	 */
 	 */
 	seq07 = vgaxi(Seqx, 0x07);
 	seq07 = vgaxi(Seqx, 0x07);
 	opage = 0;
 	opage = 0;
-	p = KADDR(scr->aperture);
+	p = scr->vaddr;
 	if(!(seq07 & 0xF0)){
 	if(!(seq07 & 0xF0)){
 		lock(&scr->devlock);
 		lock(&scr->devlock);
 		opage = clgd542xpageset(scr, scr->storage>>16);
 		opage = clgd542xpageset(scr, scr->storage>>16);

+ 29 - 87
sys/src/9/pc/vgaclgd546x.c

@@ -26,93 +26,35 @@ enum {
 	CursorMMIO	= 0xE0,
 	CursorMMIO	= 0xE0,
 };
 };
 
 
-static ulong
-clgd546xlinear(VGAscr* scr, int* size, int* align)
+static void
+clgd546xlinear(VGAscr* scr, int, int)
 {
 {
-	ulong aperture, oaperture;
-	int oapsize, wasupamem;
-	Pcidev *p;
-
-	oaperture = scr->aperture;
-	oapsize = scr->apsize;
-	wasupamem = scr->isupamem;
-
-	aperture = 0;
-	if(p = pcimatch(nil, 0x1013, 0)){
-		switch(p->did){
-		case 0xD0:
-		case 0xD4:
-		case 0xD6:
-			aperture = p->mem[0].bar & ~0x0F;
-			*size = p->mem[0].size;
-			break;
-		default:
-			break;
-		}
-	}
-
-	if(wasupamem){
-		if(oaperture == aperture)
-			return oaperture;
-		upafree(oaperture, oapsize);
-	}
-	scr->isupamem = 0;
-
-	aperture = upamalloc(aperture, *size, *align);
-	if(aperture == 0){
-		if(wasupamem && upamalloc(oaperture, oapsize, 0)){
-			aperture = oaperture;
-			scr->isupamem = 1;
-		}
-		else
-			scr->isupamem = 0;
-	}
-	else
-		scr->isupamem = 1;
-
-	return aperture;
+	vgalinearpci(scr);
 }
 }
+
 static void
 static void
 clgd546xenable(VGAscr* scr)
 clgd546xenable(VGAscr* scr)
 {
 {
 	Pcidev *p;
 	Pcidev *p;
-	int size, align;
-	ulong aperture;
 
 
-	/*
-	 * Only once, can't be disabled for now.
-	 * scr->io holds the virtual address of
-	 * the MMIO registers.
-	 */
-	if(scr->io)
+	if(scr->mmio)
 		return;
 		return;
-	if(p = pcimatch(nil, 0x1013, 0)){
-		switch(p->did){
-		case 0xD0:
-		case 0xD4:
-		case 0xD6:
-			break;
-		default:
-			return;
-		}
-	}
-	else
+	if((p = pcimatch(nil, 0x1013, 0)) == nil)
 		return;
 		return;
-	scr->io = upamalloc(p->mem[1].bar & ~0x0F, p->mem[1].size, 0);
-	if(scr->io == 0)
+	switch(p->did){
+	case 0xD0:
+	case 0xD4:
+	case 0xD6:
+		break;
+	default:
 		return;
 		return;
-	addvgaseg("clgd546xmmio", scr->io, p->mem[1].size);
-
-	scr->io = (ulong)KADDR(scr->io);
-
-	size = p->mem[0].size;
-	align = 0;
-	aperture = clgd546xlinear(scr, &size, &align);
-	if(aperture) {
-		scr->aperture = aperture;
-		scr->apsize = size;
-		addvgaseg("clgd546xscreen", aperture, size);
 	}
 	}
+
+	scr->pci = p;
+	scr->mmio = vmap(p->mem[1].bar&~0x0F, p->mem[1].size);
+	if(scr->mmio == 0)
+		return;
+	addvgaseg("clgd546xmmio", p->mem[1].bar&~0x0F, p->mem[1].size);
 }
 }
 
 
 static void
 static void
@@ -120,9 +62,9 @@ clgd546xcurdisable(VGAscr* scr)
 {
 {
 	Cursor546x *cursor546x;
 	Cursor546x *cursor546x;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
-	cursor546x = (Cursor546x*)(scr->io+CursorMMIO);
+	cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
 	cursor546x->enable = 0;
 	cursor546x->enable = 0;
 }
 }
 
 
@@ -133,16 +75,16 @@ clgd546xcurload(VGAscr* scr, Cursor* curs)
 	uchar *p;
 	uchar *p;
 	Cursor546x *cursor546x;
 	Cursor546x *cursor546x;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
-	cursor546x = (Cursor546x*)(scr->io+CursorMMIO);
+	cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
 
 
 	/*
 	/*
 	 * Disable the cursor then change only the bits
 	 * Disable the cursor then change only the bits
 	 * that need it.
 	 * that need it.
 	 */
 	 */
 	cursor546x->enable = 0;
 	cursor546x->enable = 0;
-	p = (uchar*)(scr->aperture + scr->storage);
+	p = (uchar*)scr->vaddr + scr->storage;
 	for(y = 0; y < 16; y++){
 	for(y = 0; y < 16; y++){
 		c = curs->set[2*y];
 		c = curs->set[2*y];
 		m = 0;
 		m = 0;
@@ -189,9 +131,9 @@ clgd546xcurmove(VGAscr* scr, Point p)
 	int x, xo, y, yo;
 	int x, xo, y, yo;
 	Cursor546x *cursor546x;
 	Cursor546x *cursor546x;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return 1;
 		return 1;
-	cursor546x = (Cursor546x*)(scr->io+CursorMMIO);
+	cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
 
 
 	if((x = p.x+scr->offset.x) < 0){
 	if((x = p.x+scr->offset.x) < 0){
 		xo = -x;
 		xo = -x;
@@ -220,15 +162,15 @@ clgd546xcurenable(VGAscr* scr)
 	Cursor546x *cursor546x;
 	Cursor546x *cursor546x;
 
 
 	clgd546xenable(scr);
 	clgd546xenable(scr);
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
-	cursor546x = (Cursor546x*)(scr->io+CursorMMIO);
+	cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
 
 
 	/*
 	/*
 	 * Cursor colours.
 	 * Cursor colours.
 	 * Can't call setcolor here as cursor is already locked.
 	 * Can't call setcolor here as cursor is already locked.
 	 */
 	 */
-	p = (uchar*)(scr->io+PaletteState);
+	p = (uchar*)scr->mmio+PaletteState;
 	*p |= 0x08;
 	*p |= 0x08;
 	vgao(PaddrW, 0x00);
 	vgao(PaddrW, 0x00);
 	vgao(Pdata, Pwhite);
 	vgao(Pdata, Pwhite);
@@ -248,7 +190,7 @@ clgd546xcurenable(VGAscr* scr)
 	 */
 	 */
 	scr->storage = ((vgaxi(Seqx, 0x14) & 0x07)+1)*1024*1022;
 	scr->storage = ((vgaxi(Seqx, 0x14) & 0x07)+1)*1024*1022;
 	cursor546x->addr = (scr->storage>>10)<<2;
 	cursor546x->addr = (scr->storage>>10)<<2;
-	memset((uchar*)(scr->aperture + scr->storage), 0, 2*64*16);
+	memset((uchar*)scr->vaddr + scr->storage, 0, 2*64*16);
 
 
 	/*
 	/*
 	 * Load, locate and enable the 64x64 cursor.
 	 * Load, locate and enable the 64x64 cursor.

+ 2 - 1
sys/src/9/pc/vgact65545.c

@@ -3,6 +3,7 @@
 #include "mem.h"
 #include "mem.h"
 #include "dat.h"
 #include "dat.h"
 #include "fns.h"
 #include "fns.h"
+#include "io.h"
 #include "../port/error.h"
 #include "../port/error.h"
 
 
 #define	Image	IMAGE
 #define	Image	IMAGE
@@ -52,7 +53,7 @@ ct65545initcursor(VGAscr* scr, int xo, int yo, int index)
 	uint and, clr, set, xor;
 	uint and, clr, set, xor;
 	int i, x, y;
 	int i, x, y;
 
 
-	mem = KADDR(scr->aperture);
+	mem = scr->vaddr;
 	mem += scr->storage + index*1024;
 	mem += scr->storage + index*1024;
 
 
 	for(y = yo; y < 16; y++){
 	for(y = yo; y < 16; y++){

+ 17 - 39
sys/src/9/pc/vgacyber938x.c

@@ -38,50 +38,28 @@ cyber938xpage(VGAscr* scr, int page)
 	unlock(&scr->devlock);
 	unlock(&scr->devlock);
 }
 }
 
 
-static ulong
-cyber938xlinear(VGAscr* scr, int* size, int* align)
+static void
+cyber938xlinear(VGAscr* scr, int, int)
 {
 {
-	ulong aperture, oaperture;
-	int oapsize, wasupamem;
-	int osize;
 	Pcidev *p;
 	Pcidev *p;
 
 
-	osize = *size;
-	oaperture = scr->aperture;
-	oapsize = scr->apsize;
-	wasupamem = scr->isupamem;
-	if(wasupamem)
-		upafree(oaperture, oapsize);
-	scr->isupamem = 0;
-	scr->mmio = 0;
-
-	if(p = pcimatch(nil, 0x1023, 0)){
-		aperture = p->mem[0].bar & ~0x0F;
-		*size = p->mem[0].size;
-		/*
-		 * Heuristic to detect the MMIO space.  We're flying blind
-		 * here, with only the XFree86 source to guide us.
-		 */
-		if(p->mem[1].size == 0x20000)
-			scr->mmio = (ulong*)(p->mem[1].bar & ~0x0F);
-	}
-	else
-		aperture = 0;
+	if(scr->vaddr)
+		return;
+	
+	vgalinearpciid(scr, 0x1023, 0);
+	p = scr->pci;
 
 
-	aperture = upamalloc(aperture, *size, *align);
-	if(aperture == 0){
-		if(wasupamem && upamalloc(oaperture, oapsize, 0))
-			scr->isupamem = 1;
-	}
-	else
-		scr->isupamem = 1;
+	/*
+	 * Heuristic to detect the MMIO space.  We're flying blind
+	 * here, with only the XFree86 source to guide us.
+	 */
+	if(p->mem[1].size == 0x20000)
+		scr->mmio = vmap(p->mem[1].bar & ~0x0F, p->mem[1].size);
 
 
-	if(aperture)
-		addvgaseg("cyber938xscreen", aperture, osize);
+	if(scr->apsize)
+		addvgaseg("cyber938xscreen", scr->paddr, scr->apsize);
 	if(scr->mmio)
 	if(scr->mmio)
-		addvgaseg("cyber938xmmio", (ulong)scr->mmio, 0x20000);
-
-	return aperture;
+		addvgaseg("cyber938xmmio", p->mem[1].bar&~0x0F, 0x20000);
 }
 }
 
 
 static void
 static void
@@ -99,7 +77,7 @@ cyber938xcurload(VGAscr* scr, Cursor* curs)
 	cyber938xcurdisable(scr);
 	cyber938xcurdisable(scr);
 
 
 	opage = 0;
 	opage = 0;
-	p = KADDR(scr->aperture);
+	p = scr->vaddr;
 	islinear = vgaxi(Crtx, 0x21) & 0x20;
 	islinear = vgaxi(Crtx, 0x21) & 0x20;
 	if(!islinear){
 	if(!islinear){
 		lock(&scr->devlock);
 		lock(&scr->devlock);

+ 2 - 1
sys/src/9/pc/vgaet4000.c

@@ -3,6 +3,7 @@
 #include "mem.h"
 #include "mem.h"
 #include "dat.h"
 #include "dat.h"
 #include "fns.h"
 #include "fns.h"
+#include "io.h"
 #include "../port/error.h"
 #include "../port/error.h"
 
 
 #define	Image	IMAGE
 #define	Image	IMAGE
@@ -139,7 +140,7 @@ et4000load(VGAscr *scr, Cursor *c)
 	et4000disable(scr);
 	et4000disable(scr);
 
 
 	setet4000page(scr->storage>>16);
 	setet4000page(scr->storage>>16);
-	mem = (uchar*)KADDR(scr->aperture) + (scr->storage & 0xFFFF);
+	mem = (uchar*)scr->vaddr + (scr->storage & 0xFFFF);
 
 
 	/*
 	/*
 	 * Initialise the 64x64 cursor RAM array. There are 2 planes,
 	 * Initialise the 64x64 cursor RAM array. There are 2 planes,

+ 15 - 61
sys/src/9/pc/vgahiqvideo.c

@@ -34,65 +34,21 @@ hiqvideoxo(long port, uchar index, uchar data)
 	outb(port+1, data);
 	outb(port+1, data);
 }
 }
 
 
-static ulong
-hiqvideolinear(VGAscr* scr, int* size, int* align)
+static void
+hiqvideolinear(VGAscr*, int, int)
 {
 {
-	ulong aperture, oaperture;
-	int oapsize, wasupamem;
-	Pcidev *p;
-
-	oaperture = scr->aperture;
-	oapsize = scr->apsize;
-	wasupamem = scr->isupamem;
-
-	aperture = 0;
-	if(p = pcimatch(nil, 0x102C, 0)){
-		switch(p->did){
-		case 0x00C0:		/* 69000 HiQVideo */
-		case 0x00E0:		/* 65550 HiQV32 */
-		case 0x00E4:		/* 65554 HiQV32 */
-		case 0x00E5:		/* 65555 HiQV32 */
-			aperture = p->mem[0].bar & ~0x0F;
-			*size = p->mem[0].size;
-			break;
-		default:
-			break;
-		}
-	}
-
-	if(wasupamem){
-		if(oaperture == aperture)
-			return oaperture;
-		upafree(oaperture, oapsize);
-	}
-	scr->isupamem = 0;
-
-	aperture = upamalloc(aperture, *size, *align);
-	if(aperture == 0){
-		if(wasupamem && upamalloc(oaperture, oapsize, 0)){
-			aperture = oaperture;
-			scr->isupamem = 1;
-		}
-		else
-			scr->isupamem = 0;
-	}
-	else
-		scr->isupamem = 1;
-
-	return aperture;
 }
 }
 
 
 static void
 static void
 hiqvideoenable(VGAscr* scr)
 hiqvideoenable(VGAscr* scr)
 {
 {
 	Pcidev *p;
 	Pcidev *p;
-	int align, size, vmsize;
-	ulong aperture;
+	int vmsize;
 
 
 	/*
 	/*
 	 * Only once, can't be disabled for now.
 	 * Only once, can't be disabled for now.
 	 */
 	 */
-	if(scr->io)
+	if(scr->mmio)
 		return;
 		return;
 	if(p = pcimatch(nil, 0x102C, 0)){
 	if(p = pcimatch(nil, 0x102C, 0)){
 		switch(p->did){
 		switch(p->did){
@@ -119,23 +75,21 @@ hiqvideoenable(VGAscr* scr)
 	else
 	else
 		return;
 		return;
 
 
-	size = p->mem[0].size;
-	align = 0;
-	aperture = hiqvideolinear(scr, &size, &align);
-	if(aperture) {
-		scr->aperture = aperture;
-		scr->apsize = size;
-		addvgaseg("hiqvideoscreen", aperture, size);
+	scr->pci = p;
+	vgalinearpci(scr);
+	
+	if(scr->paddr) {
+		addvgaseg("hiqvideoscreen", scr->paddr, scr->apsize);
 	}
 	}
 
 
 	/*
 	/*
 	 * Find a place for the cursor data in display memory.
 	 * Find a place for the cursor data in display memory.
 	 * Must be on a 4096-byte boundary.
 	 * Must be on a 4096-byte boundary.
-	 * scr->io holds the physical address of the cursor
+	 * scr->mmio holds the virtual address of the cursor
 	 * storage area in the framebuffer region.
 	 * storage area in the framebuffer region.
 	 */
 	 */
 	scr->storage = vmsize-4096;
 	scr->storage = vmsize-4096;
-	scr->io = scr->aperture+scr->storage;
+	scr->mmio = (ulong*)((uchar*)scr->vaddr+scr->storage);
 }
 }
 
 
 static void
 static void
@@ -155,9 +109,9 @@ hiqvideocurload(VGAscr* scr, Cursor* curs)
 	 */
 	 */
 	hiqvideocurdisable(scr);
 	hiqvideocurdisable(scr);
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
-	p = KADDR(scr->io);
+	p = (uchar*)scr->mmio;
 
 
 	for(y = 0; y < 16; y += 2){
 	for(y = 0; y < 16; y += 2){
 		*p++ = ~(curs->clr[2*y]|curs->set[2*y]);
 		*p++ = ~(curs->clr[2*y]|curs->set[2*y]);
@@ -197,7 +151,7 @@ hiqvideocurmove(VGAscr* scr, Point p)
 {
 {
 	int x, y;
 	int x, y;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return 1;
 		return 1;
 
 
 	if((x = p.x+scr->offset.x) < 0)
 	if((x = p.x+scr->offset.x) < 0)
@@ -219,7 +173,7 @@ hiqvideocurenable(VGAscr* scr)
 	uchar xr80;
 	uchar xr80;
 
 
 	hiqvideoenable(scr);
 	hiqvideoenable(scr);
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
 
 
 	/*
 	/*

+ 38 - 88
sys/src/9/pc/vgai81x.c

@@ -49,94 +49,44 @@ i81xpcimatch(void)
 	return nil;
 	return nil;
 }
 }
 
 
-static ulong
-i81xlinear(VGAscr* scr, int* size, int* align)
-{
-	Pcidev *p;
-	int oapsize, wasupamem;
-	ulong aperture, oaperture, fbuf, fbend, *rp;
-
-	oaperture = scr->aperture;
-	oapsize = scr->apsize;
-	wasupamem = scr->isupamem;
-
-	aperture = 0;
-	p = i81xpcimatch();
-	if(p != nil) {
-		aperture = p->mem[0].bar & ~0x0F;
-		*size = p->mem[0].size;
-		if(*size > Fbsize)
-			*size = Fbsize;
-	}
-
-	if(wasupamem){
-		if(oaperture == aperture)
-			return oaperture;
-		upafree(oaperture, oapsize);
-	}
-	scr->isupamem = 0;
-
-	aperture = upamalloc(aperture, *size, *align);
-	if(aperture == 0){
-		if(wasupamem && upamalloc(oaperture, oapsize, 0)){
-			aperture = oaperture;
-			scr->isupamem = 1;
-		}
-		else
-			scr->isupamem = 0;
-	}
-	else
-		scr->isupamem = 1;
-
-	/* allocate space for frame buffer, populate page table */
-	if(oapsize == 0) {
-		fbuf = PADDR(xspanalloc(*size, BY2PG, 0));
-		fbend = PGROUND(fbuf+*size);
-		rp = KADDR(scr->io+0x10000);
-		while(fbuf < fbend) {
-			*rp++ = fbuf | (1<<0);
-			fbuf += BY2PG;
-		}
-	}
-	return aperture;
-}
-
 static void
 static void
 i81xenable(VGAscr* scr)
 i81xenable(VGAscr* scr)
 {
 {
 	Pcidev *p;
 	Pcidev *p;
-	int align, size;
+	int size;
 	Mach *mach0;
 	Mach *mach0;
-	ulong aperture, pgtbl, *rp, cursor, *pte;
-
-	/*
-	 * Only once, can't be disabled for now.
-	 * scr->io holds the physical address of
-	 * the MMIO registers.
-	 */
-	if(scr->io)
+	ulong *pgtbl, *rp, cursor, *pte, fbuf, fbend;
+	
+	if(scr->mmio)
 		return;
 		return;
 	p = i81xpcimatch();
 	p = i81xpcimatch();
 	if(p == nil)
 	if(p == nil)
 		return;
 		return;
-	scr->io = upamalloc(p->mem[1].bar & ~0x0F, p->mem[1].size, 0);
-	if(scr->io == 0)
+	scr->mmio = vmap(p->mem[1].bar & ~0x0F, p->mem[1].size);
+	if(scr->mmio == 0)
 		return;
 		return;
+	addvgaseg("i81xmmio", p->mem[1].bar&~0x0F, p->mem[1].size);
 
 
 	/* allocate page table */
 	/* allocate page table */
-	pgtbl = PADDR(xspanalloc(64*1024, BY2PG, 0));
-	rp = KADDR(scr->io+0x2020);
-	*rp = pgtbl | 1;
-
-	addvgaseg("i81xmmio", (ulong)scr->io, p->mem[0].size);
+	pgtbl = xspanalloc(64*1024, BY2PG, 0);
+	scr->mmio[0x2020/4] = PADDR(pgtbl) | 1;
 
 
 	size = p->mem[0].size;
 	size = p->mem[0].size;
-	align = 0;
-	aperture = i81xlinear(scr, &size, &align);
-	if(aperture){
-		scr->aperture = aperture;
-		scr->apsize = size;
-		addvgaseg("i81xscreen", aperture, size);
+	if(size > 0)
+		size = Fbsize;
+	vgalinearaddr(scr, p->mem[0].bar&~0xF, size);
+	addvgaseg("i81xscreen", p->mem[0].bar&~0xF, size);
+
+	/*
+	 * allocate backing store for frame buffer
+	 * and populate device page tables.
+	 */
+	fbuf = PADDR(xspanalloc(size, BY2PG, 0));
+	fbend = PGROUND(fbuf+size);
+	rp = scr->mmio+0x10000/4;
+	while(fbuf < fbend) {
+		*rp++ = fbuf | 1;
+		fbuf += BY2PG;
 	}
 	}
 
 
 	/*
 	/*
@@ -147,9 +97,9 @@ i81xenable(VGAscr* scr)
 	mach0 = MACHP(0);
 	mach0 = MACHP(0);
 	pte = mmuwalk(mach0->pdb, cursor, 2, 0);
 	pte = mmuwalk(mach0->pdb, cursor, 2, 0);
 	if(pte == nil)
 	if(pte == nil)
-		panic("i81x cursor");
+		panic("i81x cursor mmuwalk");
 	*pte |= PTEUNCACHED;
 	*pte |= PTEUNCACHED;
-	scr->storage = PADDR(cursor);
+	scr->storage = cursor;
 }
 }
 
 
 static void
 static void
@@ -157,9 +107,9 @@ i81xcurdisable(VGAscr* scr)
 {
 {
 	CursorI81x *hwcurs;
 	CursorI81x *hwcurs;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
-	hwcurs = KADDR(scr->io+hwCur);
+	hwcurs = (void*)((uchar*)scr->mmio+hwCur);
 	hwcurs->ctl = (1<<4);
 	hwcurs->ctl = (1<<4);
 }
 }
 
 
@@ -170,9 +120,9 @@ i81xcurload(VGAscr* scr, Cursor* curs)
 	uchar *p;
 	uchar *p;
 	CursorI81x *hwcurs;
 	CursorI81x *hwcurs;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
-	hwcurs = KADDR(scr->io+hwCur);
+	hwcurs = (void*)((uchar*)scr->mmio+hwCur);
 
 
 	/*
 	/*
 	 * Disable the cursor then load the new image in
 	 * Disable the cursor then load the new image in
@@ -181,7 +131,7 @@ i81xcurload(VGAscr* scr, Cursor* curs)
 	 * transparent.
 	 * transparent.
 	 */
 	 */
 	hwcurs->ctl = (1<<4);
 	hwcurs->ctl = (1<<4);
-	p = KADDR(scr->storage);
+	p = (uchar*)scr->storage;
 	for(y = 0; y < 16; y += 2) {
 	for(y = 0; y < 16; y += 2) {
 		*p++ = ~(curs->clr[2*y]|curs->set[2*y]);
 		*p++ = ~(curs->clr[2*y]|curs->set[2*y]);
 		*p++ = ~(curs->clr[2*y+1]|curs->set[2*y+1]);
 		*p++ = ~(curs->clr[2*y+1]|curs->set[2*y+1]);
@@ -213,9 +163,9 @@ i81xcurmove(VGAscr* scr, Point p)
 	ulong pos;
 	ulong pos;
 	CursorI81x *hwcurs;
 	CursorI81x *hwcurs;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return 1;
 		return 1;
-	hwcurs = KADDR(scr->io+hwCur);
+	hwcurs = (void*)((uchar*)scr->mmio+hwCur);
 
 
 	x = p.x+scr->offset.x;
 	x = p.x+scr->offset.x;
 	y = p.y+scr->offset.y;
 	y = p.y+scr->offset.y;
@@ -242,15 +192,15 @@ i81xcurenable(VGAscr* scr)
 	CursorI81x *hwcurs;
 	CursorI81x *hwcurs;
 
 
 	i81xenable(scr);
 	i81xenable(scr);
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
-	hwcurs = KADDR(scr->io+hwCur);
+	hwcurs = (void*)((uchar*)scr->mmio+hwCur);
 
 
 	/*
 	/*
 	 * Initialise the 32x32 cursor to be transparent in 2bpp mode.
 	 * Initialise the 32x32 cursor to be transparent in 2bpp mode.
 	 */
 	 */
-	hwcurs->base = scr->storage;
-	p = KADDR(scr->storage);
+	hwcurs->base = PADDR(scr->storage);
+	p = (uchar*)scr->storage;
 	for(i = 0; i < 32/2; i++) {
 	for(i = 0; i < 32/2; i++) {
 		memset(p, 0xff, 8);
 		memset(p, 0xff, 8);
 		memset(p+8, 0, 8);
 		memset(p+8, 0, 8);
@@ -269,7 +219,7 @@ VGAdev vgai81xdev = {
 	i81xenable,
 	i81xenable,
 	nil,
 	nil,
 	nil,
 	nil,
-	i81xlinear,
+	nil,
 };
 };
 
 
 VGAcur vgai81xcur = {
 VGAcur vgai81xcur = {

+ 13 - 53
sys/src/9/pc/vgamach64xx.c

@@ -168,13 +168,11 @@ mach64xxenable(VGAscr* scr)
 {
 {
 	Pcidev *p;
 	Pcidev *p;
 
 
-	/*
-	 * Only once, can't be disabled for now.
-	 */
 	if(scr->io)
 	if(scr->io)
 		return;
 		return;
 	if(p = mach64xxpci()){
 	if(p = mach64xxpci()){
 		scr->id = p->did;
 		scr->id = p->did;
+		scr->pci = p;
 
 
 		/*
 		/*
 		 * The CT doesn't always have the I/O base address
 		 * The CT doesn't always have the I/O base address
@@ -189,53 +187,15 @@ mach64xxenable(VGAscr* scr)
 	}
 	}
 }
 }
 
 
-static ulong
-mach64xxlinear(VGAscr* scr, int* size, int* align)
+static void
+mach64xxlinear(VGAscr* scr, int size, int)
 {
 {
-	ulong aperture, osize, oaperture;
-	int i, oapsize, wasupamem;
-	Pcidev *p;
-
-	osize = *size;
-	oaperture = scr->aperture;
-	oapsize = scr->apsize;
-	wasupamem = scr->isupamem;
-
-	if(p = mach64xxpci()){
-		for(i=0; i<nelem(p->mem); i++){
-			if(p->mem[i].size >= *size
-			&& ((p->mem[i].bar & ~0x0F) & (*align-1)) == 0)
-				break;
-		}
-		if(i >= nelem(p->mem)){
-			print("vgamach64xx: aperture not found\n");
-			return 0;
-		}
-		aperture = p->mem[i].bar & ~0x0F;
-		*size = p->mem[i].size;
-	}
-	else
-		aperture = 0;
-
-	if(wasupamem)
-		upafree(oaperture, oapsize);
-	scr->isupamem = 0;
-
-	aperture = upamalloc(aperture, *size, *align);
-	if(aperture == 0){
-		if(wasupamem && upamalloc(oaperture, oapsize, 0))
-			scr->isupamem = 1;
-	}
-	else
-		scr->isupamem = 1;
-
-	scr->mmio = KADDR(aperture+osize-0x400);
-	if(oaperture && oaperture != aperture)
-		print("warning (BUG): redefinition of aperture does not change mach64mmio segment\n");
-	addvgaseg("mach64mmio", aperture+osize-BY2PG, BY2PG);
-	addvgaseg("mach64screen", aperture, osize);
-
-	return aperture;
+	vgalinearpci(scr);
+	if(scr->paddr == 0)
+		return;
+	scr->mmio = (ulong*)((uchar*)scr->vaddr+size-1024);
+	addvgaseg("mach64mmio", scr->paddr+size-BY2PG, BY2PG);
+	addvgaseg("mach64screen", scr->paddr, scr->apsize);
 }
 }
 
 
 enum {
 enum {
@@ -474,7 +434,7 @@ mach64xxcurload(VGAscr* scr, Cursor* curs)
 	r = ior32(scr, GenTestCntl);
 	r = ior32(scr, GenTestCntl);
 	iow32(scr, GenTestCntl, r & ~0x80);
 	iow32(scr, GenTestCntl, r & ~0x80);
 
 
-	p = KADDR(scr->aperture);
+	p = scr->vaddr;
 	p += scr->storage;
 	p += scr->storage;
 
 
 	/*
 	/*
@@ -792,7 +752,7 @@ initengine(VGAscr *scr)
 	}
 	}
 
 
 	/* Get the base freq from the BIOS */
 	/* Get the base freq from the BIOS */
-	bios  = KADDR(0xC000);
+	bios  = kaddr(0xC000);
 	table = *(ushort *)(bios + 0x48);
 	table = *(ushort *)(bios + 0x48);
 	table = *(ushort *)(bios + table + 0x10);
 	table = *(ushort *)(bios + table + 0x10);
 	switch (*(ushort *)(bios + table + 0x08)) {
 	switch (*(ushort *)(bios + table + 0x08)) {
@@ -1120,7 +1080,7 @@ ovl_status(VGAscr *scr, Chan *, char **field)
 		   mach64revb? "yes": "no",
 		   mach64revb? "yes": "no",
 		   mach64refclock);
 		   mach64refclock);
 	pprint("%s: storage @%.8luX, aperture @%8.ulX, ovl buf @%.8ulX\n",
 	pprint("%s: storage @%.8luX, aperture @%8.ulX, ovl buf @%.8ulX\n",
-		   scr->dev->name, scr->storage, scr->aperture,
+		   scr->dev->name, scr->storage, scr->paddr,
 		   mach64overlay);
 		   mach64overlay);
 }
 }
 	
 	
@@ -1215,7 +1175,7 @@ mach64xxovlwrite(VGAscr *scr, void *a, int len, vlong offs)
 
 
 		_offs = (ulong)(offs % ovl_fib);
 		_offs = (ulong)(offs % ovl_fib);
 		nb     = (_offs + len > ovl_fib)? ovl_fib - _offs: len;
 		nb     = (_offs + len > ovl_fib)? ovl_fib - _offs: len;
-		memmove((uchar *)KADDR(scr->aperture + mach64overlay + _offs), 
+		memmove((uchar *)scr->vaddr + mach64overlay + _offs, 
 				  src, nb);
 				  src, nb);
 		offs += nb;
 		offs += nb;
 		src  += nb;
 		src  += nb;

+ 22 - 73
sys/src/9/pc/vgamga2164w.c

@@ -42,82 +42,31 @@ mgapcimatch(void)
 	return p;
 	return p;
 }
 }
 
 
-static ulong
-mga2164wlinear(VGAscr* scr, int* size, int* align)
-{
-	ulong aperture, oaperture;
-	int oapsize, wasupamem;
-	Pcidev *p;
-
-	oaperture = scr->aperture;
-	oapsize = scr->apsize;
-	wasupamem = scr->isupamem;
-
-	if(p = mgapcimatch()){
-		aperture = p->mem[p->did==MGA2064? 1 : 0].bar & ~0x0F;
-		*size = (p->did==MGA2064? 8 :16)*1024*1024;
-	}
-	else
-		aperture = 0;
-
-	if(wasupamem) {
-		if(oaperture == aperture)
-			return oaperture;
-		upafree(oaperture, oapsize);
-	}
-	scr->isupamem = 0;
-
-	aperture = upamalloc(aperture, *size, *align);
-	if(aperture == 0){
-		if(wasupamem && upamalloc(oaperture, oapsize, 0)) {
-			aperture = oaperture;
-			scr->isupamem = 1;
-		}
-		else
-			scr->isupamem = 0;
-	}
-	else
-		scr->isupamem = 1;
-
-	return aperture;
-}
-
 static void
 static void
 mga2164wenable(VGAscr* scr)
 mga2164wenable(VGAscr* scr)
 {
 {
 	Pcidev *p;
 	Pcidev *p;
-	int size, align, immio;
-	ulong aperture;
 
 
-	/*
-	 * Only once, can't be disabled for now.
-	 * scr->io holds the virtual address of
-	 * the MMIO registers.
-	 */
-	if(scr->io)
+	if(scr->mmio)
 		return;
 		return;
 
 
 	p = mgapcimatch();
 	p = mgapcimatch();
 	if(p == nil)
 	if(p == nil)
 		return;
 		return;
 
 
-	immio = p->did==MGA2064? 0 : 1;
-	scr->io = upamalloc(p->mem[immio].bar & ~0x0F, p->mem[immio].size, 0);
-	if(scr->io == 0)
-		return;
-	addvgaseg("mga2164wmmio", scr->io, p->mem[immio].size);
-
-	scr->io = (ulong)KADDR(scr->io);
-
-	/* need to map frame buffer here too, so vga can find memory size */
-	size = (p->did==MGA2064? 8 :16)*1024*1024;
-	align = 0;
-	aperture = mga2164wlinear(scr, &size, &align);
-	if(aperture) {
-		scr->aperture = aperture;
-		scr->apsize = size;
-		addvgaseg("mga2164wscreen", aperture, size);
+	if(p->did == MGA2064){
+		scr->mmio = vmap(p->mem[0].bar&~0x0F, p->mem[0].size);
+		if(scr->mmio == nil)
+			return;
+		vgalinearaddr(scr, p->mem[1].bar&~0x0F, 8*MB);
+	}else{
+		scr->mmio = vmap(p->mem[1].bar&~0x0F, p->mem[1].size);
+		if(scr->mmio == nil)
+			return;
+		vgalinearaddr(scr, p->mem[0].bar&~0x0F, 16*MB);
 	}
 	}
+	if(scr->paddr)
+		addvgaseg("mga2164wscreen", scr->paddr, scr->apsize);
 }
 }
 
 
 enum {
 enum {
@@ -142,9 +91,9 @@ tvp3026disable(VGAscr* scr)
 {
 {
 	uchar *tvp3026;
 	uchar *tvp3026;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
-	tvp3026 = KADDR(scr->io+0x3C00);
+	tvp3026 = (uchar*)scr->mmio+0x3C00;
 
 
 	/*
 	/*
 	 * Make sure cursor is off
 	 * Make sure cursor is off
@@ -161,9 +110,9 @@ tvp3026load(VGAscr* scr, Cursor* curs)
 	int x, y;
 	int x, y;
 	uchar *tvp3026;
 	uchar *tvp3026;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
-	tvp3026 = KADDR(scr->io+0x3C00);
+	tvp3026 = (uchar*)scr->mmio+0x3C00;
 
 
 	/*
 	/*
 	 * Make sure cursor is off by initialising the cursor
 	 * Make sure cursor is off by initialising the cursor
@@ -223,9 +172,9 @@ tvp3026move(VGAscr* scr, Point p)
 	int x, y;
 	int x, y;
 	uchar *tvp3026;
 	uchar *tvp3026;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return 1;
 		return 1;
-	tvp3026 = KADDR(scr->io+0x3C00);
+	tvp3026 = (uchar*)scr->mmio+0x3C00;
 
 
 	x = p.x+scr->offset.x;
 	x = p.x+scr->offset.x;
 	y = p.y+scr->offset.y;
 	y = p.y+scr->offset.y;
@@ -244,9 +193,9 @@ tvp3026enable(VGAscr* scr)
 	int i;
 	int i;
 	uchar *tvp3026;
 	uchar *tvp3026;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
-	tvp3026 = KADDR(scr->io+0x3C00);
+	tvp3026 = (uchar*)scr->mmio+0x3C00;
 
 
 	tvp3026disable(scr);
 	tvp3026disable(scr);
 
 
@@ -276,7 +225,7 @@ VGAdev vgamga2164wdev = {
 	mga2164wenable,			/* enable */
 	mga2164wenable,			/* enable */
 	0,				/* disable */
 	0,				/* disable */
 	0,				/* page */
 	0,				/* page */
-	mga2164wlinear,			/* linear */
+	0,				/* linear */
 };
 };
 
 
 VGAcur vgamga2164wcur = {
 VGAcur vgamga2164wcur = {

+ 41 - 93
sys/src/9/pc/vgamga4xx.c

@@ -23,9 +23,6 @@ enum {
 	MGA4xx			= 0x0525,
 	MGA4xx			= 0x0525,
 	MGA200			= 0x0521,
 	MGA200			= 0x0521,
 
 
-	Kilo				= 1024,
-	Meg				= 1024*1024,
-
 	FCOL			= 0x1c24,
 	FCOL			= 0x1c24,
 	FXRIGHT			= 0x1cac,	
 	FXRIGHT			= 0x1cac,	
 	FXLEFT			= 0x1ca8,
 	FXLEFT			= 0x1ca8,
@@ -91,59 +88,17 @@ mgapcimatch(void)
 	return p;
 	return p;
 }
 }
 
 
-static ulong
-mga4xxlinear(VGAscr* scr, int* size, int* align)
-{
-	ulong 	aperture, oaperture;
-	int 		oapsize, wasupamem;
-	Pcidev *	p;
-
-	oaperture = scr->aperture;
-	oapsize = scr->apsize;
-	wasupamem = scr->isupamem;
-
-	if(p = mgapcimatch()){
-		aperture = p->mem[0].bar & ~0x0F;
-		if(p->did == MGA4xx)
-			*size = 32*Meg;
-		else
-			*size = 8*Meg;
-	}
-	else
-		aperture = 0;
-
-	if(wasupamem) {
-		if(oaperture == aperture)
-			return oaperture;
-		upafree(oaperture, oapsize);
-	}
-	scr->isupamem = 0;
-
-	aperture = upamalloc(aperture, *size, *align);
-	if(aperture == 0){
-		if(wasupamem && upamalloc(oaperture, oapsize, 0)) {
-			aperture = oaperture;
-			scr->isupamem = 1;
-		}
-		else
-			scr->isupamem = 0;
-	}
-	else
-		scr->isupamem = 1;
-
-	return aperture;
-}
 
 
 static void
 static void
 mgawrite8(VGAscr* scr, int index, uchar val)
 mgawrite8(VGAscr* scr, int index, uchar val)
 {
 {
-	((uchar*)scr->io)[index] = val;
+	((uchar*)scr->mmio)[index] = val;
 }
 }
 
 
 static uchar
 static uchar
 mgaread8(VGAscr* scr, int index)
 mgaread8(VGAscr* scr, int index)
 {
 {
-	return ((uchar*)scr->io)[index];
+	return ((uchar*)scr->mmio)[index];
 }
 }
 
 
 static uchar
 static uchar
@@ -163,60 +118,53 @@ static void
 mga4xxenable(VGAscr* scr)
 mga4xxenable(VGAscr* scr)
 {
 {
 	Pcidev *	pci;
 	Pcidev *	pci;
-	int 		size, align;
-	ulong 	aperture;
+	int 		size;
 	int 		i, n, k;
 	int 		i, n, k;
 	uchar *	p;
 	uchar *	p;
 	uchar	x[16];
 	uchar	x[16];
 	uchar	crtcext3;
 	uchar	crtcext3;
 
 
-	/*
-	 * Only once, can't be disabled for now.
-	 * scr->io holds the virtual address of
-	 * the MMIO registers.
-	 */
-	if(scr->io)
+	if(scr->mmio)
 		return;
 		return;
 
 
 	pci = mgapcimatch();
 	pci = mgapcimatch();
 	if(pci == nil)
 	if(pci == nil)
 		return;
 		return;
 
 
-	scr->io = upamalloc(pci->mem[1].bar & ~0x0F, 16*1024, 0);
-	if(scr->io == 0)
+	scr->mmio = vmap(pci->mem[1].bar&~0x0F, 16*1024);
+	if(scr->mmio == nil)
 		return;
 		return;
-
-	addvgaseg("mga4xxmmio", scr->io, pci->mem[1].size);
-
-	scr->io = (ulong)KADDR(scr->io);
+	
+	addvgaseg("mga4xxmmio", pci->mem[1].bar&~0x0F, pci->mem[1].size);
 
 
 	/* need to map frame buffer here too, so vga can find memory size */
 	/* need to map frame buffer here too, so vga can find memory size */
-	size = 8*Meg;
-	align = 0;
-	aperture = mga4xxlinear(scr, &size, &align);
-	if(aperture) {
-		scr->aperture = aperture;
-		addvgaseg("mga4xxscreen", aperture, size);
+	if(pci->did == MGA4xx)
+		size = 32*MB;
+	else
+		size = 8*MB;
+	vgalinearaddr(scr, pci->mem[0].bar&~0x0F, size);
 
 
-		/* Find out how much memory is here, some multiple of 2 Meg */
+	if(scr->paddr){
+
+		/* Find out how much memory is here, some multiple of 2 MB */
 
 
 		/* First Set MGA Mode ... */
 		/* First Set MGA Mode ... */
 		crtcext3 = crtcextset(scr, 3, 0x80, 0x00);
 		crtcext3 = crtcextset(scr, 3, 0x80, 0x00);
 
 
-		p = (uchar*)aperture;
-		n = (size / Meg) / 2;
+		p = scr->vaddr;
+		n = (size / MB) / 2;
 		for (i = 0; i < n; i++) {
 		for (i = 0; i < n; i++) {
-			k = (2*i+1)*Meg;
+			k = (2*i+1)*MB;
 			p[k] = 0;
 			p[k] = 0;
 			p[k] = i+1;
 			p[k] = i+1;
-			*((uchar*)(scr->io + CACHEFLUSH)) = 0;
+			*((uchar*)scr->mmio + CACHEFLUSH) = 0;
 			x[i] = p[k];
 			x[i] = p[k];
  		}
  		}
 		for(i = 1; i < n; i++)
 		for(i = 1; i < n; i++)
 			if(x[i] != i+1)
 			if(x[i] != i+1)
 				break;
 				break;
-  		scr->apsize = 2*i*Meg;
-
+		scr->apsize = 2*i*MB;	/* sketchy */
+		addvgaseg("mga4xxscreen", scr->paddr, scr->apsize);
 		crtcextset(scr, 3, crtcext3, 0xff);
 		crtcextset(scr, 3, crtcext3, 0xff);
 	}
 	}
 }
 }
@@ -240,10 +188,10 @@ dac4xxdisable(VGAscr* scr)
 {
 {
 	uchar * 	dac4xx;
 	uchar * 	dac4xx;
 	
 	
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
 
 
-	dac4xx = KADDR(scr->io+0x3C00);
+	dac4xx = (uchar*)scr->mmio+0x3C00;
 	
 	
 	*(dac4xx+Index) = Icctl;
 	*(dac4xx+Index) = Icctl;
 	*(dac4xx+Data) = 0x00;
 	*(dac4xx+Data) = 0x00;
@@ -256,14 +204,14 @@ dac4xxload(VGAscr* scr, Cursor* curs)
 	uchar *	p;
 	uchar *	p;
 	uchar * 	dac4xx;
 	uchar * 	dac4xx;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
 
 
-	dac4xx = KADDR(scr->io+0x3C00);
+	dac4xx = (uchar*)scr->mmio+0x3C00;
 	
 	
 	dac4xxdisable(scr);
 	dac4xxdisable(scr);
 
 
-	p = KADDR(scr->storage);
+	p = scr->vaddr;
 	for(y = 0; y < 64; y++){
 	for(y = 0; y < 64; y++){
 		*p++ = 0; *p++ = 0; *p++ = 0;
 		*p++ = 0; *p++ = 0; *p++ = 0;
 		*p++ = 0; *p++ = 0; *p++ = 0;
 		*p++ = 0; *p++ = 0; *p++ = 0;
@@ -296,10 +244,10 @@ dac4xxmove(VGAscr* scr, Point p)
 	int 		x, y;
 	int 		x, y;
 	uchar *	dac4xx;
 	uchar *	dac4xx;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return 1;
 		return 1;
 
 
-	dac4xx = KADDR(scr->io + 0x3C00);
+	dac4xx = (uchar*)scr->mmio + 0x3C00;
 
 
 	x = p.x + scr->offset.x;
 	x = p.x + scr->offset.x;
 	y = p.y + scr->offset.y;
 	y = p.y + scr->offset.y;
@@ -319,9 +267,9 @@ dac4xxenable(VGAscr* scr)
 	uchar *	dac4xx;
 	uchar *	dac4xx;
 	ulong	storage;
 	ulong	storage;
 	
 	
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
-	dac4xx = KADDR(scr->io+0x3C00);
+	dac4xx = (uchar*)scr->mmio+0x3C00;
 
 
 	dac4xxdisable(scr);
 	dac4xxdisable(scr);
 
 
@@ -332,7 +280,7 @@ dac4xxenable(VGAscr* scr)
 	*(dac4xx+Index) = Icuradrh;
 	*(dac4xx+Index) = Icuradrh;
 	*(dac4xx+Data) = 0xff & (storage >> 18);		
 	*(dac4xx+Data) = 0xff & (storage >> 18);		
 
 
-	scr->storage = (ulong) KADDR((ulong)scr->aperture + (ulong)storage);
+	scr->storage = (ulong)scr->vaddr + storage;
 
 
 	/* Show X11-Like Cursor */
 	/* Show X11-Like Cursor */
 	*(dac4xx+Index) = Icctl;
 	*(dac4xx+Index) = Icctl;
@@ -380,9 +328,9 @@ mga4xxblank(VGAscr* scr, int blank)
 	/* blank = 0 -> turn screen on */
 	/* blank = 0 -> turn screen on */
 	/* blank = 1 -> turn screen off */
 	/* blank = 1 -> turn screen off */
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
-	mga = KADDR(scr->io);	
+	mga = (uchar*)scr->mmio;	
 
 
 	if (blank == 0) {
 	if (blank == 0) {
 		seq1 = 0x00;
 		seq1 = 0x00;
@@ -432,9 +380,9 @@ mga4xxfill(VGAscr* scr, Rectangle r, ulong color)
 	uchar * 		mga;
 	uchar * 		mga;
  
  
 	/* Constant Shaded Trapezoids / Rectangle Fills */
 	/* Constant Shaded Trapezoids / Rectangle Fills */
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return 0;
 		return 0;
-	mga = KADDR(scr->io);
+	mga = (uchar*)scr->mmio;
 
 
 	mgawrite32(mga, DWGCTL, 0);
 	mgawrite32(mga, DWGCTL, 0);
 	mgawrite32(mga, FCOL, color);
 	mgawrite32(mga, FCOL, color);
@@ -460,10 +408,10 @@ mga4xxscroll(VGAscr* scr, Rectangle r_dst, Rectangle r_src)
 	int 		ydir;
 	int 		ydir;
  
  
 	/* Two-operand Bitblts */
 	/* Two-operand Bitblts */
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return 0;
 		return 0;
 
 
-	mga = KADDR(scr->io);
+	mga = (uchar*)scr->mmio;
 
 
 	pitch = Dx(scr->gscreen->r);
 	pitch = Dx(scr->gscreen->r);
 
 
@@ -556,9 +504,9 @@ mga4xxdrawinit(VGAscr* scr)
 	if (p == nil)
 	if (p == nil)
 		return ;
 		return ;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
-	mga = KADDR(scr->io);
+	mga = (uchar*)scr->mmio;
 
 
 	mgawrite32(mga, SRCORG, 0);
 	mgawrite32(mga, SRCORG, 0);
 	mgawrite32(mga, DSTORG, 0);
 	mgawrite32(mga, DSTORG, 0);
@@ -590,7 +538,7 @@ VGAdev vgamga4xxdev = {
 	mga4xxenable,		/* enable */
 	mga4xxenable,		/* enable */
 	0,					/* disable */
 	0,					/* disable */
 	0,					/* page */
 	0,					/* page */
-	mga4xxlinear,			/* linear */
+	0,					/* linear */
 	mga4xxdrawinit,
 	mga4xxdrawinit,
 };
 };
 
 

+ 27 - 84
sys/src/9/pc/vganeomagic.c

@@ -22,72 +22,20 @@ struct CursorNM {
 	int	addr;
 	int	addr;
 };
 };
 
 
-static ulong
-neomagiclinear(VGAscr* scr, int* size, int* align)
-{
-	ulong aperture, oaperture;
-	int oapsize, wasupamem;
-	Pcidev *p;
-
-	oaperture = scr->aperture;
-	oapsize = scr->apsize;
-	wasupamem = scr->isupamem;
-
-	aperture = 0;
-	if(p = pcimatch(nil, 0x10C8, 0)){
-		switch(p->did){
-		case 0x0003:		/* MagicGraph 128ZV */
-		case 0x0083:		/* MagicGraph 128ZV+ */
-		case 0x0004:		/* MagicGraph 128XD */
-		case 0x0005:		/* MagicMedia 256AV */
-		case 0x0006:		/* MagicMedia 256ZX */
-			aperture = p->mem[0].bar & ~0x0F;
-			*size = p->mem[0].size;
-			break;
-		default:
-			break;
-		}
-	}
-
-	if(wasupamem){
-		if(oaperture == aperture)
-			return oaperture;
-		upafree(oaperture, oapsize);
-	}
-	scr->isupamem = 0;
-
-	aperture = upamalloc(aperture, *size, *align);
-//print("neomagiclinear1 %lux %d\n", aperture, *size);
-	if(aperture == 0){
-		if(wasupamem && upamalloc(oaperture, oapsize, 0)){
-			aperture = oaperture;
-			scr->isupamem = 1;
-		}
-		else
-			scr->isupamem = 0;
-	}
-	else
-		scr->isupamem = 1;
-
-	return aperture;
-}
-
 static void
 static void
 neomagicenable(VGAscr* scr)
 neomagicenable(VGAscr* scr)
 {
 {
 	Pcidev *p;
 	Pcidev *p;
-	int align, curoff, size, vmsize;
-	ulong aperture;
+	int curoff, vmsize;
 	ulong ioaddr;
 	ulong ioaddr;
 	ulong iosize;
 	ulong iosize;
 
 
 	/*
 	/*
-	 * Only once, can't be disabled for now.
-	 * scr->io holds the physical address of the cursor registers
+	 * scr->mmio holds the virtual address of the cursor registers
 	 * in the MMIO space. This may need to change for older chips
 	 * in the MMIO space. This may need to change for older chips
 	 * which have the MMIO space offset in the framebuffer region.
 	 * which have the MMIO space offset in the framebuffer region.
 	 */
 	 */
-	if(scr->io)
+	if(scr->mmio)
 		return;
 		return;
 	if(p = pcimatch(nil, 0x10C8, 0)){
 	if(p = pcimatch(nil, 0x10C8, 0)){
 		switch(p->did){
 		switch(p->did){
@@ -127,11 +75,12 @@ neomagicenable(VGAscr* scr)
 	}
 	}
 	else
 	else
 		return;
 		return;
-	scr->io = upamalloc(ioaddr, iosize, 0);
-	if(scr->io == 0)
+	scr->pci = p;
+
+	scr->mmio = vmap(ioaddr, iosize);
+	if(scr->mmio == nil)
 		return;
 		return;
-	addvgaseg("neomagicmmio", scr->io, iosize);
-	scr->mmio = KADDR(scr->io);
+	addvgaseg("neomagicmmio", ioaddr, iosize);
 
 
 	/*
 	/*
 	 * Find a place for the cursor data in display memory.
 	 * Find a place for the cursor data in display memory.
@@ -139,16 +88,10 @@ neomagicenable(VGAscr* scr)
 	 * last 2KB of the framebuffer.
 	 * last 2KB of the framebuffer.
 	 */
 	 */
 	scr->storage = vmsize-2*1024;
 	scr->storage = vmsize-2*1024;
-	scr->io += curoff;
-
-	size = p->mem[0].size;
-	align = 0;
-	aperture = neomagiclinear(scr, &size, &align);
-	if(aperture) {
-		scr->aperture = aperture;
-		scr->apsize = size;
-		addvgaseg("neomagicscreen", aperture, size);
-	}
+	scr->mmio = (ulong*)((uchar*)scr->mmio + curoff);
+	vgalinearpci(scr);
+	if(scr->paddr)
+		addvgaseg("neomagicscreen", scr->paddr, scr->apsize);
 }
 }
 
 
 static void
 static void
@@ -156,9 +99,9 @@ neomagiccurdisable(VGAscr* scr)
 {
 {
 	CursorNM *cursornm;
 	CursorNM *cursornm;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
-	cursornm = KADDR(scr->io);
+	cursornm = (void*)scr->mmio;
 	cursornm->enable = 0;
 	cursornm->enable = 0;
 }
 }
 
 
@@ -169,7 +112,7 @@ neomagicinitcursor(VGAscr* scr, int xo, int yo, int index)
 	uint p0, p1;
 	uint p0, p1;
 	int x, y;
 	int x, y;
 
 
-	p = KADDR(scr->aperture);
+	p = (uchar*)scr->mmio;
 	p += scr->storage + index*1024;
 	p += scr->storage + index*1024;
 
 
 	for(y = yo; y < 16; y++){
 	for(y = yo; y < 16; y++){
@@ -211,9 +154,9 @@ neomagiccurload(VGAscr* scr, Cursor* curs)
 {
 {
 	CursorNM *cursornm;
 	CursorNM *cursornm;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
-	cursornm = KADDR(scr->io);
+	cursornm = (void*)scr->mmio;
 
 
 	cursornm->enable = 0;
 	cursornm->enable = 0;
 	memmove(&scr->Cursor, curs, sizeof(Cursor));
 	memmove(&scr->Cursor, curs, sizeof(Cursor));
@@ -227,9 +170,9 @@ neomagiccurmove(VGAscr* scr, Point p)
 	CursorNM *cursornm;
 	CursorNM *cursornm;
 	int addr, index, x, xo, y, yo;
 	int addr, index, x, xo, y, yo;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return 1;
 		return 1;
-	cursornm = KADDR(scr->io);
+	cursornm = (void*)scr->mmio;
 
 
 	index = 0;
 	index = 0;
 	if((x = p.x+scr->offset.x) < 0){
 	if((x = p.x+scr->offset.x) < 0){
@@ -266,9 +209,9 @@ neomagiccurenable(VGAscr* scr)
 	CursorNM *cursornm;
 	CursorNM *cursornm;
 
 
 	neomagicenable(scr);
 	neomagicenable(scr);
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
-	cursornm = KADDR(scr->io);
+	cursornm = (void*)scr->mmio;
 	cursornm->enable = 0;
 	cursornm->enable = 0;
 
 
 	/*
 	/*
@@ -426,7 +369,7 @@ neomagichwfill(VGAscr *scr, Rectangle r, ulong sval)
 		| NEO_BC0_SRC_IS_FG
 		| NEO_BC0_SRC_IS_FG
 		| NEO_BC3_SKIP_MAPPING
 		| NEO_BC3_SKIP_MAPPING
 		| GXcopy;
 		| GXcopy;
-	mmio[DstStartOff] = scr->aperture
+	mmio[DstStartOff] = scr->paddr
 		+ r.min.y*scr->gscreen->width*BY2WD
 		+ r.min.y*scr->gscreen->width*BY2WD
 		+ r.min.x*scr->gscreen->depth/BI2BY;
 		+ r.min.x*scr->gscreen->depth/BI2BY;
 	mmio[XYExt] = (Dy(r) << 16) | (Dx(r) & 0xffff);
 	mmio[XYExt] = (Dy(r) << 16) | (Dx(r) & 0xffff);
@@ -452,9 +395,9 @@ neomagichwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
 			| NEO_BC3_FIFO_EN
 			| NEO_BC3_FIFO_EN
 			| NEO_BC3_SKIP_MAPPING
 			| NEO_BC3_SKIP_MAPPING
 			| GXcopy;
 			| GXcopy;
-		mmio[SrcStartOff] = scr->aperture
+		mmio[SrcStartOff] = scr->paddr
 			+ sr.min.y*pitch + sr.min.x*pixel;
 			+ sr.min.y*pitch + sr.min.x*pixel;
-		mmio[DstStartOff] = scr->aperture
+		mmio[DstStartOff] = scr->paddr
 			+ r.min.y*pitch + r.min.x*pixel;
 			+ r.min.y*pitch + r.min.x*pixel;
 	} else {
 	} else {
 		/* start from lower-right */
 		/* start from lower-right */
@@ -465,9 +408,9 @@ neomagichwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
 			| NEO_BC3_FIFO_EN
 			| NEO_BC3_FIFO_EN
 			| NEO_BC3_SKIP_MAPPING
 			| NEO_BC3_SKIP_MAPPING
 			| GXcopy;
 			| GXcopy;
-		mmio[SrcStartOff] = scr->aperture
+		mmio[SrcStartOff] = scr->paddr
 			+ (sr.max.y-1)*pitch + (sr.max.x-1)*pixel;
 			+ (sr.max.y-1)*pitch + (sr.max.x-1)*pixel;
-		mmio[DstStartOff] = scr->aperture
+		mmio[DstStartOff] = scr->paddr
 			+ (r.max.y-1)*pitch + (r.max.x-1)*pixel;
 			+ (r.max.y-1)*pitch + (r.max.x-1)*pixel;
 	}
 	}
 	mmio[XYExt] = (Dy(r) << 16) | (Dx(r) & 0xffff);
 	mmio[XYExt] = (Dy(r) << 16) | (Dx(r) & 0xffff);
@@ -549,7 +492,7 @@ VGAdev vganeomagicdev = {
 	neomagicenable,
 	neomagicenable,
 	nil,
 	nil,
 	nil,
 	nil,
-	neomagiclinear,
+	nil,
 	neomagicdrawinit,
 	neomagicdrawinit,
 };
 };
 
 

+ 29 - 74
sys/src/9/pc/vganvidia.c

@@ -77,8 +77,6 @@ struct {
 	int		dmamax;
 	int		dmamax;
 } nv;
 } nv;
 
 
-
-/* Nvidia is good about backwards compatibility -- any did >= 0x20 is fine */
 static Pcidev*
 static Pcidev*
 nvidiapci(void)
 nvidiapci(void)
 {
 {
@@ -92,83 +90,40 @@ nvidiapci(void)
 	return nil;
 	return nil;
 }
 }
 
 
-static ulong
-nvidialinear(VGAscr* scr, int* size, int* align)
+static void
+nvidialinear(VGAscr*, int, int)
 {
 {
-	Pcidev *p;
-	int oapsize, wasupamem;
-	ulong aperture, oaperture;
-
-	oaperture = scr->aperture;
-	oapsize = scr->apsize;
-	wasupamem = scr->isupamem;
-
-	aperture = 0;
-	if(p = nvidiapci()){
-		aperture = p->mem[1].bar & ~0x0F;
-		*size = p->mem[1].size;
-	}
-
-	if(wasupamem){
-		if(oaperture == aperture)
-			return oaperture;
-		upafree(oaperture, oapsize);
-	}
-	scr->isupamem = 0;
-
-	aperture = upamalloc(aperture, *size, *align);
-	if(aperture == 0){
-		if(wasupamem && upamalloc(oaperture, oapsize, 0)){
-			aperture = oaperture;
-			scr->isupamem = 1;
-		}
-		else
-			scr->isupamem = 0;
-	}
-	else
-		scr->isupamem = 1;
-
-	return aperture;
 }
 }
 
 
 static void
 static void
 nvidiaenable(VGAscr* scr)
 nvidiaenable(VGAscr* scr)
 {
 {
 	Pcidev *p;
 	Pcidev *p;
-	ulong aperture, *q;
-	int align, size, tmp;
-
-	/*
-	 * Only once, can't be disabled for now.
-	 * scr->io holds the physical address of
-	 * the MMIO registers.
-	 */
-	if(scr->io)
+	ulong *q;
+	int tmp;
+
+	if(scr->mmio)
 		return;
 		return;
 	p = nvidiapci();
 	p = nvidiapci();
 	if(p == nil)
 	if(p == nil)
 		return;
 		return;
 	scr->id = p->did;
 	scr->id = p->did;
+	scr->pci = p;
 
 
-	scr->io = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
-	if(scr->io == 0)
+	scr->mmio = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
+	if(scr->mmio == nil)
 		return;
 		return;
-	addvgaseg("nvidiammio", scr->io, p->mem[0].size);
-
-	size = p->mem[1].size;
-	align = 0;
-	aperture = nvidialinear(scr, &size, &align);
-	if(aperture){
-		scr->aperture = aperture;
-		scr->apsize = size;
-		addvgaseg("nvidiascreen", aperture, size);
-	}
+	addvgaseg("nvidiammio", p->mem[0].bar&~0x0F, p->mem[0].size);
+
+	vgalinearpci(scr);
+	if(scr->apsize)
+		addvgaseg("nvidiascreen", scr->paddr, scr->apsize);
 
 
 	/* find video memory size */
 	/* find video memory size */
 	switch (scr->id & 0x0ff0) {
 	switch (scr->id & 0x0ff0) {
 	case 0x0020:
 	case 0x0020:
 	case 0x00A0:
 	case 0x00A0:
-		q = KADDR(scr->io + Pfb);
+		q = (void*)((uchar*)scr->mmio + Pfb);
 		tmp = *q;
 		tmp = *q;
 		if (tmp & 0x0100) {
 		if (tmp & 0x0100) {
 			scr->storage = ((tmp >> 12) & 0x0F) * 1024 + 1024 * 2;
 			scr->storage = ((tmp >> 12) & 0x0F) * 1024 + 1024 * 2;
@@ -191,7 +146,7 @@ nvidiaenable(VGAscr* scr)
 		scr->storage = (((tmp >> 4) & 127) + 1) * 1024 * 1024;
 		scr->storage = (((tmp >> 4) & 127) + 1) * 1024 * 1024;
 		break;
 		break;
 	default:
 	default:
-		q = KADDR(scr->io + Pfb +  0x020C);
+		q = (void*)((uchar*)scr->mmio + Pfb +  0x020C);
 		tmp = (*q >> 20) & 0xFF;
 		tmp = (*q >> 20) & 0xFF;
 		if (tmp == 0)
 		if (tmp == 0)
 			tmp = 16;
 			tmp = 16;
@@ -203,7 +158,7 @@ nvidiaenable(VGAscr* scr)
 static void
 static void
 nvidiacurdisable(VGAscr* scr)
 nvidiacurdisable(VGAscr* scr)
 {
 {
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
 
 
 	vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) & ~0x01);
 	vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) & ~0x01);
@@ -218,7 +173,7 @@ nvidiacurload(VGAscr* scr, Cursor* curs)
 	ushort	c,s;
 	ushort	c,s;
 	ulong	tmp;
 	ulong	tmp;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
 
 
 	vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) & ~0x01);
 	vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) & ~0x01);
@@ -226,10 +181,10 @@ nvidiacurload(VGAscr* scr, Cursor* curs)
 	switch (scr->id & 0x0ff0) {
 	switch (scr->id & 0x0ff0) {
 	case 0x0020:
 	case 0x0020:
 	case 0x00A0:
 	case 0x00A0:
-		p = KADDR(scr->io + Pramin + 0x1E00 * 4);
+		p = (void*)((uchar*)scr->mmio + Pramin + 0x1E00 * 4);
 		break;
 		break;
 	default:
 	default:
-		p = KADDR(scr->aperture + scr->storage - 96*1024);
+		p = (void*)((uchar*)scr->vaddr + scr->storage - 96*1024);
 		break;
 		break;
 	}
 	}
 
 
@@ -268,10 +223,10 @@ nvidiacurmove(VGAscr* scr, Point p)
 {
 {
 	ulong*	cursorpos;
 	ulong*	cursorpos;
 
 
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return 1;
 		return 1;
 
 
-	cursorpos = KADDR(scr->io + hwCurPos);
+	cursorpos = (void*)((uchar*)scr->mmio + hwCurPos);
 	*cursorpos = ((p.y+scr->offset.y)<<16)|((p.x+scr->offset.x) & 0xFFFF);
 	*cursorpos = ((p.y+scr->offset.y)<<16)|((p.x+scr->offset.x) & 0xFFFF);
 
 
 	return 0;
 	return 0;
@@ -281,7 +236,7 @@ static void
 nvidiacurenable(VGAscr* scr)
 nvidiacurenable(VGAscr* scr)
 {
 {
 	nvidiaenable(scr);
 	nvidiaenable(scr);
-	if(scr->io == 0)
+	if(scr->mmio == 0)
 		return;
 		return;
 
 
 	vgaxo(Crtx, 0x1F, 0x57);
 	vgaxo(Crtx, 0x1F, 0x57);
@@ -299,9 +254,9 @@ writeput(VGAscr *scr, int data)
 	ulong	*fifo;
 	ulong	*fifo;
 
 
 	outb(0x3D0,0);
 	outb(0x3D0,0);
-	p=KADDR(scr->aperture);
+	p = scr->vaddr;
 	scratch = *p;
 	scratch = *p;
-	fifo = KADDR(scr->io + Fifo);
+	fifo = (void*)((uchar*)scr->mmio + Fifo);
 	fifo[0x10] = (data << 2);
 	fifo[0x10] = (data << 2);
 	USED(scratch);
 	USED(scratch);
 }
 }
@@ -311,7 +266,7 @@ readget(VGAscr *scr)
 {
 {
 	ulong	*fifo;
 	ulong	*fifo;
 
 
-	fifo = KADDR(scr->io + Fifo);
+	fifo = (void*)((uchar*)scr->mmio + Fifo);
 	return (fifo[0x0011] >> 2);
 	return (fifo[0x0011] >> 2);
 }
 }
 
 
@@ -375,7 +330,7 @@ waitforidle(VGAscr *scr)
 	ulong*	pgraph;
 	ulong*	pgraph;
 	int x;
 	int x;
 
 
-	pgraph = KADDR(scr->io + Pgraph);
+	pgraph = (void*)((uchar*)scr->mmio + Pgraph);
 
 
 	x = 0;
 	x = 0;
 	while((readget(scr) != nv.dmaput) && x++ < 1000000)
 	while((readget(scr) != nv.dmaput) && x++ < 1000000)
@@ -388,7 +343,7 @@ waitforidle(VGAscr *scr)
 		;
 		;
 
 
 	if(x >= 1000000)
 	if(x >= 1000000)
-		iprint("idle stat %lud scrio %.8lux scr %p pc %luX\n", *pgraph, scr->io, scr, getcallerpc(&scr));
+		iprint("idle stat %lud scrio %.8lux scr %p pc %luX\n", *pgraph, scr->mmio, scr, getcallerpc(&scr));
 }
 }
 
 
 static void
 static void
@@ -399,7 +354,7 @@ nvresetgraphics(VGAscr *scr)
 
 
 	pitch = scr->gscreen->width*BY2WD;
 	pitch = scr->gscreen->width*BY2WD;
 
 
-	nv.dmabase = KADDR(scr->aperture + scr->storage - 128*1024);
+	nv.dmabase = (void*)((uchar*)scr->vaddr + scr->storage - 128*1024);
 
 
 	for(i=0; i<SKIPS; i++)
 	for(i=0; i<SKIPS; i++)
 		nv.dmabase[i] = 0x00000000;
 		nv.dmabase[i] = 0x00000000;

Some files were not shown because too many files changed in this diff