fdc.c 73 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392
  1. /*
  2. * QEMU Floppy disk emulator (Intel 82078)
  3. *
  4. * Copyright (c) 2003, 2007 Jocelyn Mayer
  5. * Copyright (c) 2008 Hervé Poussineau
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. * THE SOFTWARE.
  24. */
  25. /*
  26. * The controller is used in Sun4m systems in a slightly different
  27. * way. There are changes in DOR register and DMA is not available.
  28. */
  29. #include "qemu/osdep.h"
  30. #include "hw/block/fdc.h"
  31. #include "qapi/error.h"
  32. #include "qemu/error-report.h"
  33. #include "qemu/timer.h"
  34. #include "qemu/memalign.h"
  35. #include "hw/irq.h"
  36. #include "hw/isa/isa.h"
  37. #include "hw/qdev-properties.h"
  38. #include "hw/qdev-properties-system.h"
  39. #include "migration/vmstate.h"
  40. #include "hw/block/block.h"
  41. #include "sysemu/block-backend.h"
  42. #include "sysemu/blockdev.h"
  43. #include "sysemu/sysemu.h"
  44. #include "qemu/log.h"
  45. #include "qemu/main-loop.h"
  46. #include "qemu/module.h"
  47. #include "trace.h"
  48. #include "qom/object.h"
  49. #include "fdc-internal.h"
  50. /********************************************************/
  51. /* debug Floppy devices */
  52. #define DEBUG_FLOPPY 0
  53. #define FLOPPY_DPRINTF(fmt, ...) \
  54. do { \
  55. if (DEBUG_FLOPPY) { \
  56. fprintf(stderr, "FLOPPY: " fmt , ## __VA_ARGS__); \
  57. } \
  58. } while (0)
  59. /* Anonymous BlockBackend for empty drive */
  60. static BlockBackend *blk_create_empty_drive(void)
  61. {
  62. return blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
  63. }
  64. /********************************************************/
  65. /* qdev floppy bus */
  66. #define TYPE_FLOPPY_BUS "floppy-bus"
  67. OBJECT_DECLARE_SIMPLE_TYPE(FloppyBus, FLOPPY_BUS)
  68. static FDrive *get_drv(FDCtrl *fdctrl, int unit);
  69. static const TypeInfo floppy_bus_info = {
  70. .name = TYPE_FLOPPY_BUS,
  71. .parent = TYPE_BUS,
  72. .instance_size = sizeof(FloppyBus),
  73. };
  74. static void floppy_bus_create(FDCtrl *fdc, FloppyBus *bus, DeviceState *dev)
  75. {
  76. qbus_init(bus, sizeof(FloppyBus), TYPE_FLOPPY_BUS, dev, NULL);
  77. bus->fdc = fdc;
  78. }
  79. /********************************************************/
  80. /* Floppy drive emulation */
  81. /* In many cases, the total sector size of a format is enough to uniquely
  82. * identify it. However, there are some total sector collisions between
  83. * formats of different physical size, and these are noted below by
  84. * highlighting the total sector size for entries with collisions. */
  85. const FDFormat fd_formats[] = {
  86. /* First entry is default format */
  87. /* 1.44 MB 3"1/2 floppy disks */
  88. { FLOPPY_DRIVE_TYPE_144, 18, 80, 1, FDRIVE_RATE_500K, }, /* 3.5" 2880 */
  89. { FLOPPY_DRIVE_TYPE_144, 20, 80, 1, FDRIVE_RATE_500K, }, /* 3.5" 3200 */
  90. { FLOPPY_DRIVE_TYPE_144, 21, 80, 1, FDRIVE_RATE_500K, },
  91. { FLOPPY_DRIVE_TYPE_144, 21, 82, 1, FDRIVE_RATE_500K, },
  92. { FLOPPY_DRIVE_TYPE_144, 21, 83, 1, FDRIVE_RATE_500K, },
  93. { FLOPPY_DRIVE_TYPE_144, 22, 80, 1, FDRIVE_RATE_500K, },
  94. { FLOPPY_DRIVE_TYPE_144, 23, 80, 1, FDRIVE_RATE_500K, },
  95. { FLOPPY_DRIVE_TYPE_144, 24, 80, 1, FDRIVE_RATE_500K, },
  96. /* 2.88 MB 3"1/2 floppy disks */
  97. { FLOPPY_DRIVE_TYPE_288, 36, 80, 1, FDRIVE_RATE_1M, },
  98. { FLOPPY_DRIVE_TYPE_288, 39, 80, 1, FDRIVE_RATE_1M, },
  99. { FLOPPY_DRIVE_TYPE_288, 40, 80, 1, FDRIVE_RATE_1M, },
  100. { FLOPPY_DRIVE_TYPE_288, 44, 80, 1, FDRIVE_RATE_1M, },
  101. { FLOPPY_DRIVE_TYPE_288, 48, 80, 1, FDRIVE_RATE_1M, },
  102. /* 720 kB 3"1/2 floppy disks */
  103. { FLOPPY_DRIVE_TYPE_144, 9, 80, 1, FDRIVE_RATE_250K, }, /* 3.5" 1440 */
  104. { FLOPPY_DRIVE_TYPE_144, 10, 80, 1, FDRIVE_RATE_250K, },
  105. { FLOPPY_DRIVE_TYPE_144, 10, 82, 1, FDRIVE_RATE_250K, },
  106. { FLOPPY_DRIVE_TYPE_144, 10, 83, 1, FDRIVE_RATE_250K, },
  107. { FLOPPY_DRIVE_TYPE_144, 13, 80, 1, FDRIVE_RATE_250K, },
  108. { FLOPPY_DRIVE_TYPE_144, 14, 80, 1, FDRIVE_RATE_250K, },
  109. /* 1.2 MB 5"1/4 floppy disks */
  110. { FLOPPY_DRIVE_TYPE_120, 15, 80, 1, FDRIVE_RATE_500K, },
  111. { FLOPPY_DRIVE_TYPE_120, 18, 80, 1, FDRIVE_RATE_500K, }, /* 5.25" 2880 */
  112. { FLOPPY_DRIVE_TYPE_120, 18, 82, 1, FDRIVE_RATE_500K, },
  113. { FLOPPY_DRIVE_TYPE_120, 18, 83, 1, FDRIVE_RATE_500K, },
  114. { FLOPPY_DRIVE_TYPE_120, 20, 80, 1, FDRIVE_RATE_500K, }, /* 5.25" 3200 */
  115. /* 720 kB 5"1/4 floppy disks */
  116. { FLOPPY_DRIVE_TYPE_120, 9, 80, 1, FDRIVE_RATE_250K, }, /* 5.25" 1440 */
  117. { FLOPPY_DRIVE_TYPE_120, 11, 80, 1, FDRIVE_RATE_250K, },
  118. /* 360 kB 5"1/4 floppy disks */
  119. { FLOPPY_DRIVE_TYPE_120, 9, 40, 1, FDRIVE_RATE_300K, }, /* 5.25" 720 */
  120. { FLOPPY_DRIVE_TYPE_120, 9, 40, 0, FDRIVE_RATE_300K, },
  121. { FLOPPY_DRIVE_TYPE_120, 10, 41, 1, FDRIVE_RATE_300K, },
  122. { FLOPPY_DRIVE_TYPE_120, 10, 42, 1, FDRIVE_RATE_300K, },
  123. /* 320 kB 5"1/4 floppy disks */
  124. { FLOPPY_DRIVE_TYPE_120, 8, 40, 1, FDRIVE_RATE_250K, },
  125. { FLOPPY_DRIVE_TYPE_120, 8, 40, 0, FDRIVE_RATE_250K, },
  126. /* 360 kB must match 5"1/4 better than 3"1/2... */
  127. { FLOPPY_DRIVE_TYPE_144, 9, 80, 0, FDRIVE_RATE_250K, }, /* 3.5" 720 */
  128. /* end */
  129. { FLOPPY_DRIVE_TYPE_NONE, -1, -1, 0, 0, },
  130. };
  131. static FDriveSize drive_size(FloppyDriveType drive)
  132. {
  133. switch (drive) {
  134. case FLOPPY_DRIVE_TYPE_120:
  135. return FDRIVE_SIZE_525;
  136. case FLOPPY_DRIVE_TYPE_144:
  137. case FLOPPY_DRIVE_TYPE_288:
  138. return FDRIVE_SIZE_350;
  139. default:
  140. return FDRIVE_SIZE_UNKNOWN;
  141. }
  142. }
  143. #define GET_CUR_DRV(fdctrl) ((fdctrl)->cur_drv)
  144. #define SET_CUR_DRV(fdctrl, drive) ((fdctrl)->cur_drv = (drive))
  145. /* Will always be a fixed parameter for us */
  146. #define FD_SECTOR_LEN 512
  147. #define FD_SECTOR_SC 2 /* Sector size code */
  148. #define FD_RESET_SENSEI_COUNT 4 /* Number of sense interrupts on RESET */
  149. static FloppyDriveType get_fallback_drive_type(FDrive *drv);
  150. /* Hack: FD_SEEK is expected to work on empty drives. However, QEMU
  151. * currently goes through some pains to keep seeks within the bounds
  152. * established by last_sect and max_track. Correcting this is difficult,
  153. * as refactoring FDC code tends to expose nasty bugs in the Linux kernel.
  154. *
  155. * For now: allow empty drives to have large bounds so we can seek around,
  156. * with the understanding that when a diskette is inserted, the bounds will
  157. * properly tighten to match the geometry of that inserted medium.
  158. */
  159. static void fd_empty_seek_hack(FDrive *drv)
  160. {
  161. drv->last_sect = 0xFF;
  162. drv->max_track = 0xFF;
  163. }
  164. static void fd_init(FDrive *drv)
  165. {
  166. /* Drive */
  167. drv->perpendicular = 0;
  168. /* Disk */
  169. drv->disk = FLOPPY_DRIVE_TYPE_NONE;
  170. drv->last_sect = 0;
  171. drv->max_track = 0;
  172. drv->ro = true;
  173. drv->media_changed = 1;
  174. }
  175. #define NUM_SIDES(drv) ((drv)->flags & FDISK_DBL_SIDES ? 2 : 1)
  176. static int fd_sector_calc(uint8_t head, uint8_t track, uint8_t sect,
  177. uint8_t last_sect, uint8_t num_sides)
  178. {
  179. return (((track * num_sides) + head) * last_sect) + sect - 1;
  180. }
  181. /* Returns current position, in sectors, for given drive */
  182. static int fd_sector(FDrive *drv)
  183. {
  184. return fd_sector_calc(drv->head, drv->track, drv->sect, drv->last_sect,
  185. NUM_SIDES(drv));
  186. }
  187. /* Returns current position, in bytes, for given drive */
  188. static int fd_offset(FDrive *drv)
  189. {
  190. g_assert(fd_sector(drv) < INT_MAX >> BDRV_SECTOR_BITS);
  191. return fd_sector(drv) << BDRV_SECTOR_BITS;
  192. }
  193. /* Seek to a new position:
  194. * returns 0 if already on right track
  195. * returns 1 if track changed
  196. * returns 2 if track is invalid
  197. * returns 3 if sector is invalid
  198. * returns 4 if seek is disabled
  199. */
  200. static int fd_seek(FDrive *drv, uint8_t head, uint8_t track, uint8_t sect,
  201. int enable_seek)
  202. {
  203. uint32_t sector;
  204. int ret;
  205. if (track > drv->max_track ||
  206. (head != 0 && (drv->flags & FDISK_DBL_SIDES) == 0)) {
  207. FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
  208. head, track, sect, 1,
  209. (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
  210. drv->max_track, drv->last_sect);
  211. return 2;
  212. }
  213. if (sect > drv->last_sect) {
  214. FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
  215. head, track, sect, 1,
  216. (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
  217. drv->max_track, drv->last_sect);
  218. return 3;
  219. }
  220. sector = fd_sector_calc(head, track, sect, drv->last_sect, NUM_SIDES(drv));
  221. ret = 0;
  222. if (sector != fd_sector(drv)) {
  223. #if 0
  224. if (!enable_seek) {
  225. FLOPPY_DPRINTF("error: no implicit seek %d %02x %02x"
  226. " (max=%d %02x %02x)\n",
  227. head, track, sect, 1, drv->max_track,
  228. drv->last_sect);
  229. return 4;
  230. }
  231. #endif
  232. drv->head = head;
  233. if (drv->track != track) {
  234. if (drv->blk != NULL && blk_is_inserted(drv->blk)) {
  235. drv->media_changed = 0;
  236. }
  237. ret = 1;
  238. }
  239. drv->track = track;
  240. drv->sect = sect;
  241. }
  242. if (drv->blk == NULL || !blk_is_inserted(drv->blk)) {
  243. ret = 2;
  244. }
  245. return ret;
  246. }
  247. /* Set drive back to track 0 */
  248. static void fd_recalibrate(FDrive *drv)
  249. {
  250. FLOPPY_DPRINTF("recalibrate\n");
  251. fd_seek(drv, 0, 0, 1, 1);
  252. }
  253. /**
  254. * Determine geometry based on inserted diskette.
  255. * Will not operate on an empty drive.
  256. *
  257. * @return: 0 on success, -1 if the drive is empty.
  258. */
  259. static int pick_geometry(FDrive *drv)
  260. {
  261. BlockBackend *blk = drv->blk;
  262. const FDFormat *parse;
  263. uint64_t nb_sectors, size;
  264. int i;
  265. int match, size_match, type_match;
  266. bool magic = drv->drive == FLOPPY_DRIVE_TYPE_AUTO;
  267. /* We can only pick a geometry if we have a diskette. */
  268. if (!drv->blk || !blk_is_inserted(drv->blk) ||
  269. drv->drive == FLOPPY_DRIVE_TYPE_NONE)
  270. {
  271. return -1;
  272. }
  273. /* We need to determine the likely geometry of the inserted medium.
  274. * In order of preference, we look for:
  275. * (1) The same drive type and number of sectors,
  276. * (2) The same diskette size and number of sectors,
  277. * (3) The same drive type.
  278. *
  279. * In all cases, matches that occur higher in the drive table will take
  280. * precedence over matches that occur later in the table.
  281. */
  282. blk_get_geometry(blk, &nb_sectors);
  283. match = size_match = type_match = -1;
  284. for (i = 0; ; i++) {
  285. parse = &fd_formats[i];
  286. if (parse->drive == FLOPPY_DRIVE_TYPE_NONE) {
  287. break;
  288. }
  289. size = (parse->max_head + 1) * parse->max_track * parse->last_sect;
  290. if (nb_sectors == size) {
  291. if (magic || parse->drive == drv->drive) {
  292. /* (1) perfect match -- nb_sectors and drive type */
  293. goto out;
  294. } else if (drive_size(parse->drive) == drive_size(drv->drive)) {
  295. /* (2) size match -- nb_sectors and physical medium size */
  296. match = (match == -1) ? i : match;
  297. } else {
  298. /* This is suspicious -- Did the user misconfigure? */
  299. size_match = (size_match == -1) ? i : size_match;
  300. }
  301. } else if (type_match == -1) {
  302. if ((parse->drive == drv->drive) ||
  303. (magic && (parse->drive == get_fallback_drive_type(drv)))) {
  304. /* (3) type match -- nb_sectors mismatch, but matches the type
  305. * specified explicitly by the user, or matches the fallback
  306. * default type when using the drive autodetect mechanism */
  307. type_match = i;
  308. }
  309. }
  310. }
  311. /* No exact match found */
  312. if (match == -1) {
  313. if (size_match != -1) {
  314. parse = &fd_formats[size_match];
  315. FLOPPY_DPRINTF("User requested floppy drive type '%s', "
  316. "but inserted medium appears to be a "
  317. "%"PRId64" sector '%s' type\n",
  318. FloppyDriveType_str(drv->drive),
  319. nb_sectors,
  320. FloppyDriveType_str(parse->drive));
  321. }
  322. assert(type_match != -1 && "misconfigured fd_format");
  323. match = type_match;
  324. }
  325. parse = &(fd_formats[match]);
  326. out:
  327. if (parse->max_head == 0) {
  328. drv->flags &= ~FDISK_DBL_SIDES;
  329. } else {
  330. drv->flags |= FDISK_DBL_SIDES;
  331. }
  332. drv->max_track = parse->max_track;
  333. drv->last_sect = parse->last_sect;
  334. drv->disk = parse->drive;
  335. drv->media_rate = parse->rate;
  336. return 0;
  337. }
  338. static void pick_drive_type(FDrive *drv)
  339. {
  340. if (drv->drive != FLOPPY_DRIVE_TYPE_AUTO) {
  341. return;
  342. }
  343. if (pick_geometry(drv) == 0) {
  344. drv->drive = drv->disk;
  345. } else {
  346. drv->drive = get_fallback_drive_type(drv);
  347. }
  348. g_assert(drv->drive != FLOPPY_DRIVE_TYPE_AUTO);
  349. }
  350. /* Revalidate a disk drive after a disk change */
  351. static void fd_revalidate(FDrive *drv)
  352. {
  353. int rc;
  354. FLOPPY_DPRINTF("revalidate\n");
  355. if (drv->blk != NULL) {
  356. drv->ro = !blk_is_writable(drv->blk);
  357. if (!blk_is_inserted(drv->blk)) {
  358. FLOPPY_DPRINTF("No disk in drive\n");
  359. drv->disk = FLOPPY_DRIVE_TYPE_NONE;
  360. fd_empty_seek_hack(drv);
  361. } else if (!drv->media_validated) {
  362. rc = pick_geometry(drv);
  363. if (rc) {
  364. FLOPPY_DPRINTF("Could not validate floppy drive media");
  365. } else {
  366. drv->media_validated = true;
  367. FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n",
  368. (drv->flags & FDISK_DBL_SIDES) ? 2 : 1,
  369. drv->max_track, drv->last_sect,
  370. drv->ro ? "ro" : "rw");
  371. }
  372. }
  373. } else {
  374. FLOPPY_DPRINTF("No drive connected\n");
  375. drv->last_sect = 0;
  376. drv->max_track = 0;
  377. drv->flags &= ~FDISK_DBL_SIDES;
  378. drv->drive = FLOPPY_DRIVE_TYPE_NONE;
  379. drv->disk = FLOPPY_DRIVE_TYPE_NONE;
  380. }
  381. }
  382. static void fd_change_cb(void *opaque, bool load, Error **errp)
  383. {
  384. FDrive *drive = opaque;
  385. if (!load) {
  386. blk_set_perm(drive->blk, 0, BLK_PERM_ALL, &error_abort);
  387. } else {
  388. if (!blkconf_apply_backend_options(drive->conf,
  389. !blk_supports_write_perm(drive->blk),
  390. false, errp)) {
  391. return;
  392. }
  393. }
  394. drive->media_changed = 1;
  395. drive->media_validated = false;
  396. fd_revalidate(drive);
  397. }
  398. static const BlockDevOps fd_block_ops = {
  399. .change_media_cb = fd_change_cb,
  400. };
  401. #define TYPE_FLOPPY_DRIVE "floppy"
  402. OBJECT_DECLARE_SIMPLE_TYPE(FloppyDrive, FLOPPY_DRIVE)
  403. struct FloppyDrive {
  404. DeviceState qdev;
  405. uint32_t unit;
  406. BlockConf conf;
  407. FloppyDriveType type;
  408. };
  409. static const Property floppy_drive_properties[] = {
  410. DEFINE_PROP_UINT32("unit", FloppyDrive, unit, -1),
  411. DEFINE_BLOCK_PROPERTIES(FloppyDrive, conf),
  412. DEFINE_PROP_SIGNED("drive-type", FloppyDrive, type,
  413. FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
  414. FloppyDriveType),
  415. };
  416. static void floppy_drive_realize(DeviceState *qdev, Error **errp)
  417. {
  418. FloppyDrive *dev = FLOPPY_DRIVE(qdev);
  419. FloppyBus *bus = FLOPPY_BUS(qdev->parent_bus);
  420. FDrive *drive;
  421. bool read_only;
  422. int ret;
  423. if (dev->unit == -1) {
  424. for (dev->unit = 0; dev->unit < MAX_FD; dev->unit++) {
  425. drive = get_drv(bus->fdc, dev->unit);
  426. if (!drive->blk) {
  427. break;
  428. }
  429. }
  430. }
  431. if (dev->unit >= MAX_FD) {
  432. error_setg(errp, "Can't create floppy unit %d, bus supports "
  433. "only %d units", dev->unit, MAX_FD);
  434. return;
  435. }
  436. drive = get_drv(bus->fdc, dev->unit);
  437. if (drive->blk) {
  438. error_setg(errp, "Floppy unit %d is in use", dev->unit);
  439. return;
  440. }
  441. if (!dev->conf.blk) {
  442. dev->conf.blk = blk_create_empty_drive();
  443. ret = blk_attach_dev(dev->conf.blk, qdev);
  444. assert(ret == 0);
  445. /* Don't take write permissions on an empty drive to allow attaching a
  446. * read-only node later */
  447. read_only = true;
  448. } else {
  449. read_only = !blk_bs(dev->conf.blk) ||
  450. !blk_supports_write_perm(dev->conf.blk);
  451. }
  452. if (!blkconf_blocksizes(&dev->conf, errp)) {
  453. return;
  454. }
  455. if (dev->conf.logical_block_size != 512 ||
  456. dev->conf.physical_block_size != 512)
  457. {
  458. error_setg(errp, "Physical and logical block size must "
  459. "be 512 for floppy");
  460. return;
  461. }
  462. /* rerror/werror aren't supported by fdc and therefore not even registered
  463. * with qdev. So set the defaults manually before they are used in
  464. * blkconf_apply_backend_options(). */
  465. dev->conf.rerror = BLOCKDEV_ON_ERROR_AUTO;
  466. dev->conf.werror = BLOCKDEV_ON_ERROR_AUTO;
  467. if (!blkconf_apply_backend_options(&dev->conf, read_only, false, errp)) {
  468. return;
  469. }
  470. /* 'enospc' is the default for -drive, 'report' is what blk_new() gives us
  471. * for empty drives. */
  472. if (blk_get_on_error(dev->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC &&
  473. blk_get_on_error(dev->conf.blk, 0) != BLOCKDEV_ON_ERROR_REPORT) {
  474. error_setg(errp, "fdc doesn't support drive option werror");
  475. return;
  476. }
  477. if (blk_get_on_error(dev->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
  478. error_setg(errp, "fdc doesn't support drive option rerror");
  479. return;
  480. }
  481. drive->conf = &dev->conf;
  482. drive->blk = dev->conf.blk;
  483. drive->fdctrl = bus->fdc;
  484. fd_init(drive);
  485. blk_set_dev_ops(drive->blk, &fd_block_ops, drive);
  486. /* Keep 'type' qdev property and FDrive->drive in sync */
  487. drive->drive = dev->type;
  488. pick_drive_type(drive);
  489. dev->type = drive->drive;
  490. fd_revalidate(drive);
  491. }
  492. static void floppy_drive_class_init(ObjectClass *klass, void *data)
  493. {
  494. DeviceClass *k = DEVICE_CLASS(klass);
  495. k->realize = floppy_drive_realize;
  496. set_bit(DEVICE_CATEGORY_STORAGE, k->categories);
  497. k->bus_type = TYPE_FLOPPY_BUS;
  498. device_class_set_props(k, floppy_drive_properties);
  499. k->desc = "virtual floppy drive";
  500. }
  501. static const TypeInfo floppy_drive_info = {
  502. .name = TYPE_FLOPPY_DRIVE,
  503. .parent = TYPE_DEVICE,
  504. .instance_size = sizeof(FloppyDrive),
  505. .class_init = floppy_drive_class_init,
  506. };
  507. /********************************************************/
  508. /* Intel 82078 floppy disk controller emulation */
  509. static void fdctrl_to_command_phase(FDCtrl *fdctrl);
  510. static void fdctrl_raise_irq(FDCtrl *fdctrl);
  511. static FDrive *get_cur_drv(FDCtrl *fdctrl);
  512. static uint32_t fdctrl_read_statusA(FDCtrl *fdctrl);
  513. static uint32_t fdctrl_read_statusB(FDCtrl *fdctrl);
  514. static uint32_t fdctrl_read_dor(FDCtrl *fdctrl);
  515. static void fdctrl_write_dor(FDCtrl *fdctrl, uint32_t value);
  516. static uint32_t fdctrl_read_tape(FDCtrl *fdctrl);
  517. static void fdctrl_write_tape(FDCtrl *fdctrl, uint32_t value);
  518. static uint32_t fdctrl_read_main_status(FDCtrl *fdctrl);
  519. static void fdctrl_write_rate(FDCtrl *fdctrl, uint32_t value);
  520. static uint32_t fdctrl_read_data(FDCtrl *fdctrl);
  521. static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value);
  522. static uint32_t fdctrl_read_dir(FDCtrl *fdctrl);
  523. static void fdctrl_write_ccr(FDCtrl *fdctrl, uint32_t value);
  524. enum {
  525. FD_DIR_WRITE = 0,
  526. FD_DIR_READ = 1,
  527. FD_DIR_SCANE = 2,
  528. FD_DIR_SCANL = 3,
  529. FD_DIR_SCANH = 4,
  530. FD_DIR_VERIFY = 5,
  531. };
  532. enum {
  533. FD_STATE_MULTI = 0x01, /* multi track flag */
  534. FD_STATE_FORMAT = 0x02, /* format flag */
  535. };
  536. enum {
  537. FD_REG_SRA = 0x00,
  538. FD_REG_SRB = 0x01,
  539. FD_REG_DOR = 0x02,
  540. FD_REG_TDR = 0x03,
  541. FD_REG_MSR = 0x04,
  542. FD_REG_DSR = 0x04,
  543. FD_REG_FIFO = 0x05,
  544. FD_REG_DIR = 0x07,
  545. FD_REG_CCR = 0x07,
  546. };
  547. enum {
  548. FD_CMD_READ_TRACK = 0x02,
  549. FD_CMD_SPECIFY = 0x03,
  550. FD_CMD_SENSE_DRIVE_STATUS = 0x04,
  551. FD_CMD_WRITE = 0x05,
  552. FD_CMD_READ = 0x06,
  553. FD_CMD_RECALIBRATE = 0x07,
  554. FD_CMD_SENSE_INTERRUPT_STATUS = 0x08,
  555. FD_CMD_WRITE_DELETED = 0x09,
  556. FD_CMD_READ_ID = 0x0a,
  557. FD_CMD_READ_DELETED = 0x0c,
  558. FD_CMD_FORMAT_TRACK = 0x0d,
  559. FD_CMD_DUMPREG = 0x0e,
  560. FD_CMD_SEEK = 0x0f,
  561. FD_CMD_VERSION = 0x10,
  562. FD_CMD_SCAN_EQUAL = 0x11,
  563. FD_CMD_PERPENDICULAR_MODE = 0x12,
  564. FD_CMD_CONFIGURE = 0x13,
  565. FD_CMD_LOCK = 0x14,
  566. FD_CMD_VERIFY = 0x16,
  567. FD_CMD_POWERDOWN_MODE = 0x17,
  568. FD_CMD_PART_ID = 0x18,
  569. FD_CMD_SCAN_LOW_OR_EQUAL = 0x19,
  570. FD_CMD_SCAN_HIGH_OR_EQUAL = 0x1d,
  571. FD_CMD_SAVE = 0x2e,
  572. FD_CMD_OPTION = 0x33,
  573. FD_CMD_RESTORE = 0x4e,
  574. FD_CMD_DRIVE_SPECIFICATION_COMMAND = 0x8e,
  575. FD_CMD_RELATIVE_SEEK_OUT = 0x8f,
  576. FD_CMD_FORMAT_AND_WRITE = 0xcd,
  577. FD_CMD_RELATIVE_SEEK_IN = 0xcf,
  578. };
  579. enum {
  580. FD_CONFIG_PRETRK = 0xff, /* Pre-compensation set to track 0 */
  581. FD_CONFIG_FIFOTHR = 0x0f, /* FIFO threshold set to 1 byte */
  582. FD_CONFIG_POLL = 0x10, /* Poll enabled */
  583. FD_CONFIG_EFIFO = 0x20, /* FIFO disabled */
  584. FD_CONFIG_EIS = 0x40, /* No implied seeks */
  585. };
  586. enum {
  587. FD_SR0_DS0 = 0x01,
  588. FD_SR0_DS1 = 0x02,
  589. FD_SR0_HEAD = 0x04,
  590. FD_SR0_EQPMT = 0x10,
  591. FD_SR0_SEEK = 0x20,
  592. FD_SR0_ABNTERM = 0x40,
  593. FD_SR0_INVCMD = 0x80,
  594. FD_SR0_RDYCHG = 0xc0,
  595. };
  596. enum {
  597. FD_SR1_MA = 0x01, /* Missing address mark */
  598. FD_SR1_NW = 0x02, /* Not writable */
  599. FD_SR1_EC = 0x80, /* End of cylinder */
  600. };
  601. enum {
  602. FD_SR2_SNS = 0x04, /* Scan not satisfied */
  603. FD_SR2_SEH = 0x08, /* Scan equal hit */
  604. };
  605. enum {
  606. FD_SRA_DIR = 0x01,
  607. FD_SRA_nWP = 0x02,
  608. FD_SRA_nINDX = 0x04,
  609. FD_SRA_HDSEL = 0x08,
  610. FD_SRA_nTRK0 = 0x10,
  611. FD_SRA_STEP = 0x20,
  612. FD_SRA_nDRV2 = 0x40,
  613. FD_SRA_INTPEND = 0x80,
  614. };
  615. enum {
  616. FD_SRB_MTR0 = 0x01,
  617. FD_SRB_MTR1 = 0x02,
  618. FD_SRB_WGATE = 0x04,
  619. FD_SRB_RDATA = 0x08,
  620. FD_SRB_WDATA = 0x10,
  621. FD_SRB_DR0 = 0x20,
  622. };
  623. enum {
  624. #if MAX_FD == 4
  625. FD_DOR_SELMASK = 0x03,
  626. #else
  627. FD_DOR_SELMASK = 0x01,
  628. #endif
  629. FD_DOR_nRESET = 0x04,
  630. FD_DOR_DMAEN = 0x08,
  631. FD_DOR_MOTEN0 = 0x10,
  632. FD_DOR_MOTEN1 = 0x20,
  633. FD_DOR_MOTEN2 = 0x40,
  634. FD_DOR_MOTEN3 = 0x80,
  635. };
  636. enum {
  637. #if MAX_FD == 4
  638. FD_TDR_BOOTSEL = 0x0c,
  639. #else
  640. FD_TDR_BOOTSEL = 0x04,
  641. #endif
  642. };
  643. enum {
  644. FD_DSR_DRATEMASK= 0x03,
  645. FD_DSR_PWRDOWN = 0x40,
  646. FD_DSR_SWRESET = 0x80,
  647. };
  648. enum {
  649. FD_MSR_DRV0BUSY = 0x01,
  650. FD_MSR_DRV1BUSY = 0x02,
  651. FD_MSR_DRV2BUSY = 0x04,
  652. FD_MSR_DRV3BUSY = 0x08,
  653. FD_MSR_CMDBUSY = 0x10,
  654. FD_MSR_NONDMA = 0x20,
  655. FD_MSR_DIO = 0x40,
  656. FD_MSR_RQM = 0x80,
  657. };
  658. enum {
  659. FD_DIR_DSKCHG = 0x80,
  660. };
  661. /*
  662. * See chapter 5.0 "Controller phases" of the spec:
  663. *
  664. * Command phase:
  665. * The host writes a command and its parameters into the FIFO. The command
  666. * phase is completed when all parameters for the command have been supplied,
  667. * and execution phase is entered.
  668. *
  669. * Execution phase:
  670. * Data transfers, either DMA or non-DMA. For non-DMA transfers, the FIFO
  671. * contains the payload now, otherwise it's unused. When all bytes of the
  672. * required data have been transferred, the state is switched to either result
  673. * phase (if the command produces status bytes) or directly back into the
  674. * command phase for the next command.
  675. *
  676. * Result phase:
  677. * The host reads out the FIFO, which contains one or more result bytes now.
  678. */
  679. enum {
  680. /* Only for migration: reconstruct phase from registers like qemu 2.3 */
  681. FD_PHASE_RECONSTRUCT = 0,
  682. FD_PHASE_COMMAND = 1,
  683. FD_PHASE_EXECUTION = 2,
  684. FD_PHASE_RESULT = 3,
  685. };
  686. #define FD_MULTI_TRACK(state) ((state) & FD_STATE_MULTI)
  687. #define FD_FORMAT_CMD(state) ((state) & FD_STATE_FORMAT)
  688. static FloppyDriveType get_fallback_drive_type(FDrive *drv)
  689. {
  690. return drv->fdctrl->fallback;
  691. }
  692. uint32_t fdctrl_read(void *opaque, uint32_t reg)
  693. {
  694. FDCtrl *fdctrl = opaque;
  695. uint32_t retval;
  696. reg &= 7;
  697. switch (reg) {
  698. case FD_REG_SRA:
  699. retval = fdctrl_read_statusA(fdctrl);
  700. break;
  701. case FD_REG_SRB:
  702. retval = fdctrl_read_statusB(fdctrl);
  703. break;
  704. case FD_REG_DOR:
  705. retval = fdctrl_read_dor(fdctrl);
  706. break;
  707. case FD_REG_TDR:
  708. retval = fdctrl_read_tape(fdctrl);
  709. break;
  710. case FD_REG_MSR:
  711. retval = fdctrl_read_main_status(fdctrl);
  712. break;
  713. case FD_REG_FIFO:
  714. retval = fdctrl_read_data(fdctrl);
  715. break;
  716. case FD_REG_DIR:
  717. retval = fdctrl_read_dir(fdctrl);
  718. break;
  719. default:
  720. retval = (uint32_t)(-1);
  721. break;
  722. }
  723. trace_fdc_ioport_read(reg, retval);
  724. return retval;
  725. }
  726. void fdctrl_write(void *opaque, uint32_t reg, uint32_t value)
  727. {
  728. FDCtrl *fdctrl = opaque;
  729. reg &= 7;
  730. trace_fdc_ioport_write(reg, value);
  731. switch (reg) {
  732. case FD_REG_DOR:
  733. fdctrl_write_dor(fdctrl, value);
  734. break;
  735. case FD_REG_TDR:
  736. fdctrl_write_tape(fdctrl, value);
  737. break;
  738. case FD_REG_DSR:
  739. fdctrl_write_rate(fdctrl, value);
  740. break;
  741. case FD_REG_FIFO:
  742. fdctrl_write_data(fdctrl, value);
  743. break;
  744. case FD_REG_CCR:
  745. fdctrl_write_ccr(fdctrl, value);
  746. break;
  747. default:
  748. break;
  749. }
  750. }
  751. static bool fdrive_media_changed_needed(void *opaque)
  752. {
  753. FDrive *drive = opaque;
  754. return (drive->blk != NULL && drive->media_changed != 1);
  755. }
  756. static const VMStateDescription vmstate_fdrive_media_changed = {
  757. .name = "fdrive/media_changed",
  758. .version_id = 1,
  759. .minimum_version_id = 1,
  760. .needed = fdrive_media_changed_needed,
  761. .fields = (const VMStateField[]) {
  762. VMSTATE_UINT8(media_changed, FDrive),
  763. VMSTATE_END_OF_LIST()
  764. }
  765. };
  766. static const VMStateDescription vmstate_fdrive_media_rate = {
  767. .name = "fdrive/media_rate",
  768. .version_id = 1,
  769. .minimum_version_id = 1,
  770. .fields = (const VMStateField[]) {
  771. VMSTATE_UINT8(media_rate, FDrive),
  772. VMSTATE_END_OF_LIST()
  773. }
  774. };
  775. static bool fdrive_perpendicular_needed(void *opaque)
  776. {
  777. FDrive *drive = opaque;
  778. return drive->perpendicular != 0;
  779. }
  780. static const VMStateDescription vmstate_fdrive_perpendicular = {
  781. .name = "fdrive/perpendicular",
  782. .version_id = 1,
  783. .minimum_version_id = 1,
  784. .needed = fdrive_perpendicular_needed,
  785. .fields = (const VMStateField[]) {
  786. VMSTATE_UINT8(perpendicular, FDrive),
  787. VMSTATE_END_OF_LIST()
  788. }
  789. };
  790. static int fdrive_post_load(void *opaque, int version_id)
  791. {
  792. fd_revalidate(opaque);
  793. return 0;
  794. }
  795. static const VMStateDescription vmstate_fdrive = {
  796. .name = "fdrive",
  797. .version_id = 1,
  798. .minimum_version_id = 1,
  799. .post_load = fdrive_post_load,
  800. .fields = (const VMStateField[]) {
  801. VMSTATE_UINT8(head, FDrive),
  802. VMSTATE_UINT8(track, FDrive),
  803. VMSTATE_UINT8(sect, FDrive),
  804. VMSTATE_END_OF_LIST()
  805. },
  806. .subsections = (const VMStateDescription * const []) {
  807. &vmstate_fdrive_media_changed,
  808. &vmstate_fdrive_media_rate,
  809. &vmstate_fdrive_perpendicular,
  810. NULL
  811. }
  812. };
  813. /*
  814. * Reconstructs the phase from register values according to the logic that was
  815. * implemented in qemu 2.3. This is the default value that is used if the phase
  816. * subsection is not present on migration.
  817. *
  818. * Don't change this function to reflect newer qemu versions, it is part of
  819. * the migration ABI.
  820. */
  821. static int reconstruct_phase(FDCtrl *fdctrl)
  822. {
  823. if (fdctrl->msr & FD_MSR_NONDMA) {
  824. return FD_PHASE_EXECUTION;
  825. } else if ((fdctrl->msr & FD_MSR_RQM) == 0) {
  826. /* qemu 2.3 disabled RQM only during DMA transfers */
  827. return FD_PHASE_EXECUTION;
  828. } else if (fdctrl->msr & FD_MSR_DIO) {
  829. return FD_PHASE_RESULT;
  830. } else {
  831. return FD_PHASE_COMMAND;
  832. }
  833. }
  834. static int fdc_pre_save(void *opaque)
  835. {
  836. FDCtrl *s = opaque;
  837. s->dor_vmstate = s->dor | GET_CUR_DRV(s);
  838. return 0;
  839. }
  840. static int fdc_pre_load(void *opaque)
  841. {
  842. FDCtrl *s = opaque;
  843. s->phase = FD_PHASE_RECONSTRUCT;
  844. return 0;
  845. }
  846. static int fdc_post_load(void *opaque, int version_id)
  847. {
  848. FDCtrl *s = opaque;
  849. SET_CUR_DRV(s, s->dor_vmstate & FD_DOR_SELMASK);
  850. s->dor = s->dor_vmstate & ~FD_DOR_SELMASK;
  851. if (s->phase == FD_PHASE_RECONSTRUCT) {
  852. s->phase = reconstruct_phase(s);
  853. }
  854. return 0;
  855. }
  856. static bool fdc_reset_sensei_needed(void *opaque)
  857. {
  858. FDCtrl *s = opaque;
  859. return s->reset_sensei != 0;
  860. }
  861. static const VMStateDescription vmstate_fdc_reset_sensei = {
  862. .name = "fdc/reset_sensei",
  863. .version_id = 1,
  864. .minimum_version_id = 1,
  865. .needed = fdc_reset_sensei_needed,
  866. .fields = (const VMStateField[]) {
  867. VMSTATE_INT32(reset_sensei, FDCtrl),
  868. VMSTATE_END_OF_LIST()
  869. }
  870. };
  871. static bool fdc_result_timer_needed(void *opaque)
  872. {
  873. FDCtrl *s = opaque;
  874. return timer_pending(s->result_timer);
  875. }
  876. static const VMStateDescription vmstate_fdc_result_timer = {
  877. .name = "fdc/result_timer",
  878. .version_id = 1,
  879. .minimum_version_id = 1,
  880. .needed = fdc_result_timer_needed,
  881. .fields = (const VMStateField[]) {
  882. VMSTATE_TIMER_PTR(result_timer, FDCtrl),
  883. VMSTATE_END_OF_LIST()
  884. }
  885. };
  886. static bool fdc_phase_needed(void *opaque)
  887. {
  888. FDCtrl *fdctrl = opaque;
  889. return reconstruct_phase(fdctrl) != fdctrl->phase;
  890. }
  891. static const VMStateDescription vmstate_fdc_phase = {
  892. .name = "fdc/phase",
  893. .version_id = 1,
  894. .minimum_version_id = 1,
  895. .needed = fdc_phase_needed,
  896. .fields = (const VMStateField[]) {
  897. VMSTATE_UINT8(phase, FDCtrl),
  898. VMSTATE_END_OF_LIST()
  899. }
  900. };
  901. const VMStateDescription vmstate_fdc = {
  902. .name = "fdc",
  903. .version_id = 2,
  904. .minimum_version_id = 2,
  905. .pre_save = fdc_pre_save,
  906. .pre_load = fdc_pre_load,
  907. .post_load = fdc_post_load,
  908. .fields = (const VMStateField[]) {
  909. /* Controller State */
  910. VMSTATE_UINT8(sra, FDCtrl),
  911. VMSTATE_UINT8(srb, FDCtrl),
  912. VMSTATE_UINT8(dor_vmstate, FDCtrl),
  913. VMSTATE_UINT8(tdr, FDCtrl),
  914. VMSTATE_UINT8(dsr, FDCtrl),
  915. VMSTATE_UINT8(msr, FDCtrl),
  916. VMSTATE_UINT8(status0, FDCtrl),
  917. VMSTATE_UINT8(status1, FDCtrl),
  918. VMSTATE_UINT8(status2, FDCtrl),
  919. /* Command FIFO */
  920. VMSTATE_VARRAY_INT32(fifo, FDCtrl, fifo_size, 0, vmstate_info_uint8,
  921. uint8_t),
  922. VMSTATE_UINT32(data_pos, FDCtrl),
  923. VMSTATE_UINT32(data_len, FDCtrl),
  924. VMSTATE_UINT8(data_state, FDCtrl),
  925. VMSTATE_UINT8(data_dir, FDCtrl),
  926. VMSTATE_UINT8(eot, FDCtrl),
  927. /* States kept only to be returned back */
  928. VMSTATE_UINT8(timer0, FDCtrl),
  929. VMSTATE_UINT8(timer1, FDCtrl),
  930. VMSTATE_UINT8(precomp_trk, FDCtrl),
  931. VMSTATE_UINT8(config, FDCtrl),
  932. VMSTATE_UINT8(lock, FDCtrl),
  933. VMSTATE_UINT8(pwrd, FDCtrl),
  934. VMSTATE_UINT8_EQUAL(num_floppies, FDCtrl, NULL),
  935. VMSTATE_STRUCT_ARRAY(drives, FDCtrl, MAX_FD, 1,
  936. vmstate_fdrive, FDrive),
  937. VMSTATE_END_OF_LIST()
  938. },
  939. .subsections = (const VMStateDescription * const []) {
  940. &vmstate_fdc_reset_sensei,
  941. &vmstate_fdc_result_timer,
  942. &vmstate_fdc_phase,
  943. NULL
  944. }
  945. };
  946. /* Change IRQ state */
  947. static void fdctrl_reset_irq(FDCtrl *fdctrl)
  948. {
  949. fdctrl->status0 = 0;
  950. if (!(fdctrl->sra & FD_SRA_INTPEND))
  951. return;
  952. FLOPPY_DPRINTF("Reset interrupt\n");
  953. qemu_set_irq(fdctrl->irq, 0);
  954. fdctrl->sra &= ~FD_SRA_INTPEND;
  955. }
  956. static void fdctrl_raise_irq(FDCtrl *fdctrl)
  957. {
  958. if (!(fdctrl->sra & FD_SRA_INTPEND)) {
  959. qemu_set_irq(fdctrl->irq, 1);
  960. fdctrl->sra |= FD_SRA_INTPEND;
  961. }
  962. fdctrl->reset_sensei = 0;
  963. FLOPPY_DPRINTF("Set interrupt status to 0x%02x\n", fdctrl->status0);
  964. }
  965. /* Reset controller */
  966. void fdctrl_reset(FDCtrl *fdctrl, int do_irq)
  967. {
  968. int i;
  969. FLOPPY_DPRINTF("reset controller\n");
  970. fdctrl_reset_irq(fdctrl);
  971. /* Initialise controller */
  972. fdctrl->sra = 0;
  973. fdctrl->srb = 0xc0;
  974. if (!fdctrl->drives[1].blk) {
  975. fdctrl->sra |= FD_SRA_nDRV2;
  976. }
  977. fdctrl->cur_drv = 0;
  978. fdctrl->dor = FD_DOR_nRESET;
  979. fdctrl->dor |= (fdctrl->dma_chann != -1) ? FD_DOR_DMAEN : 0;
  980. fdctrl->msr = FD_MSR_RQM;
  981. fdctrl->reset_sensei = 0;
  982. timer_del(fdctrl->result_timer);
  983. /* FIFO state */
  984. fdctrl->data_pos = 0;
  985. fdctrl->data_len = 0;
  986. fdctrl->data_state = 0;
  987. fdctrl->data_dir = FD_DIR_WRITE;
  988. for (i = 0; i < MAX_FD; i++)
  989. fd_recalibrate(&fdctrl->drives[i]);
  990. fdctrl_to_command_phase(fdctrl);
  991. if (do_irq) {
  992. fdctrl->status0 |= FD_SR0_RDYCHG;
  993. fdctrl_raise_irq(fdctrl);
  994. fdctrl->reset_sensei = FD_RESET_SENSEI_COUNT;
  995. }
  996. }
  997. static inline FDrive *drv0(FDCtrl *fdctrl)
  998. {
  999. return &fdctrl->drives[(fdctrl->tdr & FD_TDR_BOOTSEL) >> 2];
  1000. }
  1001. static inline FDrive *drv1(FDCtrl *fdctrl)
  1002. {
  1003. if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (1 << 2))
  1004. return &fdctrl->drives[1];
  1005. else
  1006. return &fdctrl->drives[0];
  1007. }
  1008. #if MAX_FD == 4
  1009. static inline FDrive *drv2(FDCtrl *fdctrl)
  1010. {
  1011. if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (2 << 2))
  1012. return &fdctrl->drives[2];
  1013. else
  1014. return &fdctrl->drives[1];
  1015. }
  1016. static inline FDrive *drv3(FDCtrl *fdctrl)
  1017. {
  1018. if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (3 << 2))
  1019. return &fdctrl->drives[3];
  1020. else
  1021. return &fdctrl->drives[2];
  1022. }
  1023. #endif
  1024. static FDrive *get_drv(FDCtrl *fdctrl, int unit)
  1025. {
  1026. switch (unit) {
  1027. case 0: return drv0(fdctrl);
  1028. case 1: return drv1(fdctrl);
  1029. #if MAX_FD == 4
  1030. case 2: return drv2(fdctrl);
  1031. case 3: return drv3(fdctrl);
  1032. #endif
  1033. default: return NULL;
  1034. }
  1035. }
  1036. static FDrive *get_cur_drv(FDCtrl *fdctrl)
  1037. {
  1038. FDrive *cur_drv = get_drv(fdctrl, fdctrl->cur_drv);
  1039. if (!cur_drv->blk) {
  1040. /*
  1041. * Kludge: empty drive line selected. Create an anonymous
  1042. * BlockBackend to avoid NULL deref with various BlockBackend
  1043. * API calls within this model (CVE-2021-20196).
  1044. * Due to the controller QOM model limitations, we don't
  1045. * attach the created to the controller device.
  1046. */
  1047. cur_drv->blk = blk_create_empty_drive();
  1048. }
  1049. return cur_drv;
  1050. }
  1051. /* Status A register : 0x00 (read-only) */
  1052. static uint32_t fdctrl_read_statusA(FDCtrl *fdctrl)
  1053. {
  1054. uint32_t retval = fdctrl->sra;
  1055. FLOPPY_DPRINTF("status register A: 0x%02x\n", retval);
  1056. return retval;
  1057. }
  1058. /* Status B register : 0x01 (read-only) */
  1059. static uint32_t fdctrl_read_statusB(FDCtrl *fdctrl)
  1060. {
  1061. uint32_t retval = fdctrl->srb;
  1062. FLOPPY_DPRINTF("status register B: 0x%02x\n", retval);
  1063. return retval;
  1064. }
  1065. /* Digital output register : 0x02 */
  1066. static uint32_t fdctrl_read_dor(FDCtrl *fdctrl)
  1067. {
  1068. uint32_t retval = fdctrl->dor;
  1069. /* Selected drive */
  1070. retval |= fdctrl->cur_drv;
  1071. FLOPPY_DPRINTF("digital output register: 0x%02x\n", retval);
  1072. return retval;
  1073. }
  1074. static void fdctrl_write_dor(FDCtrl *fdctrl, uint32_t value)
  1075. {
  1076. FLOPPY_DPRINTF("digital output register set to 0x%02x\n", value);
  1077. /* Motors */
  1078. if (value & FD_DOR_MOTEN0)
  1079. fdctrl->srb |= FD_SRB_MTR0;
  1080. else
  1081. fdctrl->srb &= ~FD_SRB_MTR0;
  1082. if (value & FD_DOR_MOTEN1)
  1083. fdctrl->srb |= FD_SRB_MTR1;
  1084. else
  1085. fdctrl->srb &= ~FD_SRB_MTR1;
  1086. /* Drive */
  1087. if (value & 1)
  1088. fdctrl->srb |= FD_SRB_DR0;
  1089. else
  1090. fdctrl->srb &= ~FD_SRB_DR0;
  1091. /* Reset */
  1092. if (!(value & FD_DOR_nRESET)) {
  1093. if (fdctrl->dor & FD_DOR_nRESET) {
  1094. FLOPPY_DPRINTF("controller enter RESET state\n");
  1095. }
  1096. } else {
  1097. if (!(fdctrl->dor & FD_DOR_nRESET)) {
  1098. FLOPPY_DPRINTF("controller out of RESET state\n");
  1099. fdctrl_reset(fdctrl, 1);
  1100. fdctrl->dsr &= ~FD_DSR_PWRDOWN;
  1101. }
  1102. }
  1103. /* Selected drive */
  1104. fdctrl->cur_drv = value & FD_DOR_SELMASK;
  1105. fdctrl->dor = value;
  1106. }
  1107. /* Tape drive register : 0x03 */
  1108. static uint32_t fdctrl_read_tape(FDCtrl *fdctrl)
  1109. {
  1110. uint32_t retval = fdctrl->tdr;
  1111. FLOPPY_DPRINTF("tape drive register: 0x%02x\n", retval);
  1112. return retval;
  1113. }
  1114. static void fdctrl_write_tape(FDCtrl *fdctrl, uint32_t value)
  1115. {
  1116. /* Reset mode */
  1117. if (!(fdctrl->dor & FD_DOR_nRESET)) {
  1118. FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
  1119. return;
  1120. }
  1121. FLOPPY_DPRINTF("tape drive register set to 0x%02x\n", value);
  1122. /* Disk boot selection indicator */
  1123. fdctrl->tdr = value & FD_TDR_BOOTSEL;
  1124. /* Tape indicators: never allow */
  1125. }
  1126. /* Main status register : 0x04 (read) */
  1127. static uint32_t fdctrl_read_main_status(FDCtrl *fdctrl)
  1128. {
  1129. uint32_t retval = fdctrl->msr;
  1130. fdctrl->dsr &= ~FD_DSR_PWRDOWN;
  1131. fdctrl->dor |= FD_DOR_nRESET;
  1132. FLOPPY_DPRINTF("main status register: 0x%02x\n", retval);
  1133. return retval;
  1134. }
  1135. /* Data select rate register : 0x04 (write) */
  1136. static void fdctrl_write_rate(FDCtrl *fdctrl, uint32_t value)
  1137. {
  1138. /* Reset mode */
  1139. if (!(fdctrl->dor & FD_DOR_nRESET)) {
  1140. FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
  1141. return;
  1142. }
  1143. FLOPPY_DPRINTF("select rate register set to 0x%02x\n", value);
  1144. /* Reset: autoclear */
  1145. if (value & FD_DSR_SWRESET) {
  1146. fdctrl->dor &= ~FD_DOR_nRESET;
  1147. fdctrl_reset(fdctrl, 1);
  1148. fdctrl->dor |= FD_DOR_nRESET;
  1149. }
  1150. if (value & FD_DSR_PWRDOWN) {
  1151. fdctrl_reset(fdctrl, 1);
  1152. }
  1153. fdctrl->dsr = value;
  1154. }
  1155. /* Configuration control register: 0x07 (write) */
  1156. static void fdctrl_write_ccr(FDCtrl *fdctrl, uint32_t value)
  1157. {
  1158. /* Reset mode */
  1159. if (!(fdctrl->dor & FD_DOR_nRESET)) {
  1160. FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
  1161. return;
  1162. }
  1163. FLOPPY_DPRINTF("configuration control register set to 0x%02x\n", value);
  1164. /* Only the rate selection bits used in AT mode, and we
  1165. * store those in the DSR.
  1166. */
  1167. fdctrl->dsr = (fdctrl->dsr & ~FD_DSR_DRATEMASK) |
  1168. (value & FD_DSR_DRATEMASK);
  1169. }
  1170. static int fdctrl_media_changed(FDrive *drv)
  1171. {
  1172. return drv->media_changed;
  1173. }
  1174. /* Digital input register : 0x07 (read-only) */
  1175. static uint32_t fdctrl_read_dir(FDCtrl *fdctrl)
  1176. {
  1177. uint32_t retval = 0;
  1178. if (fdctrl_media_changed(get_cur_drv(fdctrl))) {
  1179. retval |= FD_DIR_DSKCHG;
  1180. }
  1181. if (retval != 0) {
  1182. FLOPPY_DPRINTF("Floppy digital input register: 0x%02x\n", retval);
  1183. }
  1184. return retval;
  1185. }
  1186. /* Clear the FIFO and update the state for receiving the next command */
  1187. static void fdctrl_to_command_phase(FDCtrl *fdctrl)
  1188. {
  1189. fdctrl->phase = FD_PHASE_COMMAND;
  1190. fdctrl->data_dir = FD_DIR_WRITE;
  1191. fdctrl->data_pos = 0;
  1192. fdctrl->data_len = 1; /* Accept command byte, adjust for params later */
  1193. fdctrl->msr &= ~(FD_MSR_CMDBUSY | FD_MSR_DIO);
  1194. fdctrl->msr |= FD_MSR_RQM;
  1195. }
  1196. /* Update the state to allow the guest to read out the command status.
  1197. * @fifo_len is the number of result bytes to be read out. */
  1198. static void fdctrl_to_result_phase(FDCtrl *fdctrl, int fifo_len)
  1199. {
  1200. fdctrl->phase = FD_PHASE_RESULT;
  1201. fdctrl->data_dir = FD_DIR_READ;
  1202. fdctrl->data_len = fifo_len;
  1203. fdctrl->data_pos = 0;
  1204. fdctrl->msr |= FD_MSR_CMDBUSY | FD_MSR_RQM | FD_MSR_DIO;
  1205. }
  1206. /* Set an error: unimplemented/unknown command */
  1207. static void fdctrl_unimplemented(FDCtrl *fdctrl, int direction)
  1208. {
  1209. qemu_log_mask(LOG_UNIMP, "fdc: unimplemented command 0x%02x\n",
  1210. fdctrl->fifo[0]);
  1211. fdctrl->fifo[0] = FD_SR0_INVCMD;
  1212. fdctrl_to_result_phase(fdctrl, 1);
  1213. }
  1214. /* Seek to next sector
  1215. * returns 0 when end of track reached (for DBL_SIDES on head 1)
  1216. * otherwise returns 1
  1217. */
  1218. static int fdctrl_seek_to_next_sect(FDCtrl *fdctrl, FDrive *cur_drv)
  1219. {
  1220. FLOPPY_DPRINTF("seek to next sector (%d %02x %02x => %d)\n",
  1221. cur_drv->head, cur_drv->track, cur_drv->sect,
  1222. fd_sector(cur_drv));
  1223. /* XXX: cur_drv->sect >= cur_drv->last_sect should be an
  1224. error in fact */
  1225. uint8_t new_head = cur_drv->head;
  1226. uint8_t new_track = cur_drv->track;
  1227. uint8_t new_sect = cur_drv->sect;
  1228. int ret = 1;
  1229. if (new_sect >= cur_drv->last_sect ||
  1230. new_sect == fdctrl->eot) {
  1231. new_sect = 1;
  1232. if (FD_MULTI_TRACK(fdctrl->data_state)) {
  1233. if (new_head == 0 &&
  1234. (cur_drv->flags & FDISK_DBL_SIDES) != 0) {
  1235. new_head = 1;
  1236. } else {
  1237. new_head = 0;
  1238. new_track++;
  1239. fdctrl->status0 |= FD_SR0_SEEK;
  1240. if ((cur_drv->flags & FDISK_DBL_SIDES) == 0) {
  1241. ret = 0;
  1242. }
  1243. }
  1244. } else {
  1245. fdctrl->status0 |= FD_SR0_SEEK;
  1246. new_track++;
  1247. ret = 0;
  1248. }
  1249. if (ret == 1) {
  1250. FLOPPY_DPRINTF("seek to next track (%d %02x %02x => %d)\n",
  1251. new_head, new_track, new_sect, fd_sector(cur_drv));
  1252. }
  1253. } else {
  1254. new_sect++;
  1255. }
  1256. fd_seek(cur_drv, new_head, new_track, new_sect, 1);
  1257. return ret;
  1258. }
  1259. /* Callback for transfer end (stop or abort) */
  1260. static void fdctrl_stop_transfer(FDCtrl *fdctrl, uint8_t status0,
  1261. uint8_t status1, uint8_t status2)
  1262. {
  1263. FDrive *cur_drv;
  1264. cur_drv = get_cur_drv(fdctrl);
  1265. fdctrl->status0 &= ~(FD_SR0_DS0 | FD_SR0_DS1 | FD_SR0_HEAD);
  1266. fdctrl->status0 |= GET_CUR_DRV(fdctrl);
  1267. if (cur_drv->head) {
  1268. fdctrl->status0 |= FD_SR0_HEAD;
  1269. }
  1270. fdctrl->status0 |= status0;
  1271. FLOPPY_DPRINTF("transfer status: %02x %02x %02x (%02x)\n",
  1272. status0, status1, status2, fdctrl->status0);
  1273. fdctrl->fifo[0] = fdctrl->status0;
  1274. fdctrl->fifo[1] = status1;
  1275. fdctrl->fifo[2] = status2;
  1276. fdctrl->fifo[3] = cur_drv->track;
  1277. fdctrl->fifo[4] = cur_drv->head;
  1278. fdctrl->fifo[5] = cur_drv->sect;
  1279. fdctrl->fifo[6] = FD_SECTOR_SC;
  1280. fdctrl->data_dir = FD_DIR_READ;
  1281. if (fdctrl->dma_chann != -1 && !(fdctrl->msr & FD_MSR_NONDMA)) {
  1282. IsaDmaClass *k = ISADMA_GET_CLASS(fdctrl->dma);
  1283. k->release_DREQ(fdctrl->dma, fdctrl->dma_chann);
  1284. }
  1285. fdctrl->msr |= FD_MSR_RQM | FD_MSR_DIO;
  1286. fdctrl->msr &= ~FD_MSR_NONDMA;
  1287. fdctrl_to_result_phase(fdctrl, 7);
  1288. fdctrl_raise_irq(fdctrl);
  1289. }
  1290. /* Prepare a data transfer (either DMA or FIFO) */
  1291. static void fdctrl_start_transfer(FDCtrl *fdctrl, int direction)
  1292. {
  1293. FDrive *cur_drv;
  1294. uint8_t kh, kt, ks;
  1295. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1296. cur_drv = get_cur_drv(fdctrl);
  1297. kt = fdctrl->fifo[2];
  1298. kh = fdctrl->fifo[3];
  1299. ks = fdctrl->fifo[4];
  1300. FLOPPY_DPRINTF("Start transfer at %d %d %02x %02x (%d)\n",
  1301. GET_CUR_DRV(fdctrl), kh, kt, ks,
  1302. fd_sector_calc(kh, kt, ks, cur_drv->last_sect,
  1303. NUM_SIDES(cur_drv)));
  1304. switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) {
  1305. case 2:
  1306. /* sect too big */
  1307. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
  1308. fdctrl->fifo[3] = kt;
  1309. fdctrl->fifo[4] = kh;
  1310. fdctrl->fifo[5] = ks;
  1311. return;
  1312. case 3:
  1313. /* track too big */
  1314. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_EC, 0x00);
  1315. fdctrl->fifo[3] = kt;
  1316. fdctrl->fifo[4] = kh;
  1317. fdctrl->fifo[5] = ks;
  1318. return;
  1319. case 4:
  1320. /* No seek enabled */
  1321. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
  1322. fdctrl->fifo[3] = kt;
  1323. fdctrl->fifo[4] = kh;
  1324. fdctrl->fifo[5] = ks;
  1325. return;
  1326. case 1:
  1327. fdctrl->status0 |= FD_SR0_SEEK;
  1328. break;
  1329. default:
  1330. break;
  1331. }
  1332. /* Check the data rate. If the programmed data rate does not match
  1333. * the currently inserted medium, the operation has to fail. */
  1334. if ((fdctrl->dsr & FD_DSR_DRATEMASK) != cur_drv->media_rate) {
  1335. FLOPPY_DPRINTF("data rate mismatch (fdc=%d, media=%d)\n",
  1336. fdctrl->dsr & FD_DSR_DRATEMASK, cur_drv->media_rate);
  1337. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00);
  1338. fdctrl->fifo[3] = kt;
  1339. fdctrl->fifo[4] = kh;
  1340. fdctrl->fifo[5] = ks;
  1341. return;
  1342. }
  1343. /* Set the FIFO state */
  1344. fdctrl->data_dir = direction;
  1345. fdctrl->data_pos = 0;
  1346. assert(fdctrl->msr & FD_MSR_CMDBUSY);
  1347. if (fdctrl->fifo[0] & 0x80)
  1348. fdctrl->data_state |= FD_STATE_MULTI;
  1349. else
  1350. fdctrl->data_state &= ~FD_STATE_MULTI;
  1351. if (fdctrl->fifo[5] == 0) {
  1352. fdctrl->data_len = fdctrl->fifo[8];
  1353. } else {
  1354. int tmp;
  1355. fdctrl->data_len = 128 << (fdctrl->fifo[5] > 7 ? 7 : fdctrl->fifo[5]);
  1356. tmp = (fdctrl->fifo[6] - ks + 1);
  1357. if (tmp < 0) {
  1358. FLOPPY_DPRINTF("invalid EOT: %d\n", tmp);
  1359. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00);
  1360. fdctrl->fifo[3] = kt;
  1361. fdctrl->fifo[4] = kh;
  1362. fdctrl->fifo[5] = ks;
  1363. return;
  1364. }
  1365. if (fdctrl->fifo[0] & 0x80)
  1366. tmp += fdctrl->fifo[6];
  1367. fdctrl->data_len *= tmp;
  1368. }
  1369. fdctrl->eot = fdctrl->fifo[6];
  1370. if (fdctrl->dor & FD_DOR_DMAEN) {
  1371. /* DMA transfer is enabled. */
  1372. IsaDmaClass *k = ISADMA_GET_CLASS(fdctrl->dma);
  1373. FLOPPY_DPRINTF("direction=%d (%d - %d)\n",
  1374. direction, (128 << fdctrl->fifo[5]) *
  1375. (cur_drv->last_sect - ks + 1), fdctrl->data_len);
  1376. /* No access is allowed until DMA transfer has completed */
  1377. fdctrl->msr &= ~FD_MSR_RQM;
  1378. if (direction != FD_DIR_VERIFY) {
  1379. /*
  1380. * Now, we just have to wait for the DMA controller to
  1381. * recall us...
  1382. */
  1383. k->hold_DREQ(fdctrl->dma, fdctrl->dma_chann);
  1384. k->schedule(fdctrl->dma);
  1385. } else {
  1386. /* Start transfer */
  1387. fdctrl_transfer_handler(fdctrl, fdctrl->dma_chann, 0,
  1388. fdctrl->data_len);
  1389. }
  1390. return;
  1391. }
  1392. FLOPPY_DPRINTF("start non-DMA transfer\n");
  1393. fdctrl->msr |= FD_MSR_NONDMA | FD_MSR_RQM;
  1394. if (direction != FD_DIR_WRITE)
  1395. fdctrl->msr |= FD_MSR_DIO;
  1396. /* IO based transfer: calculate len */
  1397. fdctrl_raise_irq(fdctrl);
  1398. }
  1399. /* Prepare a transfer of deleted data */
  1400. static void fdctrl_start_transfer_del(FDCtrl *fdctrl, int direction)
  1401. {
  1402. qemu_log_mask(LOG_UNIMP, "fdctrl_start_transfer_del() unimplemented\n");
  1403. /* We don't handle deleted data,
  1404. * so we don't return *ANYTHING*
  1405. */
  1406. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
  1407. }
  1408. /* handlers for DMA transfers */
  1409. int fdctrl_transfer_handler(void *opaque, int nchan, int dma_pos, int dma_len)
  1410. {
  1411. FDCtrl *fdctrl;
  1412. FDrive *cur_drv;
  1413. int len, start_pos, rel_pos;
  1414. uint8_t status0 = 0x00, status1 = 0x00, status2 = 0x00;
  1415. IsaDmaClass *k;
  1416. fdctrl = opaque;
  1417. if (fdctrl->msr & FD_MSR_RQM) {
  1418. FLOPPY_DPRINTF("Not in DMA transfer mode !\n");
  1419. return 0;
  1420. }
  1421. k = ISADMA_GET_CLASS(fdctrl->dma);
  1422. cur_drv = get_cur_drv(fdctrl);
  1423. if (fdctrl->data_dir == FD_DIR_SCANE || fdctrl->data_dir == FD_DIR_SCANL ||
  1424. fdctrl->data_dir == FD_DIR_SCANH)
  1425. status2 = FD_SR2_SNS;
  1426. if (dma_len > fdctrl->data_len)
  1427. dma_len = fdctrl->data_len;
  1428. if (cur_drv->blk == NULL) {
  1429. if (fdctrl->data_dir == FD_DIR_WRITE)
  1430. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
  1431. else
  1432. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
  1433. len = 0;
  1434. goto transfer_error;
  1435. }
  1436. rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
  1437. for (start_pos = fdctrl->data_pos; fdctrl->data_pos < dma_len;) {
  1438. len = dma_len - fdctrl->data_pos;
  1439. if (len + rel_pos > FD_SECTOR_LEN)
  1440. len = FD_SECTOR_LEN - rel_pos;
  1441. FLOPPY_DPRINTF("copy %d bytes (%d %d %d) %d pos %d %02x "
  1442. "(%d-0x%08x 0x%08x)\n", len, dma_len, fdctrl->data_pos,
  1443. fdctrl->data_len, GET_CUR_DRV(fdctrl), cur_drv->head,
  1444. cur_drv->track, cur_drv->sect, fd_sector(cur_drv),
  1445. fd_sector(cur_drv) * FD_SECTOR_LEN);
  1446. if (fdctrl->data_dir != FD_DIR_WRITE ||
  1447. len < FD_SECTOR_LEN || rel_pos != 0) {
  1448. /* READ & SCAN commands and realign to a sector for WRITE */
  1449. if (blk_pread(cur_drv->blk, fd_offset(cur_drv), BDRV_SECTOR_SIZE,
  1450. fdctrl->fifo, 0) < 0) {
  1451. FLOPPY_DPRINTF("Floppy: error getting sector %d\n",
  1452. fd_sector(cur_drv));
  1453. /* Sure, image size is too small... */
  1454. memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
  1455. }
  1456. }
  1457. switch (fdctrl->data_dir) {
  1458. case FD_DIR_READ:
  1459. /* READ commands */
  1460. k->write_memory(fdctrl->dma, nchan, fdctrl->fifo + rel_pos,
  1461. fdctrl->data_pos, len);
  1462. break;
  1463. case FD_DIR_WRITE:
  1464. /* WRITE commands */
  1465. if (cur_drv->ro) {
  1466. /* Handle readonly medium early, no need to do DMA, touch the
  1467. * LED or attempt any writes. A real floppy doesn't attempt
  1468. * to write to readonly media either. */
  1469. fdctrl_stop_transfer(fdctrl,
  1470. FD_SR0_ABNTERM | FD_SR0_SEEK, FD_SR1_NW,
  1471. 0x00);
  1472. goto transfer_error;
  1473. }
  1474. k->read_memory(fdctrl->dma, nchan, fdctrl->fifo + rel_pos,
  1475. fdctrl->data_pos, len);
  1476. if (blk_pwrite(cur_drv->blk, fd_offset(cur_drv), BDRV_SECTOR_SIZE,
  1477. fdctrl->fifo, 0) < 0) {
  1478. FLOPPY_DPRINTF("error writing sector %d\n",
  1479. fd_sector(cur_drv));
  1480. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
  1481. goto transfer_error;
  1482. }
  1483. break;
  1484. case FD_DIR_VERIFY:
  1485. /* VERIFY commands */
  1486. break;
  1487. default:
  1488. /* SCAN commands */
  1489. {
  1490. uint8_t tmpbuf[FD_SECTOR_LEN];
  1491. int ret;
  1492. k->read_memory(fdctrl->dma, nchan, tmpbuf, fdctrl->data_pos,
  1493. len);
  1494. ret = memcmp(tmpbuf, fdctrl->fifo + rel_pos, len);
  1495. if (ret == 0) {
  1496. status2 = FD_SR2_SEH;
  1497. goto end_transfer;
  1498. }
  1499. if ((ret < 0 && fdctrl->data_dir == FD_DIR_SCANL) ||
  1500. (ret > 0 && fdctrl->data_dir == FD_DIR_SCANH)) {
  1501. status2 = 0x00;
  1502. goto end_transfer;
  1503. }
  1504. }
  1505. break;
  1506. }
  1507. fdctrl->data_pos += len;
  1508. rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
  1509. if (rel_pos == 0) {
  1510. /* Seek to next sector */
  1511. if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv))
  1512. break;
  1513. }
  1514. }
  1515. end_transfer:
  1516. len = fdctrl->data_pos - start_pos;
  1517. FLOPPY_DPRINTF("end transfer %d %d %d\n",
  1518. fdctrl->data_pos, len, fdctrl->data_len);
  1519. if (fdctrl->data_dir == FD_DIR_SCANE ||
  1520. fdctrl->data_dir == FD_DIR_SCANL ||
  1521. fdctrl->data_dir == FD_DIR_SCANH)
  1522. status2 = FD_SR2_SEH;
  1523. fdctrl->data_len -= len;
  1524. fdctrl_stop_transfer(fdctrl, status0, status1, status2);
  1525. transfer_error:
  1526. return len;
  1527. }
  1528. /* Data register : 0x05 */
  1529. static uint32_t fdctrl_read_data(FDCtrl *fdctrl)
  1530. {
  1531. FDrive *cur_drv;
  1532. uint32_t retval = 0;
  1533. uint32_t pos;
  1534. cur_drv = get_cur_drv(fdctrl);
  1535. fdctrl->dsr &= ~FD_DSR_PWRDOWN;
  1536. if (!(fdctrl->msr & FD_MSR_RQM) || !(fdctrl->msr & FD_MSR_DIO)) {
  1537. FLOPPY_DPRINTF("error: controller not ready for reading\n");
  1538. return 0;
  1539. }
  1540. /* If data_len spans multiple sectors, the current position in the FIFO
  1541. * wraps around while fdctrl->data_pos is the real position in the whole
  1542. * request. */
  1543. pos = fdctrl->data_pos;
  1544. pos %= FD_SECTOR_LEN;
  1545. switch (fdctrl->phase) {
  1546. case FD_PHASE_EXECUTION:
  1547. assert(fdctrl->msr & FD_MSR_NONDMA);
  1548. if (pos == 0) {
  1549. if (fdctrl->data_pos != 0)
  1550. if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
  1551. FLOPPY_DPRINTF("error seeking to next sector %d\n",
  1552. fd_sector(cur_drv));
  1553. return 0;
  1554. }
  1555. if (blk_pread(cur_drv->blk, fd_offset(cur_drv), BDRV_SECTOR_SIZE,
  1556. fdctrl->fifo, 0)
  1557. < 0) {
  1558. FLOPPY_DPRINTF("error getting sector %d\n",
  1559. fd_sector(cur_drv));
  1560. /* Sure, image size is too small... */
  1561. memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
  1562. }
  1563. }
  1564. if (++fdctrl->data_pos == fdctrl->data_len) {
  1565. fdctrl->msr &= ~FD_MSR_RQM;
  1566. fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
  1567. }
  1568. break;
  1569. case FD_PHASE_RESULT:
  1570. assert(!(fdctrl->msr & FD_MSR_NONDMA));
  1571. if (++fdctrl->data_pos == fdctrl->data_len) {
  1572. fdctrl->msr &= ~FD_MSR_RQM;
  1573. fdctrl_to_command_phase(fdctrl);
  1574. fdctrl_reset_irq(fdctrl);
  1575. }
  1576. break;
  1577. case FD_PHASE_COMMAND:
  1578. default:
  1579. abort();
  1580. }
  1581. retval = fdctrl->fifo[pos];
  1582. FLOPPY_DPRINTF("data register: 0x%02x\n", retval);
  1583. return retval;
  1584. }
  1585. static void fdctrl_format_sector(FDCtrl *fdctrl)
  1586. {
  1587. FDrive *cur_drv;
  1588. uint8_t kh, kt, ks;
  1589. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1590. cur_drv = get_cur_drv(fdctrl);
  1591. kt = fdctrl->fifo[6];
  1592. kh = fdctrl->fifo[7];
  1593. ks = fdctrl->fifo[8];
  1594. FLOPPY_DPRINTF("format sector at %d %d %02x %02x (%d)\n",
  1595. GET_CUR_DRV(fdctrl), kh, kt, ks,
  1596. fd_sector_calc(kh, kt, ks, cur_drv->last_sect,
  1597. NUM_SIDES(cur_drv)));
  1598. switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) {
  1599. case 2:
  1600. /* sect too big */
  1601. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
  1602. fdctrl->fifo[3] = kt;
  1603. fdctrl->fifo[4] = kh;
  1604. fdctrl->fifo[5] = ks;
  1605. return;
  1606. case 3:
  1607. /* track too big */
  1608. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_EC, 0x00);
  1609. fdctrl->fifo[3] = kt;
  1610. fdctrl->fifo[4] = kh;
  1611. fdctrl->fifo[5] = ks;
  1612. return;
  1613. case 4:
  1614. /* No seek enabled */
  1615. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
  1616. fdctrl->fifo[3] = kt;
  1617. fdctrl->fifo[4] = kh;
  1618. fdctrl->fifo[5] = ks;
  1619. return;
  1620. case 1:
  1621. fdctrl->status0 |= FD_SR0_SEEK;
  1622. break;
  1623. default:
  1624. break;
  1625. }
  1626. memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
  1627. if (cur_drv->blk == NULL ||
  1628. blk_pwrite(cur_drv->blk, fd_offset(cur_drv), BDRV_SECTOR_SIZE,
  1629. fdctrl->fifo, 0) < 0) {
  1630. FLOPPY_DPRINTF("error formatting sector %d\n", fd_sector(cur_drv));
  1631. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
  1632. } else {
  1633. if (cur_drv->sect == cur_drv->last_sect) {
  1634. fdctrl->data_state &= ~FD_STATE_FORMAT;
  1635. /* Last sector done */
  1636. fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
  1637. } else {
  1638. /* More to do */
  1639. fdctrl->data_pos = 0;
  1640. fdctrl->data_len = 4;
  1641. }
  1642. }
  1643. }
  1644. static void fdctrl_handle_lock(FDCtrl *fdctrl, int direction)
  1645. {
  1646. fdctrl->lock = (fdctrl->fifo[0] & 0x80) ? 1 : 0;
  1647. fdctrl->fifo[0] = fdctrl->lock << 4;
  1648. fdctrl_to_result_phase(fdctrl, 1);
  1649. }
  1650. static void fdctrl_handle_dumpreg(FDCtrl *fdctrl, int direction)
  1651. {
  1652. FDrive *cur_drv = get_cur_drv(fdctrl);
  1653. /* Drives position */
  1654. fdctrl->fifo[0] = drv0(fdctrl)->track;
  1655. fdctrl->fifo[1] = drv1(fdctrl)->track;
  1656. #if MAX_FD == 4
  1657. fdctrl->fifo[2] = drv2(fdctrl)->track;
  1658. fdctrl->fifo[3] = drv3(fdctrl)->track;
  1659. #else
  1660. fdctrl->fifo[2] = 0;
  1661. fdctrl->fifo[3] = 0;
  1662. #endif
  1663. /* timers */
  1664. fdctrl->fifo[4] = fdctrl->timer0;
  1665. fdctrl->fifo[5] = (fdctrl->timer1 << 1) | (fdctrl->dor & FD_DOR_DMAEN ? 1 : 0);
  1666. fdctrl->fifo[6] = cur_drv->last_sect;
  1667. fdctrl->fifo[7] = (fdctrl->lock << 7) |
  1668. (cur_drv->perpendicular << 2);
  1669. fdctrl->fifo[8] = fdctrl->config;
  1670. fdctrl->fifo[9] = fdctrl->precomp_trk;
  1671. fdctrl_to_result_phase(fdctrl, 10);
  1672. }
  1673. static void fdctrl_handle_version(FDCtrl *fdctrl, int direction)
  1674. {
  1675. /* Controller's version */
  1676. fdctrl->fifo[0] = fdctrl->version;
  1677. fdctrl_to_result_phase(fdctrl, 1);
  1678. }
  1679. static void fdctrl_handle_partid(FDCtrl *fdctrl, int direction)
  1680. {
  1681. fdctrl->fifo[0] = 0x41; /* Stepping 1 */
  1682. fdctrl_to_result_phase(fdctrl, 1);
  1683. }
  1684. static void fdctrl_handle_restore(FDCtrl *fdctrl, int direction)
  1685. {
  1686. FDrive *cur_drv = get_cur_drv(fdctrl);
  1687. /* Drives position */
  1688. drv0(fdctrl)->track = fdctrl->fifo[3];
  1689. drv1(fdctrl)->track = fdctrl->fifo[4];
  1690. #if MAX_FD == 4
  1691. drv2(fdctrl)->track = fdctrl->fifo[5];
  1692. drv3(fdctrl)->track = fdctrl->fifo[6];
  1693. #endif
  1694. /* timers */
  1695. fdctrl->timer0 = fdctrl->fifo[7];
  1696. fdctrl->timer1 = fdctrl->fifo[8];
  1697. cur_drv->last_sect = fdctrl->fifo[9];
  1698. fdctrl->lock = fdctrl->fifo[10] >> 7;
  1699. cur_drv->perpendicular = (fdctrl->fifo[10] >> 2) & 0xF;
  1700. fdctrl->config = fdctrl->fifo[11];
  1701. fdctrl->precomp_trk = fdctrl->fifo[12];
  1702. fdctrl->pwrd = fdctrl->fifo[13];
  1703. fdctrl_to_command_phase(fdctrl);
  1704. }
  1705. static void fdctrl_handle_save(FDCtrl *fdctrl, int direction)
  1706. {
  1707. FDrive *cur_drv = get_cur_drv(fdctrl);
  1708. fdctrl->fifo[0] = 0;
  1709. fdctrl->fifo[1] = 0;
  1710. /* Drives position */
  1711. fdctrl->fifo[2] = drv0(fdctrl)->track;
  1712. fdctrl->fifo[3] = drv1(fdctrl)->track;
  1713. #if MAX_FD == 4
  1714. fdctrl->fifo[4] = drv2(fdctrl)->track;
  1715. fdctrl->fifo[5] = drv3(fdctrl)->track;
  1716. #else
  1717. fdctrl->fifo[4] = 0;
  1718. fdctrl->fifo[5] = 0;
  1719. #endif
  1720. /* timers */
  1721. fdctrl->fifo[6] = fdctrl->timer0;
  1722. fdctrl->fifo[7] = fdctrl->timer1;
  1723. fdctrl->fifo[8] = cur_drv->last_sect;
  1724. fdctrl->fifo[9] = (fdctrl->lock << 7) |
  1725. (cur_drv->perpendicular << 2);
  1726. fdctrl->fifo[10] = fdctrl->config;
  1727. fdctrl->fifo[11] = fdctrl->precomp_trk;
  1728. fdctrl->fifo[12] = fdctrl->pwrd;
  1729. fdctrl->fifo[13] = 0;
  1730. fdctrl->fifo[14] = 0;
  1731. fdctrl_to_result_phase(fdctrl, 15);
  1732. }
  1733. static void fdctrl_handle_readid(FDCtrl *fdctrl, int direction)
  1734. {
  1735. FDrive *cur_drv = get_cur_drv(fdctrl);
  1736. cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
  1737. timer_mod(fdctrl->result_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
  1738. (NANOSECONDS_PER_SECOND / 50));
  1739. }
  1740. static void fdctrl_handle_format_track(FDCtrl *fdctrl, int direction)
  1741. {
  1742. FDrive *cur_drv;
  1743. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1744. cur_drv = get_cur_drv(fdctrl);
  1745. fdctrl->data_state |= FD_STATE_FORMAT;
  1746. if (fdctrl->fifo[0] & 0x80)
  1747. fdctrl->data_state |= FD_STATE_MULTI;
  1748. else
  1749. fdctrl->data_state &= ~FD_STATE_MULTI;
  1750. cur_drv->bps =
  1751. fdctrl->fifo[2] > 7 ? 16384 : 128 << fdctrl->fifo[2];
  1752. #if 0
  1753. cur_drv->last_sect =
  1754. cur_drv->flags & FDISK_DBL_SIDES ? fdctrl->fifo[3] :
  1755. fdctrl->fifo[3] / 2;
  1756. #else
  1757. cur_drv->last_sect = fdctrl->fifo[3];
  1758. #endif
  1759. /* TODO: implement format using DMA expected by the Bochs BIOS
  1760. * and Linux fdformat (read 3 bytes per sector via DMA and fill
  1761. * the sector with the specified fill byte
  1762. */
  1763. fdctrl->data_state &= ~FD_STATE_FORMAT;
  1764. fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
  1765. }
  1766. static void fdctrl_handle_specify(FDCtrl *fdctrl, int direction)
  1767. {
  1768. fdctrl->timer0 = (fdctrl->fifo[1] >> 4) & 0xF;
  1769. fdctrl->timer1 = fdctrl->fifo[2] >> 1;
  1770. if (fdctrl->fifo[2] & 1)
  1771. fdctrl->dor &= ~FD_DOR_DMAEN;
  1772. else
  1773. fdctrl->dor |= FD_DOR_DMAEN;
  1774. /* No result back */
  1775. fdctrl_to_command_phase(fdctrl);
  1776. }
  1777. static void fdctrl_handle_sense_drive_status(FDCtrl *fdctrl, int direction)
  1778. {
  1779. FDrive *cur_drv;
  1780. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1781. cur_drv = get_cur_drv(fdctrl);
  1782. cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
  1783. /* 1 Byte status back */
  1784. fdctrl->fifo[0] = (cur_drv->ro << 6) |
  1785. (cur_drv->track == 0 ? 0x10 : 0x00) |
  1786. (cur_drv->head << 2) |
  1787. GET_CUR_DRV(fdctrl) |
  1788. 0x28;
  1789. fdctrl_to_result_phase(fdctrl, 1);
  1790. }
  1791. static void fdctrl_handle_recalibrate(FDCtrl *fdctrl, int direction)
  1792. {
  1793. FDrive *cur_drv;
  1794. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1795. cur_drv = get_cur_drv(fdctrl);
  1796. fd_recalibrate(cur_drv);
  1797. fdctrl_to_command_phase(fdctrl);
  1798. /* Raise Interrupt */
  1799. fdctrl->status0 |= FD_SR0_SEEK;
  1800. fdctrl_raise_irq(fdctrl);
  1801. }
  1802. static void fdctrl_handle_sense_interrupt_status(FDCtrl *fdctrl, int direction)
  1803. {
  1804. FDrive *cur_drv = get_cur_drv(fdctrl);
  1805. if (fdctrl->reset_sensei > 0) {
  1806. fdctrl->fifo[0] =
  1807. FD_SR0_RDYCHG + FD_RESET_SENSEI_COUNT - fdctrl->reset_sensei;
  1808. fdctrl->reset_sensei--;
  1809. } else if (!(fdctrl->sra & FD_SRA_INTPEND)) {
  1810. fdctrl->fifo[0] = FD_SR0_INVCMD;
  1811. fdctrl_to_result_phase(fdctrl, 1);
  1812. return;
  1813. } else {
  1814. fdctrl->fifo[0] =
  1815. (fdctrl->status0 & ~(FD_SR0_HEAD | FD_SR0_DS1 | FD_SR0_DS0))
  1816. | GET_CUR_DRV(fdctrl);
  1817. }
  1818. fdctrl->fifo[1] = cur_drv->track;
  1819. fdctrl_to_result_phase(fdctrl, 2);
  1820. fdctrl_reset_irq(fdctrl);
  1821. fdctrl->status0 = FD_SR0_RDYCHG;
  1822. }
  1823. static void fdctrl_handle_seek(FDCtrl *fdctrl, int direction)
  1824. {
  1825. FDrive *cur_drv;
  1826. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1827. cur_drv = get_cur_drv(fdctrl);
  1828. fdctrl_to_command_phase(fdctrl);
  1829. /* The seek command just sends step pulses to the drive and doesn't care if
  1830. * there is a medium inserted of if it's banging the head against the drive.
  1831. */
  1832. fd_seek(cur_drv, cur_drv->head, fdctrl->fifo[2], cur_drv->sect, 1);
  1833. /* Raise Interrupt */
  1834. fdctrl->status0 |= FD_SR0_SEEK;
  1835. fdctrl_raise_irq(fdctrl);
  1836. }
  1837. static void fdctrl_handle_perpendicular_mode(FDCtrl *fdctrl, int direction)
  1838. {
  1839. FDrive *cur_drv = get_cur_drv(fdctrl);
  1840. if (fdctrl->fifo[1] & 0x80)
  1841. cur_drv->perpendicular = fdctrl->fifo[1] & 0x7;
  1842. /* No result back */
  1843. fdctrl_to_command_phase(fdctrl);
  1844. }
  1845. static void fdctrl_handle_configure(FDCtrl *fdctrl, int direction)
  1846. {
  1847. fdctrl->config = fdctrl->fifo[2];
  1848. fdctrl->precomp_trk = fdctrl->fifo[3];
  1849. /* No result back */
  1850. fdctrl_to_command_phase(fdctrl);
  1851. }
  1852. static void fdctrl_handle_powerdown_mode(FDCtrl *fdctrl, int direction)
  1853. {
  1854. fdctrl->pwrd = fdctrl->fifo[1];
  1855. fdctrl->fifo[0] = fdctrl->fifo[1];
  1856. fdctrl_to_result_phase(fdctrl, 1);
  1857. }
  1858. static void fdctrl_handle_option(FDCtrl *fdctrl, int direction)
  1859. {
  1860. /* No result back */
  1861. fdctrl_to_command_phase(fdctrl);
  1862. }
  1863. static void fdctrl_handle_drive_specification_command(FDCtrl *fdctrl, int direction)
  1864. {
  1865. FDrive *cur_drv = get_cur_drv(fdctrl);
  1866. uint32_t pos;
  1867. pos = fdctrl->data_pos - 1;
  1868. pos %= FD_SECTOR_LEN;
  1869. if (fdctrl->fifo[pos] & 0x80) {
  1870. /* Command parameters done */
  1871. if (fdctrl->fifo[pos] & 0x40) {
  1872. fdctrl->fifo[0] = fdctrl->fifo[1];
  1873. fdctrl->fifo[2] = 0;
  1874. fdctrl->fifo[3] = 0;
  1875. fdctrl_to_result_phase(fdctrl, 4);
  1876. } else {
  1877. fdctrl_to_command_phase(fdctrl);
  1878. }
  1879. } else if (fdctrl->data_len > 7) {
  1880. /* ERROR */
  1881. fdctrl->fifo[0] = 0x80 |
  1882. (cur_drv->head << 2) | GET_CUR_DRV(fdctrl);
  1883. fdctrl_to_result_phase(fdctrl, 1);
  1884. }
  1885. }
  1886. static void fdctrl_handle_relative_seek_in(FDCtrl *fdctrl, int direction)
  1887. {
  1888. FDrive *cur_drv;
  1889. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1890. cur_drv = get_cur_drv(fdctrl);
  1891. if (fdctrl->fifo[2] + cur_drv->track >= cur_drv->max_track) {
  1892. fd_seek(cur_drv, cur_drv->head, cur_drv->max_track - 1,
  1893. cur_drv->sect, 1);
  1894. } else {
  1895. fd_seek(cur_drv, cur_drv->head,
  1896. cur_drv->track + fdctrl->fifo[2], cur_drv->sect, 1);
  1897. }
  1898. fdctrl_to_command_phase(fdctrl);
  1899. /* Raise Interrupt */
  1900. fdctrl->status0 |= FD_SR0_SEEK;
  1901. fdctrl_raise_irq(fdctrl);
  1902. }
  1903. static void fdctrl_handle_relative_seek_out(FDCtrl *fdctrl, int direction)
  1904. {
  1905. FDrive *cur_drv;
  1906. SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
  1907. cur_drv = get_cur_drv(fdctrl);
  1908. if (fdctrl->fifo[2] > cur_drv->track) {
  1909. fd_seek(cur_drv, cur_drv->head, 0, cur_drv->sect, 1);
  1910. } else {
  1911. fd_seek(cur_drv, cur_drv->head,
  1912. cur_drv->track - fdctrl->fifo[2], cur_drv->sect, 1);
  1913. }
  1914. fdctrl_to_command_phase(fdctrl);
  1915. /* Raise Interrupt */
  1916. fdctrl->status0 |= FD_SR0_SEEK;
  1917. fdctrl_raise_irq(fdctrl);
  1918. }
  1919. /*
  1920. * Handlers for the execution phase of each command
  1921. */
  1922. typedef struct FDCtrlCommand {
  1923. uint8_t value;
  1924. uint8_t mask;
  1925. const char* name;
  1926. int parameters;
  1927. void (*handler)(FDCtrl *fdctrl, int direction);
  1928. int direction;
  1929. } FDCtrlCommand;
  1930. static const FDCtrlCommand handlers[] = {
  1931. { FD_CMD_READ, 0x1f, "READ", 8, fdctrl_start_transfer, FD_DIR_READ },
  1932. { FD_CMD_WRITE, 0x3f, "WRITE", 8, fdctrl_start_transfer, FD_DIR_WRITE },
  1933. { FD_CMD_SEEK, 0xff, "SEEK", 2, fdctrl_handle_seek },
  1934. { FD_CMD_SENSE_INTERRUPT_STATUS, 0xff, "SENSE INTERRUPT STATUS", 0, fdctrl_handle_sense_interrupt_status },
  1935. { FD_CMD_RECALIBRATE, 0xff, "RECALIBRATE", 1, fdctrl_handle_recalibrate },
  1936. { FD_CMD_FORMAT_TRACK, 0xbf, "FORMAT TRACK", 5, fdctrl_handle_format_track },
  1937. { FD_CMD_READ_TRACK, 0xbf, "READ TRACK", 8, fdctrl_start_transfer, FD_DIR_READ },
  1938. { FD_CMD_RESTORE, 0xff, "RESTORE", 17, fdctrl_handle_restore }, /* part of READ DELETED DATA */
  1939. { FD_CMD_SAVE, 0xff, "SAVE", 0, fdctrl_handle_save }, /* part of READ DELETED DATA */
  1940. { FD_CMD_READ_DELETED, 0x1f, "READ DELETED DATA", 8, fdctrl_start_transfer_del, FD_DIR_READ },
  1941. { FD_CMD_SCAN_EQUAL, 0x1f, "SCAN EQUAL", 8, fdctrl_start_transfer, FD_DIR_SCANE },
  1942. { FD_CMD_VERIFY, 0x1f, "VERIFY", 8, fdctrl_start_transfer, FD_DIR_VERIFY },
  1943. { FD_CMD_SCAN_LOW_OR_EQUAL, 0x1f, "SCAN LOW OR EQUAL", 8, fdctrl_start_transfer, FD_DIR_SCANL },
  1944. { FD_CMD_SCAN_HIGH_OR_EQUAL, 0x1f, "SCAN HIGH OR EQUAL", 8, fdctrl_start_transfer, FD_DIR_SCANH },
  1945. { FD_CMD_WRITE_DELETED, 0x3f, "WRITE DELETED DATA", 8, fdctrl_start_transfer_del, FD_DIR_WRITE },
  1946. { FD_CMD_READ_ID, 0xbf, "READ ID", 1, fdctrl_handle_readid },
  1947. { FD_CMD_SPECIFY, 0xff, "SPECIFY", 2, fdctrl_handle_specify },
  1948. { FD_CMD_SENSE_DRIVE_STATUS, 0xff, "SENSE DRIVE STATUS", 1, fdctrl_handle_sense_drive_status },
  1949. { FD_CMD_PERPENDICULAR_MODE, 0xff, "PERPENDICULAR MODE", 1, fdctrl_handle_perpendicular_mode },
  1950. { FD_CMD_CONFIGURE, 0xff, "CONFIGURE", 3, fdctrl_handle_configure },
  1951. { FD_CMD_POWERDOWN_MODE, 0xff, "POWERDOWN MODE", 2, fdctrl_handle_powerdown_mode },
  1952. { FD_CMD_OPTION, 0xff, "OPTION", 1, fdctrl_handle_option },
  1953. { FD_CMD_DRIVE_SPECIFICATION_COMMAND, 0xff, "DRIVE SPECIFICATION COMMAND", 5, fdctrl_handle_drive_specification_command },
  1954. { FD_CMD_RELATIVE_SEEK_OUT, 0xff, "RELATIVE SEEK OUT", 2, fdctrl_handle_relative_seek_out },
  1955. { FD_CMD_FORMAT_AND_WRITE, 0xff, "FORMAT AND WRITE", 10, fdctrl_unimplemented },
  1956. { FD_CMD_RELATIVE_SEEK_IN, 0xff, "RELATIVE SEEK IN", 2, fdctrl_handle_relative_seek_in },
  1957. { FD_CMD_LOCK, 0x7f, "LOCK", 0, fdctrl_handle_lock },
  1958. { FD_CMD_DUMPREG, 0xff, "DUMPREG", 0, fdctrl_handle_dumpreg },
  1959. { FD_CMD_VERSION, 0xff, "VERSION", 0, fdctrl_handle_version },
  1960. { FD_CMD_PART_ID, 0xff, "PART ID", 0, fdctrl_handle_partid },
  1961. { FD_CMD_WRITE, 0x1f, "WRITE (BeOS)", 8, fdctrl_start_transfer, FD_DIR_WRITE }, /* not in specification ; BeOS 4.5 bug */
  1962. { 0, 0, "unknown", 0, fdctrl_unimplemented }, /* default handler */
  1963. };
  1964. /* Associate command to an index in the 'handlers' array */
  1965. static uint8_t command_to_handler[256];
  1966. static const FDCtrlCommand *get_command(uint8_t cmd)
  1967. {
  1968. int idx;
  1969. idx = command_to_handler[cmd];
  1970. FLOPPY_DPRINTF("%s command\n", handlers[idx].name);
  1971. return &handlers[idx];
  1972. }
  1973. static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value)
  1974. {
  1975. FDrive *cur_drv;
  1976. const FDCtrlCommand *cmd;
  1977. uint32_t pos;
  1978. /* Reset mode */
  1979. if (!(fdctrl->dor & FD_DOR_nRESET)) {
  1980. FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
  1981. return;
  1982. }
  1983. if (!(fdctrl->msr & FD_MSR_RQM) || (fdctrl->msr & FD_MSR_DIO)) {
  1984. FLOPPY_DPRINTF("error: controller not ready for writing\n");
  1985. return;
  1986. }
  1987. fdctrl->dsr &= ~FD_DSR_PWRDOWN;
  1988. FLOPPY_DPRINTF("%s: %02x\n", __func__, value);
  1989. /* If data_len spans multiple sectors, the current position in the FIFO
  1990. * wraps around while fdctrl->data_pos is the real position in the whole
  1991. * request. */
  1992. pos = fdctrl->data_pos++;
  1993. pos %= FD_SECTOR_LEN;
  1994. fdctrl->fifo[pos] = value;
  1995. if (fdctrl->data_pos == fdctrl->data_len) {
  1996. fdctrl->msr &= ~FD_MSR_RQM;
  1997. }
  1998. switch (fdctrl->phase) {
  1999. case FD_PHASE_EXECUTION:
  2000. /* For DMA requests, RQM should be cleared during execution phase, so
  2001. * we would have errored out above. */
  2002. assert(fdctrl->msr & FD_MSR_NONDMA);
  2003. /* FIFO data write */
  2004. if (pos == FD_SECTOR_LEN - 1 ||
  2005. fdctrl->data_pos == fdctrl->data_len) {
  2006. cur_drv = get_cur_drv(fdctrl);
  2007. if (blk_pwrite(cur_drv->blk, fd_offset(cur_drv), BDRV_SECTOR_SIZE,
  2008. fdctrl->fifo, 0) < 0) {
  2009. FLOPPY_DPRINTF("error writing sector %d\n",
  2010. fd_sector(cur_drv));
  2011. break;
  2012. }
  2013. if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
  2014. FLOPPY_DPRINTF("error seeking to next sector %d\n",
  2015. fd_sector(cur_drv));
  2016. break;
  2017. }
  2018. }
  2019. /* Switch to result phase when done with the transfer */
  2020. if (fdctrl->data_pos == fdctrl->data_len) {
  2021. fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
  2022. }
  2023. break;
  2024. case FD_PHASE_COMMAND:
  2025. assert(!(fdctrl->msr & FD_MSR_NONDMA));
  2026. assert(fdctrl->data_pos < FD_SECTOR_LEN);
  2027. if (pos == 0) {
  2028. /* The first byte specifies the command. Now we start reading
  2029. * as many parameters as this command requires. */
  2030. cmd = get_command(value);
  2031. fdctrl->data_len = cmd->parameters + 1;
  2032. if (cmd->parameters) {
  2033. fdctrl->msr |= FD_MSR_RQM;
  2034. }
  2035. fdctrl->msr |= FD_MSR_CMDBUSY;
  2036. }
  2037. if (fdctrl->data_pos == fdctrl->data_len) {
  2038. /* We have all parameters now, execute the command */
  2039. fdctrl->phase = FD_PHASE_EXECUTION;
  2040. if (fdctrl->data_state & FD_STATE_FORMAT) {
  2041. fdctrl_format_sector(fdctrl);
  2042. break;
  2043. }
  2044. cmd = get_command(fdctrl->fifo[0]);
  2045. FLOPPY_DPRINTF("Calling handler for '%s'\n", cmd->name);
  2046. cmd->handler(fdctrl, cmd->direction);
  2047. }
  2048. break;
  2049. case FD_PHASE_RESULT:
  2050. default:
  2051. abort();
  2052. }
  2053. }
  2054. static void fdctrl_result_timer(void *opaque)
  2055. {
  2056. FDCtrl *fdctrl = opaque;
  2057. FDrive *cur_drv = get_cur_drv(fdctrl);
  2058. /* Pretend we are spinning.
  2059. * This is needed for Coherent, which uses READ ID to check for
  2060. * sector interleaving.
  2061. */
  2062. if (cur_drv->last_sect != 0) {
  2063. cur_drv->sect = (cur_drv->sect % cur_drv->last_sect) + 1;
  2064. }
  2065. /* READ_ID can't automatically succeed! */
  2066. if ((fdctrl->dsr & FD_DSR_DRATEMASK) != cur_drv->media_rate) {
  2067. FLOPPY_DPRINTF("read id rate mismatch (fdc=%d, media=%d)\n",
  2068. fdctrl->dsr & FD_DSR_DRATEMASK, cur_drv->media_rate);
  2069. fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00);
  2070. } else {
  2071. fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
  2072. }
  2073. }
  2074. /* Init functions */
  2075. void fdctrl_init_drives(FloppyBus *bus, DriveInfo **fds)
  2076. {
  2077. DeviceState *dev;
  2078. int i;
  2079. for (i = 0; i < MAX_FD; i++) {
  2080. if (fds[i]) {
  2081. dev = qdev_new("floppy");
  2082. qdev_prop_set_uint32(dev, "unit", i);
  2083. qdev_prop_set_enum(dev, "drive-type", FLOPPY_DRIVE_TYPE_AUTO);
  2084. qdev_prop_set_drive_err(dev, "drive", blk_by_legacy_dinfo(fds[i]),
  2085. &error_fatal);
  2086. qdev_realize_and_unref(dev, &bus->bus, &error_fatal);
  2087. }
  2088. }
  2089. }
  2090. void fdctrl_realize_common(DeviceState *dev, FDCtrl *fdctrl, Error **errp)
  2091. {
  2092. int i, j;
  2093. FDrive *drive;
  2094. static int command_tables_inited = 0;
  2095. if (fdctrl->fallback == FLOPPY_DRIVE_TYPE_AUTO) {
  2096. error_setg(errp, "Cannot choose a fallback FDrive type of 'auto'");
  2097. return;
  2098. }
  2099. /* Fill 'command_to_handler' lookup table */
  2100. if (!command_tables_inited) {
  2101. command_tables_inited = 1;
  2102. for (i = ARRAY_SIZE(handlers) - 1; i >= 0; i--) {
  2103. for (j = 0; j < sizeof(command_to_handler); j++) {
  2104. if ((j & handlers[i].mask) == handlers[i].value) {
  2105. command_to_handler[j] = i;
  2106. }
  2107. }
  2108. }
  2109. }
  2110. FLOPPY_DPRINTF("init controller\n");
  2111. fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN);
  2112. memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
  2113. fdctrl->fifo_size = 512;
  2114. fdctrl->result_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
  2115. fdctrl_result_timer, fdctrl);
  2116. fdctrl->version = 0x90; /* Intel 82078 controller */
  2117. fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */
  2118. fdctrl->num_floppies = MAX_FD;
  2119. floppy_bus_create(fdctrl, &fdctrl->bus, dev);
  2120. for (i = 0; i < MAX_FD; i++) {
  2121. drive = &fdctrl->drives[i];
  2122. drive->fdctrl = fdctrl;
  2123. fd_init(drive);
  2124. fd_revalidate(drive);
  2125. }
  2126. }
  2127. static void fdc_register_types(void)
  2128. {
  2129. type_register_static(&floppy_bus_info);
  2130. type_register_static(&floppy_drive_info);
  2131. }
  2132. type_init(fdc_register_types)