Revision caed8802
b/hw/fdc.c | ||
---|---|---|
85 | 85 |
uint8_t ro; /* Is read-only */ |
86 | 86 |
} fdrive_t; |
87 | 87 |
|
88 |
static void fd_init (fdrive_t *drv) |
|
88 |
static void fd_init (fdrive_t *drv, BlockDriverState *bs)
|
|
89 | 89 |
{ |
90 | 90 |
/* Drive */ |
91 |
drv->bs = NULL; |
|
92 |
// drv->drive = FDRIVE_DRV_288; |
|
93 |
drv->drive = FDRIVE_DRV_144; |
|
91 |
drv->bs = bs; |
|
92 |
if (bs) |
|
93 |
drv->drive = FDRIVE_DRV_144; |
|
94 |
else |
|
95 |
drv->drive = FDRIVE_DRV_NONE; |
|
94 | 96 |
drv->motor = 0; |
95 | 97 |
drv->perpendicular = 0; |
96 | 98 |
drv->rv = 0; |
... | ... | |
157 | 159 |
} |
158 | 160 |
|
159 | 161 |
/* Revalidate a disk drive after a disk change */ |
160 |
static void fd_revalidate (fdrive_t *drv, int ro)
|
|
162 |
static void fd_revalidate (fdrive_t *drv) |
|
161 | 163 |
{ |
162 | 164 |
int64_t nb_sectors; |
163 | 165 |
|
164 | 166 |
FLOPPY_DPRINTF("revalidate\n"); |
165 | 167 |
drv->rv = 0; |
166 |
if (drv->bs != NULL) { |
|
168 |
/* if no drive present, cannot do more */ |
|
169 |
if (!drv->bs) |
|
170 |
return; |
|
171 |
|
|
172 |
if (bdrv_is_inserted(drv->bs)) { |
|
167 | 173 |
bdrv_get_geometry(drv->bs, &nb_sectors); |
168 | 174 |
#if 1 |
169 | 175 |
if (nb_sectors > 2880) |
... | ... | |
186 | 192 |
drv->max_track = 80; |
187 | 193 |
#endif |
188 | 194 |
} |
195 |
drv->ro = bdrv_is_read_only(drv->bs); |
|
189 | 196 |
} else { |
190 | 197 |
drv->disk = FDRIVE_DISK_NONE; |
191 | 198 |
drv->last_sect = 1; /* Avoid eventual divide by 0 bugs */ |
199 |
drv->ro = 0; |
|
192 | 200 |
} |
193 |
drv->ro = ro; |
|
194 | 201 |
drv->rv = 1; |
195 | 202 |
} |
196 | 203 |
|
204 |
static void fd_change_cb (void *opaque) |
|
205 |
{ |
|
206 |
fdrive_t *drv = opaque; |
|
207 |
fd_revalidate(drv); |
|
208 |
} |
|
209 |
|
|
197 | 210 |
/* Motor control */ |
198 | 211 |
static void fd_start (fdrive_t *drv) |
199 | 212 |
{ |
... | ... | |
220 | 233 |
static int fdctrl_transfer_handler (void *opaque, target_ulong addr, int size); |
221 | 234 |
static void fdctrl_raise_irq (uint8_t status); |
222 | 235 |
|
223 |
static uint32_t fdctrl_read_statusB (CPUState *env, uint32_t reg);
|
|
224 |
static uint32_t fdctrl_read_dor (CPUState *env, uint32_t reg);
|
|
225 |
static void fdctrl_write_dor (CPUState *env, uint32_t reg, uint32_t value);
|
|
226 |
static uint32_t fdctrl_read_tape (CPUState *env, uint32_t reg);
|
|
227 |
static void fdctrl_write_tape (CPUState *env, uint32_t reg, uint32_t value);
|
|
228 |
static uint32_t fdctrl_read_main_status (CPUState *env, uint32_t reg);
|
|
229 |
static void fdctrl_write_rate (CPUState *env, uint32_t reg, uint32_t value);
|
|
230 |
static uint32_t fdctrl_read_data (CPUState *env, uint32_t reg);
|
|
231 |
static void fdctrl_write_data (CPUState *env, uint32_t reg, uint32_t value);
|
|
232 |
static uint32_t fdctrl_read_dir (CPUState *env, uint32_t reg);
|
|
236 |
static uint32_t fdctrl_read_statusB (void *opaque, uint32_t reg);
|
|
237 |
static uint32_t fdctrl_read_dor (void *opaque, uint32_t reg);
|
|
238 |
static void fdctrl_write_dor (void *opaque, uint32_t reg, uint32_t value);
|
|
239 |
static uint32_t fdctrl_read_tape (void *opaque, uint32_t reg);
|
|
240 |
static void fdctrl_write_tape (void *opaque, uint32_t reg, uint32_t value);
|
|
241 |
static uint32_t fdctrl_read_main_status (void *opaque, uint32_t reg);
|
|
242 |
static void fdctrl_write_rate (void *opaque, uint32_t reg, uint32_t value);
|
|
243 |
static uint32_t fdctrl_read_data (void *opaque, uint32_t reg);
|
|
244 |
static void fdctrl_write_data (void *opaque, uint32_t reg, uint32_t value);
|
|
245 |
static uint32_t fdctrl_read_dir (void *opaque, uint32_t reg);
|
|
233 | 246 |
|
234 | 247 |
enum { |
235 | 248 |
FD_CTRL_ACTIVE = 0x01, |
... | ... | |
295 | 308 |
static fdctrl_t fdctrl; |
296 | 309 |
|
297 | 310 |
void fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t base, |
298 |
char boot_device)
|
|
311 |
BlockDriverState **fds)
|
|
299 | 312 |
{ |
300 | 313 |
// int io_mem; |
301 | 314 |
int i; |
... | ... | |
312 | 325 |
} else { |
313 | 326 |
fdctrl.dma_en = 0; |
314 | 327 |
} |
315 |
for (i = 0; i < MAX_FD; i++) |
|
316 |
fd_init(&fdctrl.drives[i]); |
|
328 |
for (i = 0; i < MAX_FD; i++) { |
|
329 |
fd_init(&fdctrl.drives[i], fds[i]); |
|
330 |
if (fds[i]) |
|
331 |
bdrv_set_change_cb(fds[i], fd_change_cb, &fdctrl.drives[i]); |
|
332 |
} |
|
317 | 333 |
fdctrl_reset(0); |
318 | 334 |
fdctrl.state = FD_CTRL_ACTIVE; |
319 | 335 |
if (mem_mapped) { |
... | ... | |
323 | 339 |
cpu_register_physical_memory(base, 0x08, io_mem); |
324 | 340 |
#endif |
325 | 341 |
} else { |
326 |
register_ioport_read(base + 0x01, 1, fdctrl_read_statusB, 1);
|
|
327 |
register_ioport_read(base + 0x02, 1, fdctrl_read_dor, 1);
|
|
328 |
register_ioport_write(base + 0x02, 1, fdctrl_write_dor, 1);
|
|
329 |
register_ioport_read(base + 0x03, 1, fdctrl_read_tape, 1);
|
|
330 |
register_ioport_write(base + 0x03, 1, fdctrl_write_tape, 1);
|
|
331 |
register_ioport_read(base + 0x04, 1, fdctrl_read_main_status, 1);
|
|
332 |
register_ioport_write(base + 0x04, 1, fdctrl_write_rate, 1);
|
|
333 |
register_ioport_read(base + 0x05, 1, fdctrl_read_data, 1);
|
|
334 |
register_ioport_write(base + 0x05, 1, fdctrl_write_data, 1);
|
|
335 |
register_ioport_read(base + 0x07, 1, fdctrl_read_dir, 1);
|
|
342 |
register_ioport_read(base + 0x01, 1, 1, fdctrl_read_statusB, NULL);
|
|
343 |
register_ioport_read(base + 0x02, 1, 1, fdctrl_read_dor, NULL);
|
|
344 |
register_ioport_write(base + 0x02, 1, 1, fdctrl_write_dor, NULL);
|
|
345 |
register_ioport_read(base + 0x03, 1, 1, fdctrl_read_tape, NULL);
|
|
346 |
register_ioport_write(base + 0x03, 1, 1, fdctrl_write_tape, NULL);
|
|
347 |
register_ioport_read(base + 0x04, 1, 1, fdctrl_read_main_status, NULL);
|
|
348 |
register_ioport_write(base + 0x04, 1, 1, fdctrl_write_rate, NULL);
|
|
349 |
register_ioport_read(base + 0x05, 1, 1, fdctrl_read_data, NULL);
|
|
350 |
register_ioport_write(base + 0x05, 1, 1, fdctrl_write_data, NULL);
|
|
351 |
register_ioport_read(base + 0x07, 1, 1, fdctrl_read_dir, NULL);
|
|
336 | 352 |
} |
337 |
if (boot_device == 'b') |
|
338 |
fdctrl.bootsel = 1; |
|
339 |
else |
|
340 |
fdctrl.bootsel = 0; |
|
341 |
#if defined (TARGET_I386) |
|
342 |
cmos_register_fd(fdctrl.drives[0].drive, fdctrl.drives[1].drive); |
|
343 |
#endif |
|
344 |
} |
|
345 |
|
|
346 |
int fdctrl_disk_change (int idx, const unsigned char *filename, int ro) |
|
347 |
{ |
|
348 |
fdrive_t *drv; |
|
353 |
fdctrl.bootsel = 0; |
|
349 | 354 |
|
350 |
if (idx < 0 || idx > 1) |
|
351 |
return -1; |
|
352 |
FLOPPY_DPRINTF("disk %d change: %s (%s)\n", idx, filename, |
|
353 |
ro == 0 ? "rw" : "ro"); |
|
354 |
drv = &fdctrl.drives[idx]; |
|
355 |
if (fd_table[idx] != NULL) { |
|
356 |
bdrv_close(fd_table[idx]); |
|
357 |
fd_table[idx] = NULL; |
|
355 |
for (i = 0; i < MAX_FD; i++) { |
|
356 |
fd_revalidate(&fdctrl.drives[i]); |
|
358 | 357 |
} |
359 |
fd_table[idx] = bdrv_open(filename, ro); |
|
360 |
drv->bs = fd_table[idx]; |
|
361 |
if (fd_table[idx] == NULL) |
|
362 |
return -1; |
|
363 |
fd_revalidate(drv, ro); |
|
364 |
#if 0 |
|
365 |
fd_recalibrate(drv); |
|
366 |
fdctrl_reset_fifo(); |
|
367 |
fdctrl_raise_irq(0x20); |
|
368 |
#endif |
|
358 |
} |
|
369 | 359 |
|
370 |
return 0; |
|
360 |
int fdctrl_get_drive_type(int drive_num) |
|
361 |
{ |
|
362 |
return fdctrl.drives[drive_num].drive; |
|
371 | 363 |
} |
372 | 364 |
|
373 | 365 |
/* Change IRQ state */ |
... | ... | |
411 | 403 |
} |
412 | 404 |
|
413 | 405 |
/* Status B register : 0x01 (read-only) */ |
414 |
static uint32_t fdctrl_read_statusB (CPUState *env, uint32_t reg)
|
|
406 |
static uint32_t fdctrl_read_statusB (void *opaque, uint32_t reg)
|
|
415 | 407 |
{ |
416 | 408 |
fdctrl_reset_irq(); |
417 | 409 |
FLOPPY_DPRINTF("status register: 0x00\n"); |
... | ... | |
420 | 412 |
} |
421 | 413 |
|
422 | 414 |
/* Digital output register : 0x02 */ |
423 |
static uint32_t fdctrl_read_dor (CPUState *env, uint32_t reg)
|
|
415 |
static uint32_t fdctrl_read_dor (void *opaque, uint32_t reg)
|
|
424 | 416 |
{ |
425 | 417 |
fdrive_t *cur_drv, *drv0, *drv1; |
426 | 418 |
uint32_t retval = 0; |
... | ... | |
442 | 434 |
return retval; |
443 | 435 |
} |
444 | 436 |
|
445 |
static void fdctrl_write_dor (CPUState *env, uint32_t reg, uint32_t value)
|
|
437 |
static void fdctrl_write_dor (void *opaque, uint32_t reg, uint32_t value)
|
|
446 | 438 |
{ |
447 | 439 |
fdrive_t *drv0, *drv1; |
448 | 440 |
|
... | ... | |
489 | 481 |
} |
490 | 482 |
|
491 | 483 |
/* Tape drive register : 0x03 */ |
492 |
static uint32_t fdctrl_read_tape (CPUState *env, uint32_t reg)
|
|
484 |
static uint32_t fdctrl_read_tape (void *opaque, uint32_t reg)
|
|
493 | 485 |
{ |
494 | 486 |
uint32_t retval = 0; |
495 | 487 |
|
... | ... | |
502 | 494 |
return retval; |
503 | 495 |
} |
504 | 496 |
|
505 |
static void fdctrl_write_tape (CPUState *env, uint32_t reg, uint32_t value)
|
|
497 |
static void fdctrl_write_tape (void *opaque, uint32_t reg, uint32_t value)
|
|
506 | 498 |
{ |
507 | 499 |
fdctrl_reset_irq(); |
508 | 500 |
/* Reset mode */ |
... | ... | |
517 | 509 |
} |
518 | 510 |
|
519 | 511 |
/* Main status register : 0x04 (read) */ |
520 |
static uint32_t fdctrl_read_main_status (CPUState *env, uint32_t reg)
|
|
512 |
static uint32_t fdctrl_read_main_status (void *opaque, uint32_t reg)
|
|
521 | 513 |
{ |
522 | 514 |
uint32_t retval = 0; |
523 | 515 |
|
... | ... | |
541 | 533 |
} |
542 | 534 |
|
543 | 535 |
/* Data select rate register : 0x04 (write) */ |
544 |
static void fdctrl_write_rate (CPUState *env, uint32_t reg, uint32_t value)
|
|
536 |
static void fdctrl_write_rate (void *opaque, uint32_t reg, uint32_t value)
|
|
545 | 537 |
{ |
546 | 538 |
fdctrl_reset_irq(); |
547 | 539 |
/* Reset mode */ |
... | ... | |
566 | 558 |
} |
567 | 559 |
|
568 | 560 |
/* Digital input register : 0x07 (read-only) */ |
569 |
static uint32_t fdctrl_read_dir (CPUState *env, uint32_t reg)
|
|
561 |
static uint32_t fdctrl_read_dir (void *opaque, uint32_t reg)
|
|
570 | 562 |
{ |
571 | 563 |
fdrive_t *drv0, *drv1; |
572 | 564 |
uint32_t retval = 0; |
... | ... | |
872 | 864 |
} |
873 | 865 |
|
874 | 866 |
/* Data register : 0x05 */ |
875 |
static uint32_t fdctrl_read_data (CPUState *env, uint32_t reg)
|
|
867 |
static uint32_t fdctrl_read_data (void *opaque, uint32_t reg)
|
|
876 | 868 |
{ |
877 | 869 |
fdrive_t *cur_drv, *drv0, *drv1; |
878 | 870 |
uint32_t retval = 0; |
... | ... | |
914 | 906 |
return retval; |
915 | 907 |
} |
916 | 908 |
|
917 |
static void fdctrl_write_data (CPUState *env, uint32_t reg, uint32_t value)
|
|
909 |
static void fdctrl_write_data (void *opaque, uint32_t reg, uint32_t value)
|
|
918 | 910 |
{ |
919 | 911 |
fdrive_t *cur_drv, *drv0, *drv1; |
920 | 912 |
|
b/hw/ide.c | ||
---|---|---|
314 | 314 |
|
315 | 315 |
typedef void EndTransferFunc(struct IDEState *); |
316 | 316 |
|
317 |
/* NOTE: IDEState represents in fact one drive */ |
|
317 | 318 |
typedef struct IDEState { |
318 | 319 |
/* ide config */ |
319 | 320 |
int is_cdrom; |
320 |
int cdrom_locked; |
|
321 | 321 |
int cylinders, heads, sectors; |
322 | 322 |
int64_t nb_sectors; |
323 | 323 |
int mult_sectors; |
... | ... | |
351 | 351 |
uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4]; |
352 | 352 |
} IDEState; |
353 | 353 |
|
354 |
IDEState ide_state[MAX_DISKS]; |
|
355 |
IDEState *ide_table[0x400 >> 3]; |
|
356 |
|
|
357 |
static inline IDEState *get_ide_interface(uint32_t addr) |
|
358 |
{ |
|
359 |
return ide_table[addr >> 3]; |
|
360 |
} |
|
361 |
|
|
362 | 354 |
static void padstr(char *str, const char *src, int len) |
363 | 355 |
{ |
364 | 356 |
int i, v; |
... | ... | |
815 | 807 |
#endif |
816 | 808 |
switch(s->io_buffer[0]) { |
817 | 809 |
case GPCMD_TEST_UNIT_READY: |
818 |
if (s->bs) {
|
|
810 |
if (bdrv_is_inserted(s->bs)) {
|
|
819 | 811 |
ide_atapi_cmd_ok(s); |
820 | 812 |
} else { |
821 | 813 |
ide_atapi_cmd_error(s, SENSE_NOT_READY, |
... | ... | |
867 | 859 |
buf[12] = 0x70; |
868 | 860 |
buf[13] = 3 << 5; |
869 | 861 |
buf[14] = (1 << 0) | (1 << 3) | (1 << 5); |
870 |
if (s->cdrom_locked)
|
|
862 |
if (bdrv_is_locked(s->bs))
|
|
871 | 863 |
buf[6] |= 1 << 1; |
872 | 864 |
buf[15] = 0x00; |
873 | 865 |
cpu_to_ube16(&buf[16], 706); |
... | ... | |
907 | 899 |
ide_atapi_cmd_reply(s, 18, max_len); |
908 | 900 |
break; |
909 | 901 |
case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL: |
910 |
if (s->bs) {
|
|
911 |
s->cdrom_locked = packet[4] & 1;
|
|
902 |
if (bdrv_is_inserted(s->bs)) {
|
|
903 |
bdrv_set_locked(s->bs, packet[4] & 1);
|
|
912 | 904 |
ide_atapi_cmd_ok(s); |
913 | 905 |
} else { |
914 | 906 |
ide_atapi_cmd_error(s, SENSE_NOT_READY, |
... | ... | |
920 | 912 |
{ |
921 | 913 |
int nb_sectors, lba; |
922 | 914 |
|
923 |
if (!s->bs) {
|
|
915 |
if (!bdrv_is_inserted(s->bs)) {
|
|
924 | 916 |
ide_atapi_cmd_error(s, SENSE_NOT_READY, |
925 | 917 |
ASC_MEDIUM_NOT_PRESENT); |
926 | 918 |
break; |
... | ... | |
945 | 937 |
case GPCMD_SEEK: |
946 | 938 |
{ |
947 | 939 |
int lba; |
948 |
if (!s->bs) {
|
|
940 |
if (!bdrv_is_inserted(s->bs)) {
|
|
949 | 941 |
ide_atapi_cmd_error(s, SENSE_NOT_READY, |
950 | 942 |
ASC_MEDIUM_NOT_PRESENT); |
951 | 943 |
break; |
... | ... | |
965 | 957 |
start = packet[4] & 1; |
966 | 958 |
eject = (packet[4] >> 1) & 1; |
967 | 959 |
|
968 |
/* XXX: currently none implemented */ |
|
960 |
if (eject && !start) { |
|
961 |
/* eject the disk */ |
|
962 |
bdrv_close(s->bs); |
|
963 |
} |
|
969 | 964 |
ide_atapi_cmd_ok(s); |
970 | 965 |
} |
971 | 966 |
break; |
... | ... | |
986 | 981 |
{ |
987 | 982 |
int format, msf, start_track, len; |
988 | 983 |
|
989 |
if (!s->bs) {
|
|
984 |
if (!bdrv_is_inserted(s->bs)) {
|
|
990 | 985 |
ide_atapi_cmd_error(s, SENSE_NOT_READY, |
991 | 986 |
ASC_MEDIUM_NOT_PRESENT); |
992 | 987 |
break; |
... | ... | |
1019 | 1014 |
} |
1020 | 1015 |
break; |
1021 | 1016 |
case GPCMD_READ_CDVD_CAPACITY: |
1022 |
if (!s->bs) {
|
|
1017 |
if (!bdrv_is_inserted(s->bs)) {
|
|
1023 | 1018 |
ide_atapi_cmd_error(s, SENSE_NOT_READY, |
1024 | 1019 |
ASC_MEDIUM_NOT_PRESENT); |
1025 | 1020 |
break; |
... | ... | |
1051 | 1046 |
} |
1052 | 1047 |
} |
1053 | 1048 |
|
1054 |
static void ide_ioport_write(CPUState *env, uint32_t addr, uint32_t val) |
|
1049 |
/* called when the inserted state of the media has changed */ |
|
1050 |
static void cdrom_change_cb(void *opaque) |
|
1055 | 1051 |
{ |
1056 |
IDEState *ide_if = get_ide_interface(addr); |
|
1052 |
IDEState *s = opaque; |
|
1053 |
int64_t nb_sectors; |
|
1054 |
|
|
1055 |
/* XXX: send interrupt too */ |
|
1056 |
bdrv_get_geometry(s->bs, &nb_sectors); |
|
1057 |
s->nb_sectors = nb_sectors; |
|
1058 |
} |
|
1059 |
|
|
1060 |
static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
|
1061 |
{ |
|
1062 |
IDEState *ide_if = opaque; |
|
1057 | 1063 |
IDEState *s = ide_if->cur_drive; |
1058 | 1064 |
int unit, n; |
1059 | 1065 |
|
... | ... | |
1210 | 1216 |
} |
1211 | 1217 |
} |
1212 | 1218 |
|
1213 |
static uint32_t ide_ioport_read(CPUState *env, uint32_t addr1)
|
|
1219 |
static uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
|
|
1214 | 1220 |
{ |
1215 |
IDEState *s = get_ide_interface(addr1)->cur_drive;
|
|
1221 |
IDEState *s = ((IDEState *)opaque)->cur_drive;
|
|
1216 | 1222 |
uint32_t addr; |
1217 | 1223 |
int ret; |
1218 | 1224 |
|
... | ... | |
1251 | 1257 |
return ret; |
1252 | 1258 |
} |
1253 | 1259 |
|
1254 |
static uint32_t ide_status_read(CPUState *env, uint32_t addr)
|
|
1260 |
static uint32_t ide_status_read(void *opaque, uint32_t addr)
|
|
1255 | 1261 |
{ |
1256 |
IDEState *s = get_ide_interface(addr)->cur_drive;
|
|
1262 |
IDEState *s = ((IDEState *)opaque)->cur_drive;
|
|
1257 | 1263 |
int ret; |
1258 | 1264 |
ret = s->status; |
1259 | 1265 |
#ifdef DEBUG_IDE |
... | ... | |
1262 | 1268 |
return ret; |
1263 | 1269 |
} |
1264 | 1270 |
|
1265 |
static void ide_cmd_write(CPUState *env, uint32_t addr, uint32_t val)
|
|
1271 |
static void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
|
|
1266 | 1272 |
{ |
1267 |
IDEState *ide_if = get_ide_interface(addr);
|
|
1273 |
IDEState *ide_if = opaque;
|
|
1268 | 1274 |
IDEState *s; |
1269 | 1275 |
int i; |
1270 | 1276 |
|
... | ... | |
1297 | 1303 |
ide_if[1].cmd = val; |
1298 | 1304 |
} |
1299 | 1305 |
|
1300 |
static void ide_data_writew(CPUState *env, uint32_t addr, uint32_t val)
|
|
1306 |
static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
|
|
1301 | 1307 |
{ |
1302 |
IDEState *s = get_ide_interface(addr)->cur_drive;
|
|
1308 |
IDEState *s = ((IDEState *)opaque)->cur_drive;
|
|
1303 | 1309 |
uint8_t *p; |
1304 | 1310 |
|
1305 | 1311 |
p = s->data_ptr; |
... | ... | |
1310 | 1316 |
s->end_transfer_func(s); |
1311 | 1317 |
} |
1312 | 1318 |
|
1313 |
static uint32_t ide_data_readw(CPUState *env, uint32_t addr)
|
|
1319 |
static uint32_t ide_data_readw(void *opaque, uint32_t addr)
|
|
1314 | 1320 |
{ |
1315 |
IDEState *s = get_ide_interface(addr)->cur_drive;
|
|
1321 |
IDEState *s = ((IDEState *)opaque)->cur_drive;
|
|
1316 | 1322 |
uint8_t *p; |
1317 | 1323 |
int ret; |
1318 | 1324 |
p = s->data_ptr; |
... | ... | |
1324 | 1330 |
return ret; |
1325 | 1331 |
} |
1326 | 1332 |
|
1327 |
static void ide_data_writel(CPUState *env, uint32_t addr, uint32_t val)
|
|
1333 |
static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
|
|
1328 | 1334 |
{ |
1329 |
IDEState *s = get_ide_interface(addr)->cur_drive;
|
|
1335 |
IDEState *s = ((IDEState *)opaque)->cur_drive;
|
|
1330 | 1336 |
uint8_t *p; |
1331 | 1337 |
|
1332 | 1338 |
p = s->data_ptr; |
... | ... | |
1337 | 1343 |
s->end_transfer_func(s); |
1338 | 1344 |
} |
1339 | 1345 |
|
1340 |
static uint32_t ide_data_readl(CPUState *env, uint32_t addr)
|
|
1346 |
static uint32_t ide_data_readl(void *opaque, uint32_t addr)
|
|
1341 | 1347 |
{ |
1342 |
IDEState *s = get_ide_interface(addr)->cur_drive;
|
|
1348 |
IDEState *s = ((IDEState *)opaque)->cur_drive;
|
|
1343 | 1349 |
uint8_t *p; |
1344 | 1350 |
int ret; |
1345 | 1351 |
|
... | ... | |
1407 | 1413 |
} |
1408 | 1414 |
} |
1409 | 1415 |
|
1410 |
void ide_init(void) |
|
1416 |
void ide_init(int iobase, int iobase2, int irq, |
|
1417 |
BlockDriverState *hd0, BlockDriverState *hd1) |
|
1411 | 1418 |
{ |
1412 |
IDEState *s; |
|
1413 |
int i, cylinders, iobase, iobase2;
|
|
1419 |
IDEState *s, *ide_state;
|
|
1420 |
int i, cylinders, heads, secs;
|
|
1414 | 1421 |
int64_t nb_sectors; |
1415 |
static const int ide_iobase[2] = { 0x1f0, 0x170 }; |
|
1416 |
static const int ide_iobase2[2] = { 0x3f6, 0x376 }; |
|
1417 |
static const int ide_irq[2] = { 14, 15 }; |
|
1418 | 1422 |
|
1419 |
for(i = 0; i < MAX_DISKS; i++) { |
|
1420 |
s = &ide_state[i]; |
|
1421 |
s->bs = bs_table[i]; |
|
1423 |
ide_state = qemu_mallocz(sizeof(IDEState) * 2); |
|
1424 |
if (!ide_state) |
|
1425 |
return; |
|
1426 |
|
|
1427 |
for(i = 0; i < 2; i++) { |
|
1428 |
s = ide_state + i; |
|
1429 |
if (i == 0) |
|
1430 |
s->bs = hd0; |
|
1431 |
else |
|
1432 |
s->bs = hd1; |
|
1422 | 1433 |
if (s->bs) { |
1423 | 1434 |
bdrv_get_geometry(s->bs, &nb_sectors); |
1424 | 1435 |
s->nb_sectors = nb_sectors; |
1425 |
ide_guess_geometry(s); |
|
1426 |
if (s->cylinders == 0) { |
|
1427 |
/* if no geometry, use a LBA compatible one */ |
|
1428 |
cylinders = nb_sectors / (16 * 63); |
|
1429 |
if (cylinders > 16383) |
|
1430 |
cylinders = 16383; |
|
1431 |
else if (cylinders < 2) |
|
1432 |
cylinders = 2; |
|
1436 |
/* if a geometry hint is available, use it */ |
|
1437 |
bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs); |
|
1438 |
if (cylinders != 0) { |
|
1433 | 1439 |
s->cylinders = cylinders; |
1434 |
s->heads = 16; |
|
1435 |
s->sectors = 63; |
|
1440 |
s->heads = heads; |
|
1441 |
s->sectors = secs; |
|
1442 |
} else { |
|
1443 |
ide_guess_geometry(s); |
|
1444 |
if (s->cylinders == 0) { |
|
1445 |
/* if no geometry, use a LBA compatible one */ |
|
1446 |
cylinders = nb_sectors / (16 * 63); |
|
1447 |
if (cylinders > 16383) |
|
1448 |
cylinders = 16383; |
|
1449 |
else if (cylinders < 2) |
|
1450 |
cylinders = 2; |
|
1451 |
s->cylinders = cylinders; |
|
1452 |
s->heads = 16; |
|
1453 |
s->sectors = 63; |
|
1454 |
} |
|
1455 |
} |
|
1456 |
if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) { |
|
1457 |
s->is_cdrom = 1; |
|
1458 |
bdrv_set_change_cb(s->bs, cdrom_change_cb, s); |
|
1436 | 1459 |
} |
1437 | 1460 |
} |
1438 |
s->irq = ide_irq[i >> 1];
|
|
1461 |
s->irq = irq;
|
|
1439 | 1462 |
ide_reset(s); |
1440 | 1463 |
} |
1441 |
for(i = 0; i < (MAX_DISKS / 2); i++) { |
|
1442 |
iobase = ide_iobase[i]; |
|
1443 |
iobase2 = ide_iobase2[i]; |
|
1444 |
ide_table[iobase >> 3] = &ide_state[2 * i]; |
|
1445 |
if (ide_iobase2[i]) |
|
1446 |
ide_table[iobase2 >> 3] = &ide_state[2 * i]; |
|
1447 |
register_ioport_write(iobase, 8, ide_ioport_write, 1); |
|
1448 |
register_ioport_read(iobase, 8, ide_ioport_read, 1); |
|
1449 |
register_ioport_read(iobase2, 1, ide_status_read, 1); |
|
1450 |
register_ioport_write(iobase2, 1, ide_cmd_write, 1); |
|
1451 |
|
|
1452 |
/* data ports */ |
|
1453 |
register_ioport_write(iobase, 2, ide_data_writew, 2); |
|
1454 |
register_ioport_read(iobase, 2, ide_data_readw, 2); |
|
1455 |
register_ioport_write(iobase, 4, ide_data_writel, 4); |
|
1456 |
register_ioport_read(iobase, 4, ide_data_readl, 4); |
|
1464 |
register_ioport_write(iobase, 8, 1, ide_ioport_write, ide_state); |
|
1465 |
register_ioport_read(iobase, 8, 1, ide_ioport_read, ide_state); |
|
1466 |
if (iobase2) { |
|
1467 |
register_ioport_read(iobase2, 1, 1, ide_status_read, ide_state); |
|
1468 |
register_ioport_write(iobase2, 1, 1, ide_cmd_write, ide_state); |
|
1457 | 1469 |
} |
1458 |
} |
|
1459 |
|
|
1460 |
void ide_set_geometry(int n, int cyls, int heads, int secs) |
|
1461 |
{ |
|
1462 |
ide_state[n].cylinders = cyls; |
|
1463 |
ide_state[n].heads = heads; |
|
1464 |
ide_state[n].sectors = secs; |
|
1465 |
} |
|
1466 |
|
|
1467 |
void ide_set_cdrom(int n, int is_cdrom) |
|
1468 |
{ |
|
1469 |
ide_state[n].is_cdrom = is_cdrom; |
|
1470 |
|
|
1471 |
/* data ports */ |
|
1472 |
register_ioport_write(iobase, 2, 2, ide_data_writew, ide_state); |
|
1473 |
register_ioport_read(iobase, 2, 2, ide_data_readw, ide_state); |
|
1474 |
register_ioport_write(iobase, 4, 4, ide_data_writel, ide_state); |
|
1475 |
register_ioport_read(iobase, 4, 4, ide_data_readl, ide_state); |
|
1470 | 1476 |
} |
Also available in: Unified diff