- Timestamp:
- Feb 24, 2013 6:52:37 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 83928
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevFdc.cpp
r44807 r44808 5 5 6 6 /* 7 * Copyright (C) 2006-201 1Oracle Corporation7 * Copyright (C) 2006-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 59 59 60 60 #define MAX_FD 2 61 62 #define PDMIBASE_2_FDRIVE(pInterface) \63 ((fdrive_t *)((uintptr_t)(pInterface) - RT_OFFSETOF(fdrive_t, IBase)))64 65 #define PDMIMOUNTNOTIFY_2_FDRIVE(p) \66 ((fdrive_t *)((uintptr_t)(p) - RT_OFFSETOF(fdrive_t, IMountNotify)))67 61 68 62 … … 729 723 } 730 724 731 #ifdef VBOX732 /**733 * Called when a medium is mounted.734 *735 * @param pInterface Pointer to the interface structure736 * containing the called function pointer.737 */738 static DECLCALLBACK(void) fdMountNotify(PPDMIMOUNTNOTIFY pInterface)739 {740 fdrive_t *drv = PDMIMOUNTNOTIFY_2_FDRIVE (pInterface);741 LogFlow(("fdMountNotify:\n"));742 fd_revalidate(drv);743 }744 745 /**746 * Called when a medium is unmounted.747 * @param pInterface Pointer to the interface structure748 * containing the called function pointer.749 */750 static DECLCALLBACK(void) fdUnmountNotify(PPDMIMOUNTNOTIFY pInterface)751 {752 fdrive_t *drv = PDMIMOUNTNOTIFY_2_FDRIVE (pInterface);753 LogFlow(("fdUnmountNotify:\n"));754 fd_revalidate(drv);755 }756 #endif757 758 725 /* Change IRQ state */ 759 726 static void fdctrl_reset_irq(fdctrl_t *fdctrl) … … 2079 2046 } 2080 2047 2048 2081 2049 #ifdef VBOX 2082 static DECLCALLBACK(void) fdc_timer (PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser) 2050 2051 /* -=-=-=-=-=-=-=-=- Timer Callback -=-=-=-=-=-=-=-=- */ 2052 2053 /** 2054 * @callback_method_impl{FNTMTIMERDEV} 2055 */ 2056 static DECLCALLBACK(void) fdcTimerCallback(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser) 2083 2057 { 2084 2058 fdctrl_t *fdctrl = (fdctrl_t *)pvUser; 2085 fdctrl_result_timer (fdctrl); 2086 } 2087 2088 static DECLCALLBACK(int) fdc_io_write (PPDMDEVINS pDevIns, 2089 void *pvUser, 2090 RTIOPORT Port, 2091 uint32_t u32, 2092 unsigned cb) 2093 { 2094 if (cb == 1) { 2059 fdctrl_result_timer(fdctrl); 2060 } 2061 2062 2063 /* -=-=-=-=-=-=-=-=- I/O Port Access Handlers -=-=-=-=-=-=-=-=- */ 2064 2065 /** 2066 * @callback_method_impl{FNIOMIOPORTOUT} 2067 */ 2068 static DECLCALLBACK(int) fdcIoPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 2069 { 2070 if (cb == 1) 2095 2071 fdctrl_write (pvUser, Port & 7, u32); 2096 } 2097 else { 2072 else 2098 2073 AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32)); 2099 }2100 2074 return VINF_SUCCESS; 2101 2075 } 2102 2076 2103 static DECLCALLBACK(int) fdc_io_read (PPDMDEVINS pDevIns, 2104 void *pvUser, 2105 RTIOPORT Port, 2106 uint32_t *pu32, 2107 unsigned cb) 2108 { 2109 if (cb == 1) { 2077 2078 /** 2079 * @callback_method_impl{FNIOMIOPORTOUT} 2080 */ 2081 static DECLCALLBACK(int) fdcIoPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb) 2082 { 2083 if (cb == 1) 2084 { 2110 2085 *pu32 = fdctrl_read (pvUser, Port & 7); 2111 2086 return VINF_SUCCESS; 2112 2087 } 2113 else { 2114 return VERR_IOM_IOPORT_UNUSED; 2115 } 2116 } 2117 2118 static DECLCALLBACK(int) fdcSaveExec (PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle) 2119 { 2120 fdctrl_t *s = PDMINS_2_DATA (pDevIns, fdctrl_t *); 2121 QEMUFile *f = pSSMHandle; 2088 return VERR_IOM_IOPORT_UNUSED; 2089 } 2090 2091 2092 /* -=-=-=-=-=-=-=-=- Saved state -=-=-=-=-=-=-=-=- */ 2093 2094 /** 2095 * @callback_method_impl{FNSSMDEVSAVEEXEC} 2096 */ 2097 static DECLCALLBACK(int) fdcSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM) 2098 { 2099 fdctrl_t *pThis = PDMINS_2_DATA(pDevIns, fdctrl_t *); 2122 2100 unsigned int i; 2123 2101 2124 2102 /* Save the FDC I/O registers... */ 2125 SSMR3PutU8(pSSM Handle,s->sra);2126 SSMR3PutU8(pSSM Handle,s->srb);2127 SSMR3PutU8(pSSM Handle,s->dor);2128 SSMR3PutU8(pSSM Handle,s->tdr);2129 SSMR3PutU8(pSSM Handle,s->dsr);2130 SSMR3PutU8(pSSM Handle,s->msr);2103 SSMR3PutU8(pSSM, pThis->sra); 2104 SSMR3PutU8(pSSM, pThis->srb); 2105 SSMR3PutU8(pSSM, pThis->dor); 2106 SSMR3PutU8(pSSM, pThis->tdr); 2107 SSMR3PutU8(pSSM, pThis->dsr); 2108 SSMR3PutU8(pSSM, pThis->msr); 2131 2109 /* ...the status registers... */ 2132 SSMR3PutU8(pSSM Handle,s->status0);2133 SSMR3PutU8(pSSM Handle,s->status1);2134 SSMR3PutU8(pSSM Handle,s->status2);2110 SSMR3PutU8(pSSM, pThis->status0); 2111 SSMR3PutU8(pSSM, pThis->status1); 2112 SSMR3PutU8(pSSM, pThis->status2); 2135 2113 /* ...the command FIFO... */ 2136 SSMR3PutU32(pSSM Handle, sizeof(s->fifo));2137 SSMR3PutMem(pSSM Handle, &s->fifo, sizeof(s->fifo));2138 SSMR3PutU32(pSSM Handle,s->data_pos);2139 SSMR3PutU32(pSSM Handle,s->data_len);2140 SSMR3PutU8(pSSM Handle,s->data_state);2141 SSMR3PutU8(pSSM Handle,s->data_dir);2114 SSMR3PutU32(pSSM, sizeof(pThis->fifo)); 2115 SSMR3PutMem(pSSM, &pThis->fifo, sizeof(pThis->fifo)); 2116 SSMR3PutU32(pSSM, pThis->data_pos); 2117 SSMR3PutU32(pSSM, pThis->data_len); 2118 SSMR3PutU8(pSSM, pThis->data_state); 2119 SSMR3PutU8(pSSM, pThis->data_dir); 2142 2120 /* ...and miscellaneous internal FDC state. */ 2143 SSMR3PutU8(pSSM Handle,s->reset_sensei);2144 SSMR3PutU8(pSSM Handle,s->eot);2145 SSMR3PutU8(pSSM Handle,s->timer0);2146 SSMR3PutU8(pSSM Handle,s->timer1);2147 SSMR3PutU8(pSSM Handle,s->precomp_trk);2148 SSMR3PutU8(pSSM Handle,s->config);2149 SSMR3PutU8(pSSM Handle,s->lock);2150 SSMR3PutU8(pSSM Handle,s->pwrd);2151 SSMR3PutU8(pSSM Handle,s->version);2121 SSMR3PutU8(pSSM, pThis->reset_sensei); 2122 SSMR3PutU8(pSSM, pThis->eot); 2123 SSMR3PutU8(pSSM, pThis->timer0); 2124 SSMR3PutU8(pSSM, pThis->timer1); 2125 SSMR3PutU8(pSSM, pThis->precomp_trk); 2126 SSMR3PutU8(pSSM, pThis->config); 2127 SSMR3PutU8(pSSM, pThis->lock); 2128 SSMR3PutU8(pSSM, pThis->pwrd); 2129 SSMR3PutU8(pSSM, pThis->version); 2152 2130 2153 2131 /* Save the number of drives and per-drive state. Note that the media 2154 2132 * states will be updated in fd_revalidate() and need not be saved. 2155 2133 */ 2156 SSMR3PutU8(pSSMHandle, s->num_floppies); 2157 Assert(RT_ELEMENTS(s->drives) == s->num_floppies); 2158 for (i = 0; i < s->num_floppies; ++i) { 2159 fdrive_t *d = &s->drives[i]; 2160 2161 SSMR3PutMem(pSSMHandle, &d->Led, sizeof(d->Led)); 2162 SSMR3PutU32(pSSMHandle, d->drive); 2163 SSMR3PutU8(pSSMHandle, d->dsk_chg); 2164 SSMR3PutU8(pSSMHandle, d->perpendicular); 2165 SSMR3PutU8(pSSMHandle, d->head); 2166 SSMR3PutU8(pSSMHandle, d->track); 2167 SSMR3PutU8(pSSMHandle, d->sect); 2168 } 2169 return TMR3TimerSave (s->result_timer, pSSMHandle); 2170 } 2171 2172 static DECLCALLBACK(int) fdcLoadExec (PPDMDEVINS pDevIns, 2173 PSSMHANDLE pSSMHandle, 2174 uint32_t uVersion, 2175 uint32_t uPass) 2176 { 2177 fdctrl_t *s = PDMINS_2_DATA (pDevIns, fdctrl_t *); 2178 QEMUFile *f = pSSMHandle; 2134 SSMR3PutU8(pSSM, pThis->num_floppies); 2135 Assert(RT_ELEMENTS(pThis->drives) == pThis->num_floppies); 2136 for (i = 0; i < pThis->num_floppies; ++i) 2137 { 2138 fdrive_t *d = &pThis->drives[i]; 2139 2140 SSMR3PutMem(pSSM, &d->Led, sizeof(d->Led)); 2141 SSMR3PutU32(pSSM, d->drive); 2142 SSMR3PutU8(pSSM, d->dsk_chg); 2143 SSMR3PutU8(pSSM, d->perpendicular); 2144 SSMR3PutU8(pSSM, d->head); 2145 SSMR3PutU8(pSSM, d->track); 2146 SSMR3PutU8(pSSM, d->sect); 2147 } 2148 return TMR3TimerSave (pThis->result_timer, pSSM); 2149 } 2150 2151 2152 /** 2153 * @callback_method_impl{FNSSMDEVLOADEXEC} 2154 */ 2155 static DECLCALLBACK(int) fdcLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass) 2156 { 2157 fdctrl_t *pThis = PDMINS_2_DATA(pDevIns, fdctrl_t *); 2179 2158 unsigned int i; 2180 2159 uint32_t val32; … … 2193 2172 { 2194 2173 /* First verify a few assumptions. */ 2195 AssertMsgReturn(sizeof( s->fifo) == FD_SECTOR_LEN,2174 AssertMsgReturn(sizeof(pThis->fifo) == FD_SECTOR_LEN, 2196 2175 ("The size of FIFO in saved state doesn't match!\n"), 2197 2176 VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 2198 AssertMsgReturn(RT_ELEMENTS( s->drives) == 2,2177 AssertMsgReturn(RT_ELEMENTS(pThis->drives) == 2, 2199 2178 ("The number of drives in old saved state doesn't match!\n"), 2200 2179 VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 2201 2180 /* Now load the old state. */ 2202 SSMR3GetU8(pSSM Handle, &s->version);2181 SSMR3GetU8(pSSM, &pThis->version); 2203 2182 /* Toss IRQ level, DMA channel, I/O base, and state. */ 2204 SSMR3GetU8(pSSM Handle, &val8);2205 SSMR3GetU8(pSSM Handle, &val8);2206 SSMR3GetU32(pSSM Handle, &val32);2207 SSMR3GetU8(pSSM Handle, &val8);2183 SSMR3GetU8(pSSM, &val8); 2184 SSMR3GetU8(pSSM, &val8); 2185 SSMR3GetU32(pSSM, &val32); 2186 SSMR3GetU8(pSSM, &val8); 2208 2187 /* Translate dma_en. */ 2209 SSMR3GetU8(pSSM Handle, &val8);2188 SSMR3GetU8(pSSM, &val8); 2210 2189 if (val8) 2211 s->dor |= FD_DOR_DMAEN;2212 SSMR3GetU8(pSSM Handle, &s->cur_drv);2190 pThis->dor |= FD_DOR_DMAEN; 2191 SSMR3GetU8(pSSM, &pThis->cur_drv); 2213 2192 /* Translate bootsel. */ 2214 SSMR3GetU8(pSSMHandle, &val8); 2215 s->tdr |= val8 << 2; 2216 SSMR3GetMem(pSSMHandle, &s->fifo, FD_SECTOR_LEN); 2217 SSMR3GetU32(pSSMHandle, &s->data_pos); 2218 SSMR3GetU32(pSSMHandle, &s->data_len); 2219 SSMR3GetU8(pSSMHandle, &s->data_state); 2220 SSMR3GetU8(pSSMHandle, &s->data_dir); 2221 SSMR3GetU8(pSSMHandle, &s->status0); 2222 SSMR3GetU8(pSSMHandle, &s->eot); 2223 SSMR3GetU8(pSSMHandle, &s->timer0); 2224 SSMR3GetU8(pSSMHandle, &s->timer1); 2225 SSMR3GetU8(pSSMHandle, &s->precomp_trk); 2226 SSMR3GetU8(pSSMHandle, &s->config); 2227 SSMR3GetU8(pSSMHandle, &s->lock); 2228 SSMR3GetU8(pSSMHandle, &s->pwrd); 2229 2230 for (i = 0; i < 2; ++i) { 2231 fdrive_t *d = &s->drives[i]; 2232 2233 SSMR3GetMem (pSSMHandle, &d->Led, sizeof (d->Led)); 2234 SSMR3GetU32(pSSMHandle, &val32); 2193 SSMR3GetU8(pSSM, &val8); 2194 pThis->tdr |= val8 << 2; 2195 SSMR3GetMem(pSSM, &pThis->fifo, FD_SECTOR_LEN); 2196 SSMR3GetU32(pSSM, &pThis->data_pos); 2197 SSMR3GetU32(pSSM, &pThis->data_len); 2198 SSMR3GetU8(pSSM, &pThis->data_state); 2199 SSMR3GetU8(pSSM, &pThis->data_dir); 2200 SSMR3GetU8(pSSM, &pThis->status0); 2201 SSMR3GetU8(pSSM, &pThis->eot); 2202 SSMR3GetU8(pSSM, &pThis->timer0); 2203 SSMR3GetU8(pSSM, &pThis->timer1); 2204 SSMR3GetU8(pSSM, &pThis->precomp_trk); 2205 SSMR3GetU8(pSSM, &pThis->config); 2206 SSMR3GetU8(pSSM, &pThis->lock); 2207 SSMR3GetU8(pSSM, &pThis->pwrd); 2208 2209 for (i = 0; i < 2; ++i) 2210 { 2211 fdrive_t *d = &pThis->drives[i]; 2212 2213 SSMR3GetMem (pSSM, &d->Led, sizeof (d->Led)); 2214 SSMR3GetU32(pSSM, &val32); 2235 2215 d->drive = (fdrive_type_t)val32; 2236 SSMR3GetU32(pSSM Handle, &val32); /* Toss drflags */2237 SSMR3GetU8(pSSM Handle, &d->perpendicular);2238 SSMR3GetU8(pSSM Handle, &d->head);2239 SSMR3GetU8(pSSM Handle, &d->track);2240 SSMR3GetU8(pSSM Handle, &d->sect);2241 SSMR3GetU8(pSSM Handle, &val8); /* Toss dir, rw */2242 SSMR3GetU8(pSSM Handle, &val8);2243 SSMR3GetU32(pSSM Handle, &val32);2216 SSMR3GetU32(pSSM, &val32); /* Toss drflags */ 2217 SSMR3GetU8(pSSM, &d->perpendicular); 2218 SSMR3GetU8(pSSM, &d->head); 2219 SSMR3GetU8(pSSM, &d->track); 2220 SSMR3GetU8(pSSM, &d->sect); 2221 SSMR3GetU8(pSSM, &val8); /* Toss dir, rw */ 2222 SSMR3GetU8(pSSM, &val8); 2223 SSMR3GetU32(pSSM, &val32); 2244 2224 d->flags = (fdrive_flags_t)val32; 2245 SSMR3GetU8(pSSM Handle, &d->last_sect);2246 SSMR3GetU8(pSSM Handle, &d->max_track);2247 SSMR3GetU16(pSSM Handle, &d->bps);2248 SSMR3GetU8(pSSM Handle, &d->ro);2225 SSMR3GetU8(pSSM, &d->last_sect); 2226 SSMR3GetU8(pSSM, &d->max_track); 2227 SSMR3GetU16(pSSM, &d->bps); 2228 SSMR3GetU8(pSSM, &d->ro); 2249 2229 } 2250 2230 } … … 2253 2233 Assert(uVersion == FDC_SAVESTATE_CURRENT); 2254 2234 /* Load the FDC I/O registers... */ 2255 SSMR3GetU8(pSSM Handle, &s->sra);2256 SSMR3GetU8(pSSM Handle, &s->srb);2257 SSMR3GetU8(pSSM Handle, &s->dor);2258 SSMR3GetU8(pSSM Handle, &s->tdr);2259 SSMR3GetU8(pSSM Handle, &s->dsr);2260 SSMR3GetU8(pSSM Handle, &s->msr);2235 SSMR3GetU8(pSSM, &pThis->sra); 2236 SSMR3GetU8(pSSM, &pThis->srb); 2237 SSMR3GetU8(pSSM, &pThis->dor); 2238 SSMR3GetU8(pSSM, &pThis->tdr); 2239 SSMR3GetU8(pSSM, &pThis->dsr); 2240 SSMR3GetU8(pSSM, &pThis->msr); 2261 2241 /* ...the status registers... */ 2262 SSMR3GetU8(pSSM Handle, &s->status0);2263 SSMR3GetU8(pSSM Handle, &s->status1);2264 SSMR3GetU8(pSSM Handle, &s->status2);2242 SSMR3GetU8(pSSM, &pThis->status0); 2243 SSMR3GetU8(pSSM, &pThis->status1); 2244 SSMR3GetU8(pSSM, &pThis->status2); 2265 2245 /* ...the command FIFO, if the size matches... */ 2266 SSMR3GetU32(pSSM Handle, &val32);2267 AssertMsgReturn(sizeof( s->fifo) == val32,2246 SSMR3GetU32(pSSM, &val32); 2247 AssertMsgReturn(sizeof(pThis->fifo) == val32, 2268 2248 ("The size of FIFO in saved state doesn't match!\n"), 2269 2249 VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 2270 SSMR3GetMem(pSSM Handle, &s->fifo, sizeof(s->fifo));2271 SSMR3GetU32(pSSM Handle, &s->data_pos);2272 SSMR3GetU32(pSSM Handle, &s->data_len);2273 SSMR3GetU8(pSSM Handle, &s->data_state);2274 SSMR3GetU8(pSSM Handle, &s->data_dir);2250 SSMR3GetMem(pSSM, &pThis->fifo, sizeof(pThis->fifo)); 2251 SSMR3GetU32(pSSM, &pThis->data_pos); 2252 SSMR3GetU32(pSSM, &pThis->data_len); 2253 SSMR3GetU8(pSSM, &pThis->data_state); 2254 SSMR3GetU8(pSSM, &pThis->data_dir); 2275 2255 /* ...and miscellaneous internal FDC state. */ 2276 SSMR3GetU8(pSSM Handle, &s->reset_sensei);2277 SSMR3GetU8(pSSM Handle, &s->eot);2278 SSMR3GetU8(pSSM Handle, &s->timer0);2279 SSMR3GetU8(pSSM Handle, &s->timer1);2280 SSMR3GetU8(pSSM Handle, &s->precomp_trk);2281 SSMR3GetU8(pSSM Handle, &s->config);2282 SSMR3GetU8(pSSM Handle, &s->lock);2283 SSMR3GetU8(pSSM Handle, &s->pwrd);2284 SSMR3GetU8(pSSM Handle, &s->version);2256 SSMR3GetU8(pSSM, &pThis->reset_sensei); 2257 SSMR3GetU8(pSSM, &pThis->eot); 2258 SSMR3GetU8(pSSM, &pThis->timer0); 2259 SSMR3GetU8(pSSM, &pThis->timer1); 2260 SSMR3GetU8(pSSM, &pThis->precomp_trk); 2261 SSMR3GetU8(pSSM, &pThis->config); 2262 SSMR3GetU8(pSSM, &pThis->lock); 2263 SSMR3GetU8(pSSM, &pThis->pwrd); 2264 SSMR3GetU8(pSSM, &pThis->version); 2285 2265 2286 2266 /* Validate the number of drives. */ 2287 SSMR3GetU8(pSSM Handle, &s->num_floppies);2288 AssertMsgReturn(RT_ELEMENTS( s->drives) ==s->num_floppies,2267 SSMR3GetU8(pSSM, &pThis->num_floppies); 2268 AssertMsgReturn(RT_ELEMENTS(pThis->drives) == pThis->num_floppies, 2289 2269 ("The number of drives in saved state doesn't match!\n"), 2290 2270 VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 2291 2271 2292 2272 /* Load the per-drive state. */ 2293 for (i = 0; i < s->num_floppies; ++i) { 2294 fdrive_t *d = &s->drives[i]; 2295 2296 SSMR3GetMem(pSSMHandle, &d->Led, sizeof(d->Led)); 2297 SSMR3GetU32(pSSMHandle, &val32); 2273 for (i = 0; i < pThis->num_floppies; ++i) 2274 { 2275 fdrive_t *d = &pThis->drives[i]; 2276 2277 SSMR3GetMem(pSSM, &d->Led, sizeof(d->Led)); 2278 SSMR3GetU32(pSSM, &val32); 2298 2279 d->drive = (fdrive_type_t)val32; 2299 SSMR3GetU8(pSSM Handle, &d->dsk_chg);2300 SSMR3GetU8(pSSM Handle, &d->perpendicular);2301 SSMR3GetU8(pSSM Handle, &d->head);2302 SSMR3GetU8(pSSM Handle, &d->track);2303 SSMR3GetU8(pSSM Handle, &d->sect);2280 SSMR3GetU8(pSSM, &d->dsk_chg); 2281 SSMR3GetU8(pSSM, &d->perpendicular); 2282 SSMR3GetU8(pSSM, &d->head); 2283 SSMR3GetU8(pSSM, &d->track); 2284 SSMR3GetU8(pSSM, &d->sect); 2304 2285 } 2305 2286 } 2306 return TMR3TimerLoad (s->result_timer, pSSMHandle); 2307 } 2287 return TMR3TimerLoad (pThis->result_timer, pSSM); 2288 } 2289 2290 2291 /* -=-=-=-=-=-=-=-=- Drive level interfaces -=-=-=-=-=-=-=-=- */ 2292 2293 /** 2294 * @interface_method_impl{PDMIMOUNTNOTIFY,pfnMountNotify} 2295 */ 2296 static DECLCALLBACK(void) fdMountNotify(PPDMIMOUNTNOTIFY pInterface) 2297 { 2298 fdrive_t *pDrv = RT_FROM_MEMBER(pInterface, fdrive_t, IMountNotify); 2299 LogFlow(("fdMountNotify:\n")); 2300 fd_revalidate(pDrv); 2301 } 2302 2303 2304 /** 2305 * @interface_method_impl{PDMIMOUNTNOTIFY,pfnUnmountNotify} 2306 */ 2307 static DECLCALLBACK(void) fdUnmountNotify(PPDMIMOUNTNOTIFY pInterface) 2308 { 2309 fdrive_t *pDrv = RT_FROM_MEMBER(pInterface, fdrive_t, IMountNotify); 2310 LogFlow(("fdUnmountNotify:\n")); 2311 fd_revalidate(pDrv); 2312 } 2313 2308 2314 2309 2315 /** … … 2312 2318 static DECLCALLBACK(void *) fdQueryInterface (PPDMIBASE pInterface, const char *pszIID) 2313 2319 { 2314 fdrive_t *pDr ive = PDMIBASE_2_FDRIVE(pInterface);2315 2316 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDr ive->IBase);2317 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBLOCKPORT, &pDr ive->IPort);2318 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUNTNOTIFY, &pDr ive->IMountNotify);2320 fdrive_t *pDrv = RT_FROM_MEMBER(pInterface, fdrive_t, IBase); 2321 2322 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrv->IBase); 2323 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBLOCKPORT, &pDrv->IPort); 2324 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUNTNOTIFY, &pDrv->IMountNotify); 2319 2325 return NULL; 2320 2326 } 2321 2327 2328 2329 /* -=-=-=-=-=-=-=-=- Controller level interfaces -=-=-=-=-=-=-=-=- */ 2330 2322 2331 /** 2323 * Gets the pointer to the status LED of a unit. 2324 * 2325 * @returns VBox status code. 2326 * @param pInterface Pointer to the interface structure containing the called function pointer. 2327 * @param iLUN The unit which status LED we desire. 2328 * @param ppLed Where to store the LED pointer. 2332 * @interface_method_impl{PDMILEDPORTS,pfnQueryStatusLed} 2329 2333 */ 2330 static DECLCALLBACK(int) fdcStatusQueryStatusLed (PPDMILEDPORTS pInterface, 2331 unsigned iLUN, 2332 PPDMLED *ppLed) 2333 { 2334 fdctrl_t *fdctrl = (fdctrl_t *) 2335 ((uintptr_t )pInterface - RT_OFFSETOF (fdctrl_t, ILeds)); 2336 if (iLUN < RT_ELEMENTS(fdctrl->drives)) { 2337 *ppLed = &fdctrl->drives[iLUN].Led; 2334 static DECLCALLBACK(int) fdcStatusQueryStatusLed(PPDMILEDPORTS pInterface, unsigned iLUN, PPDMLED *ppLed) 2335 { 2336 fdctrl_t *pThis = RT_FROM_MEMBER (pInterface, fdctrl_t, ILeds); 2337 if (iLUN < RT_ELEMENTS(pThis->drives)) { 2338 *ppLed = &pThis->drives[iLUN].Led; 2338 2339 Assert ((*ppLed)->u32Magic == PDMLED_MAGIC); 2339 2340 return VINF_SUCCESS; … … 2365 2366 static int fdConfig (fdrive_t *drv, PPDMDEVINS pDevIns) 2366 2367 { 2367 static const char * descs[] = {"Floppy Drive A:", "Floppy Drive B"};2368 static const char * const s_apszDesc[] = {"Floppy Drive A:", "Floppy Drive B"}; 2368 2369 int rc; 2369 2370 … … 2371 2372 * Reset the LED just to be on the safe side. 2372 2373 */ 2373 Assert (RT_ELEMENTS( descs) > drv->iLUN);2374 Assert (RT_ELEMENTS(s_apszDesc) > drv->iLUN); 2374 2375 Assert (drv->Led.u32Magic == PDMLED_MAGIC); 2375 2376 drv->Led.Actual.u32 = 0; … … 2379 2380 * Try attach the block device and get the interfaces. 2380 2381 */ 2381 rc = PDMDevHlpDriverAttach (pDevIns, drv->iLUN, &drv->IBase, &drv->pDrvBase, descs[drv->iLUN]);2382 rc = PDMDevHlpDriverAttach (pDevIns, drv->iLUN, &drv->IBase, &drv->pDrvBase, s_apszDesc[drv->iLUN]); 2382 2383 if (RT_SUCCESS (rc)) { 2383 2384 drv->pDrvBlock = PDMIBASE_QUERY_INTERFACE(drv->pDrvBase, PDMIBLOCK); … … 2431 2432 2432 2433 /** 2433 * Attach command.2434 * @interface_method_impl{PDMDEVREG,pfnAttach} 2434 2435 * 2435 2436 * This is called when we change block driver for a floppy drive. 2436 *2437 * @returns VBox status code.2438 * @param pDevIns The device instance.2439 * @param iLUN The logical unit which is being detached.2440 2437 */ 2441 static DECLCALLBACK(int) fdcAttach (PPDMDEVINS pDevIns, 2442 unsigned iLUN, uint32_t fFlags) 2443 { 2444 fdctrl_t *fdctrl = PDMINS_2_DATA (pDevIns, fdctrl_t *); 2438 static DECLCALLBACK(int) fdcAttach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags) 2439 { 2440 fdctrl_t *fdctrl = PDMINS_2_DATA(pDevIns, fdctrl_t *); 2445 2441 fdrive_t *drv; 2446 2442 int rc; … … 2484 2480 2485 2481 /** 2486 * Detach notification.2482 * @interface_method_impl{PDMDEVREG,pfnDetach} 2487 2483 * 2488 2484 * The floppy drive has been temporarily 'unplugged'. 2489 *2490 * @param pDevIns The device instance.2491 * @param iLUN The logical unit which is being detached.2492 2485 */ 2493 static DECLCALLBACK(void) fdcDetach (PPDMDEVINS pDevIns, 2494 unsigned iLUN, uint32_t fFlags) 2495 { 2496 fdctrl_t *fdctrl = PDMINS_2_DATA (pDevIns, fdctrl_t *); 2486 static DECLCALLBACK(void) fdcDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags) 2487 { 2488 fdctrl_t *pThis = PDMINS_2_DATA(pDevIns, fdctrl_t *); 2497 2489 LogFlow (("ideDetach: iLUN=%u\n", iLUN)); 2498 2490 2499 switch (iLUN) { 2500 case 0: 2501 case 1: { 2502 fdrive_t *drv = &fdctrl->drives[iLUN]; 2503 drv->pDrvBase = NULL; 2504 drv->pDrvBlock = NULL; 2505 drv->pDrvBlockBios = NULL; 2506 drv->pDrvMount = NULL; 2507 break; 2508 } 2509 2510 default: 2511 AssertMsgFailed (("Cannot detach LUN#%d!\n", iLUN)); 2512 break; 2491 switch (iLUN) 2492 { 2493 case 0: 2494 case 1: 2495 { 2496 fdrive_t *drv = &pThis->drives[iLUN]; 2497 drv->pDrvBase = NULL; 2498 drv->pDrvBlock = NULL; 2499 drv->pDrvBlockBios = NULL; 2500 drv->pDrvMount = NULL; 2501 break; 2502 } 2503 2504 default: 2505 AssertMsgFailed(("Cannot detach LUN#%d!\n", iLUN)); 2506 break; 2513 2507 } 2514 2508 } … … 2516 2510 2517 2511 /** 2518 * Handle reset.2512 * @interface_method_impl{PDMDEVREG,pfnReset} 2519 2513 * 2520 2514 * I haven't check the specs on what's supposed to happen on reset, but we 2521 2515 * should get any 'FATAL: floppy recal:f07 ctrl not ready' when resetting 2522 2516 * at wrong time like we do if this was all void. 2523 *2524 * @param pDevIns The device instance.2525 2517 */ 2526 static DECLCALLBACK(void) fdcReset 2527 { 2528 fdctrl_t * fdctrl= PDMINS_2_DATA (pDevIns, fdctrl_t *);2518 static DECLCALLBACK(void) fdcReset(PPDMDEVINS pDevIns) 2519 { 2520 fdctrl_t *pThis = PDMINS_2_DATA (pDevIns, fdctrl_t *); 2529 2521 unsigned i; 2530 2522 LogFlow (("fdcReset:\n")); 2531 2523 2532 fdctrl_reset(fdctrl, 0); 2533 2534 for (i = 0; i < RT_ELEMENTS(fdctrl->drives); i++) { 2535 fd_revalidate(&fdctrl->drives[i]); 2536 } 2524 fdctrl_reset(pThis, 0); 2525 2526 for (i = 0; i < RT_ELEMENTS(pThis->drives); i++) 2527 fd_revalidate(&pThis->drives[i]); 2537 2528 } 2538 2529 … … 2541 2532 * @interface_method_impl{PDMDEVREG,pfnConstruct} 2542 2533 */ 2543 static DECLCALLBACK(int) fdcConstruct (PPDMDEVINS pDevIns, 2544 int iInstance, 2545 PCFGMNODE pCfg) 2546 { 2534 static DECLCALLBACK(int) fdcConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg) 2535 { 2536 fdctrl_t *pThis = PDMINS_2_DATA(pDevIns, fdctrl_t *); 2547 2537 int rc; 2548 fdctrl_t *fdctrl = PDMINS_2_DATA(pDevIns, fdctrl_t*);2549 2538 unsigned i, j; 2550 2539 int ii; … … 2566 2555 * Read the configuration. 2567 2556 */ 2568 rc = CFGMR3QueryU8 (pCfg, "IRQ", &irq_lvl); 2569 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 2570 irq_lvl = 6; 2571 else if (RT_FAILURE (rc)) { 2572 AssertMsgFailed (("Configuration error: Failed to read U8 IRQ, rc=%Rrc\n", rc)); 2573 return rc; 2574 } 2575 2576 rc = CFGMR3QueryU8 (pCfg, "DMA", &dma_chann); 2577 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 2578 dma_chann = 2; 2579 else if (RT_FAILURE (rc)) { 2580 AssertMsgFailed (("Configuration error: Failed to read U8 DMA, rc=%Rrc\n", rc)); 2581 return rc; 2582 } 2583 2584 rc = CFGMR3QueryU16 (pCfg, "IOBase", &io_base); 2585 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 2586 io_base = 0x3f0; 2587 else if (RT_FAILURE (rc)) { 2588 AssertMsgFailed (("Configuration error: Failed to read U16 IOBase, rc=%Rrc\n", rc)); 2589 return rc; 2590 } 2591 2592 rc = CFGMR3QueryBool (pCfg, "MemMapped", &mem_mapped); 2593 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 2594 mem_mapped = false; 2595 else if (RT_FAILURE (rc)) { 2596 AssertMsgFailed (("Configuration error: Failed to read bool value MemMapped rc=%Rrc\n", rc)); 2597 return rc; 2598 } 2557 rc = CFGMR3QueryU8Def(pCfg, "IRQ", &irq_lvl, 6); 2558 AssertMsgRCReturn(rc, ("Configuration error: Failed to read U8 IRQ, rc=%Rrc\n", rc), rc); 2559 2560 rc = CFGMR3QueryU8Def(pCfg, "DMA", &dma_chann, 2); 2561 AssertMsgRCReturn(rc, ("Configuration error: Failed to read U8 DMA, rc=%Rrc\n", rc), rc); 2562 2563 rc = CFGMR3QueryU16Def(pCfg, "IOBase", &io_base, 0x3f0); 2564 AssertMsgRCReturn(rc, ("Configuration error: Failed to read U16 IOBase, rc=%Rrc\n", rc), rc); 2565 2566 rc = CFGMR3QueryBoolDef(pCfg, "MemMapped", &mem_mapped, false); 2567 AssertMsgRCReturn(rc, ("Configuration error: Failed to read bool value MemMapped rc=%Rrc\n", rc), rc); 2599 2568 2600 2569 /* … … 2602 2571 */ 2603 2572 LogFlow(("fdcConstruct: irq_lvl=%d dma_chann=%d io_base=%#x\n", irq_lvl, dma_chann, io_base)); 2604 fdctrl->pDevIns = pDevIns;2605 fdctrl->version = 0x90; /* Intel 82078 controller */2606 fdctrl->irq_lvl = irq_lvl;2607 fdctrl->dma_chann = dma_chann;2608 fdctrl->io_base = io_base;2609 fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */2610 fdctrl->num_floppies = MAX_FD;2573 pThis->pDevIns = pDevIns; 2574 pThis->version = 0x90; /* Intel 82078 controller */ 2575 pThis->irq_lvl = irq_lvl; 2576 pThis->dma_chann = dma_chann; 2577 pThis->io_base = io_base; 2578 pThis->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */ 2579 pThis->num_floppies = MAX_FD; 2611 2580 2612 2581 /* Fill 'command_to_handler' lookup table */ 2613 for (ii = RT_ELEMENTS(handlers) - 1; ii >= 0; ii--) {2614 for (j = 0; j < sizeof(command_to_handler); j++) {2615 if ((j & handlers[ii].mask) == handlers[ii].value) {2582 for (ii = RT_ELEMENTS(handlers) - 1; ii >= 0; ii--) 2583 for (j = 0; j < sizeof(command_to_handler); j++) 2584 if ((j & handlers[ii].mask) == handlers[ii].value) 2616 2585 command_to_handler[j] = ii; 2617 } 2618 } 2619 } 2620 2621 fdctrl->IBaseStatus.pfnQueryInterface = fdcStatusQueryInterface; 2622 fdctrl->ILeds.pfnQueryStatusLed = fdcStatusQueryStatusLed; 2623 2624 for (i = 0; i < RT_ELEMENTS(fdctrl->drives); ++i) { 2625 fdrive_t *drv = &fdctrl->drives[i]; 2626 2627 drv->drive = FDRIVE_DRV_NONE; 2628 drv->iLUN = i; 2629 2630 drv->IBase.pfnQueryInterface = fdQueryInterface; 2631 drv->IMountNotify.pfnMountNotify = fdMountNotify; 2632 drv->IMountNotify.pfnUnmountNotify = fdUnmountNotify; 2633 drv->Led.u32Magic = PDMLED_MAGIC; 2586 2587 pThis->IBaseStatus.pfnQueryInterface = fdcStatusQueryInterface; 2588 pThis->ILeds.pfnQueryStatusLed = fdcStatusQueryStatusLed; 2589 2590 for (i = 0; i < RT_ELEMENTS(pThis->drives); ++i) 2591 { 2592 fdrive_t *pDrv = &pThis->drives[i]; 2593 2594 pDrv->drive = FDRIVE_DRV_NONE; 2595 pDrv->iLUN = i; 2596 2597 pDrv->IBase.pfnQueryInterface = fdQueryInterface; 2598 pDrv->IMountNotify.pfnMountNotify = fdMountNotify; 2599 pDrv->IMountNotify.pfnUnmountNotify = fdUnmountNotify; 2600 pDrv->Led.u32Magic = PDMLED_MAGIC; 2634 2601 } 2635 2602 … … 2637 2604 * Create the FDC timer. 2638 2605 */ 2639 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, fdc _timer, fdctrl,2640 TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "FDC Timer", & fdctrl->result_timer);2641 if (RT_FAILURE 2606 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, fdcTimerCallback, pThis, 2607 TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "FDC Timer", &pThis->result_timer); 2608 if (RT_FAILURE(rc)) 2642 2609 return rc; 2643 2610 … … 2645 2612 * Register DMA channel. 2646 2613 */ 2647 if (fdctrl->dma_chann != 0xff) { 2648 rc = PDMDevHlpDMARegister (pDevIns, dma_chann, &fdctrl_transfer_handler, fdctrl); 2649 if (RT_FAILURE (rc)) 2614 if (pThis->dma_chann != 0xff) 2615 { 2616 rc = PDMDevHlpDMARegister(pDevIns, dma_chann, &fdctrl_transfer_handler, pThis); 2617 if (RT_FAILURE(rc)) 2650 2618 return rc; 2651 2619 } … … 2654 2622 * IO / MMIO. 2655 2623 */ 2656 if (mem_mapped) { 2657 AssertMsgFailed (("Memory mapped floppy not support by now\n")); 2624 if (mem_mapped) 2625 { 2626 AssertMsgFailed(("Memory mapped floppy not support by now\n")); 2658 2627 return VERR_NOT_SUPPORTED; 2659 2628 #if 0 … … 2662 2631 cpu_register_physical_memory(base, 0x08, io_mem); 2663 2632 #endif 2664 } else { 2665 rc = PDMDevHlpIOPortRegister (pDevIns, io_base + 0x1, 5, fdctrl, 2666 fdc_io_write, fdc_io_read, NULL, NULL, "FDC#1"); 2667 if (RT_FAILURE (rc)) 2633 } 2634 else 2635 { 2636 rc = PDMDevHlpIOPortRegister(pDevIns, io_base + 0x1, 5, pThis, 2637 fdcIoPortWrite, fdcIoPortRead, NULL, NULL, "FDC#1"); 2638 if (RT_FAILURE(rc)) 2668 2639 return rc; 2669 2640 2670 rc = PDMDevHlpIOPortRegister (pDevIns, io_base + 0x7, 1, fdctrl,2671 fdc_io_write, fdc_io_read, NULL, NULL, "FDC#2");2672 if (RT_FAILURE 2641 rc = PDMDevHlpIOPortRegister(pDevIns, io_base + 0x7, 1, pThis, 2642 fdcIoPortWrite, fdcIoPortRead, NULL, NULL, "FDC#2"); 2643 if (RT_FAILURE(rc)) 2673 2644 return rc; 2674 2645 } … … 2677 2648 * Register the saved state data unit. 2678 2649 */ 2679 rc = PDMDevHlpSSMRegister (pDevIns, FDC_SAVESTATE_CURRENT, sizeof(*fdctrl), fdcSaveExec, fdcLoadExec);2650 rc = PDMDevHlpSSMRegister(pDevIns, FDC_SAVESTATE_CURRENT, sizeof(*pThis), fdcSaveExec, fdcLoadExec); 2680 2651 if (RT_FAILURE(rc)) 2681 2652 return rc; … … 2684 2655 * Attach the status port (optional). 2685 2656 */ 2686 rc = PDMDevHlpDriverAttach (pDevIns, PDM_STATUS_LUN, &fdctrl->IBaseStatus, &pBase, "Status Port");2687 if (RT_SUCCESS (rc)) {2688 fdctrl->pLedsConnector = PDMIBASE_QUERY_INTERFACE(pBase, PDMILEDCONNECTORS);2689 } else if (rc != VERR_PDM_NO_ATTACHED_DRIVER) {2690 AssertMsgFailed (("Failed to attach to status driver. rc=%Rrc\n",2691 2657 rc = PDMDevHlpDriverAttach(pDevIns, PDM_STATUS_LUN, &pThis->IBaseStatus, &pBase, "Status Port"); 2658 if (RT_SUCCESS (rc)) 2659 pThis->pLedsConnector = PDMIBASE_QUERY_INTERFACE(pBase, PDMILEDCONNECTORS); 2660 else if (rc != VERR_PDM_NO_ATTACHED_DRIVER) 2661 { 2662 AssertMsgFailed(("Failed to attach to status driver. rc=%Rrc\n", rc)); 2692 2663 return rc; 2693 2664 } … … 2696 2667 * Initialize drives. 2697 2668 */ 2698 for (i = 0; i < RT_ELEMENTS(fdctrl->drives); i++) { 2699 fdrive_t *drv = &fdctrl->drives[i]; 2700 rc = fdConfig (drv, pDevIns); 2701 if ( RT_FAILURE (rc) 2702 && rc != VERR_PDM_NO_ATTACHED_DRIVER) { 2703 AssertMsgFailed (("Configuration error: failed to configure drive %d, rc=%Rrc\n", rc)); 2669 for (i = 0; i < RT_ELEMENTS(pThis->drives); i++) 2670 { 2671 fdrive_t *pDrv = &pThis->drives[i]; 2672 rc = fdConfig(pDrv, pDevIns); 2673 if ( RT_FAILURE(rc) 2674 && rc != VERR_PDM_NO_ATTACHED_DRIVER) 2675 { 2676 AssertMsgFailed(("Configuration error: failed to configure drive %d, rc=%Rrc\n", rc)); 2704 2677 return rc; 2705 2678 } 2706 2679 } 2707 2680 2708 fdctrl_reset( fdctrl, 0);2709 2710 for (i = 0; i < RT_ELEMENTS( fdctrl->drives); i++)2711 fd_revalidate(& fdctrl->drives[i]);2681 fdctrl_reset(pThis, 0); 2682 2683 for (i = 0; i < RT_ELEMENTS(pThis->drives); i++) 2684 fd_revalidate(&pThis->drives[i]); 2712 2685 2713 2686 return VINF_SUCCESS; 2714 2687 } 2688 2715 2689 2716 2690 /**
Note:
See TracChangeset
for help on using the changeset viewer.