Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CD-ROM insert, eject #900

Open
JoeOsborn opened this issue Aug 17, 2023 · 4 comments
Open

CD-ROM insert, eject #900

JoeOsborn opened this issue Aug 17, 2023 · 4 comments

Comments

@JoeOsborn
Copy link
Contributor

I think the IDEInterface would need to change in a few ways (and we should always have a CD ROM drive even with no cdrom buffer)... Here's my understanding of the problem based on the osdev wiki ( https://wiki.osdev.org/PCI_IDE_Controller#Ejecting_an_ATAPI_Drive ) and https://inst.eecs.berkeley.edu/~cs150/fa01/labs/project/ATAPI_Spec.pdf .

An empty drive should report a media type of 0x70.

When a disk is inserted, the ide controller should generate a unit attention condition that persists until it's cleared by the guest when it sends a "request sense" about it; my understanding is that this should cause all reads and stuff to error out with a "unit attention" error. At that point the controller can do what it was doing before, but with a new buffer. I think this is the second thing to implement: a function to load a CDROM into an empty cdrom controller.

For the emulator user to trigger an eject, we can do it by telling the interface to respond to queries with an error status with bit 3 (Media Change Requested) set. Then the controller should wait for the guest to send an Acknowledge Media Change command (code DB), after which the guest promises to send the eject sequence. (For a less graceful way, we could just swap the buffers and set that unit attention condition from before, but then the guest OS doesn't get a chance to e.g. prevent the eject or things like that).

For the guest OS to trigger an eject, I think there is an ATAPI command that can be implemented (see the osdev link), but it's also possible it's the start/stop unit command with the "LoEj" flag set. Here I'd want to hook on ATAPI commands and see if the guest is sending something that we're not handling.

Originally posted by @JoeOsborn in #54 (comment)

@JoeOsborn
Copy link
Contributor Author

So my first roadblock is that I can't boot from hda with a CD inserted.

I don't know much about PCI or IDE or ATA, but here's what I tried so far:

  1. I made the windows31 profile also load the windows30 CD in cdrom, adjusting the boot order to 0x132.
  2. I changed the log statement in src/ide.js:629 to include this.device.name
  3. I saw a number of ATA commands issued to ide0 and ide1; only 0xA1 was ever issued to ide1.
  4. I hit a debug assert on a spurious dma write onto ide1 (the CD)

I'm really suspicious that this is because src/ide.js:49 hardcodes the master port to 0xB400 and registers some writes and reads with the CPU, so whichever controller is initialized second is the one that gets DMA stuff done to it. What's the correct thing to do?

@JoeOsborn
Copy link
Contributor Author

JoeOsborn commented Aug 17, 2023

The ide_initialize example from https://wiki.osdev.org/PCI_IDE_Controller suggests both controllers share the same BAR1-4, but use different parts of it for their addresses. So it seems like maybe the registered writes need to dispatch to one ide controller or the other, or else each controller should register the ports it wants to listen on.

@JoeOsborn
Copy link
Contributor Author

I guess the two IDE controllers are different PCI devices so they wouldn’t share bars, but then they should use different addresses for their ports, right? The example above may be for an IDE controller with both primary/secondary and master/slave distinctions. I think that’s a thing? Would it be best to extend IDEController to have both primary and secondary channels? Otherwise I guess the master port address can just vary with the device number—but how much should it go up by for each ide controller?

@JoeOsborn
Copy link
Contributor Author

JoeOsborn commented Aug 18, 2023

With #901, the first blocker is done. Next I need to:

  • make sure empty cdroms don’t hose either bios on boot
  • make sure the cdrom is usable for data reads when it's not the boot device (requires some guest OS with a working CD driver)
  • eject the cdrom and make sure the guest notices
  • insert a new cdrom and make sure the guest notices

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant