Page 1 of 1
port range conflict
Posted: 10. Sep 2014, 07:06
by peterferrie
I'm trying to create a virtual adapter that handles writes to port 0x3f8 and reads from port 0x3f9.
I have enabled the serial port, using a pipe. The pipe client sees writes to port 0x3f8, so that part is working, but it cannot supply the data for the read from port 0x3f9.
So I tried to create a second pipe using a user-defined port number of 0x3f9, but VirtualBox says that the range conflicts with an existing device.
This happens even if I disable the first pipe, so there is nothing registered at 0x3f8.
If I move to another port like 0xccc, then the pipe client sees no writes at all.
How can I create this second pipe?
Re: port range conflict
Posted: 10. Sep 2014, 12:50
by mpack
Re: port range conflict
Posted: 10. Sep 2014, 17:31
by peterferrie
Okay...
VirtualBox is 4.3.16, 64-bit; host is Windows 7, 64-bit, 13353 MByte available; guest is DOS with 128Mb reserved
I can't supply a guest log because I can't start the guest.
Re: port range conflict
Posted: 10. Sep 2014, 18:55
by mpack
Moving this discussion to "Windows Hosts".
Why can't you start the guest? Your description above says that "the pipe client sees writes to port 0x3f8", implying AFAICT that boths ends the pipe are running.
I have not tried using bidirectional I/O to named pipe from a VM, but I have done it for a Windows host application, so there's no fundamental reason by full duplex comms shouldn't work.
What makes you think that it isn't working? What highly reliable interrupt driven serial comms driver have you installed in DOS?
"Guest is DOS with 128MB reserved". 128MB of what, reserved for what? If it's RAM there really no reason I can think of why a DOS guest would need so much. Even if you have an extended memory manager installed I'd have thought (say) 16MB would be plenty. Giving one of these old OS's more resources than they know how to handle can sometimes be a bad idea. That said, I don't see why that would be contributing to your problem here.
Re: port range conflict
Posted: 10. Sep 2014, 20:04
by peterferrie
>Why can't you start the guest?
Because I am getting a port range conflict message from VirtualBox when I attempt to start the guest, if I have registered port 0x3f9.
>Your description above says that "the pipe client sees writes to port 0x3f8", implying AFAICT that boths ends the pipe are running.
I registered port 0x3f8, and then tested the pipe. The test passes because writes to port 0x3f8 are received by the host.
However, it is not possible to supply data to port 0x3f9 through that pipe because the pipe is tied to port 0x3f8.
Any host writes to the pipe will be received on port 0x3f8. So I need a second pipe to supply data to port 0x3f9.
>What makes you think that it isn't working? What highly reliable interrupt driven serial comms driver have you installed in DOS?
It isn't working because I cannot create a pipe on port 0x3f9, because VirtualBox thinks that there is already a device registered on port 0x3f9, even though there isn't one.
The project is to simulate a HASP dongle, since I don't have a real port to which to connect it.
Re: port range conflict
Posted: 10. Sep 2014, 21:03
by peterferrie
In devserial.cpp, it appears that when the serial 1 interface is enabled, 0x3f8-3ff is reserved for use, even when the port is user-defined (and the fact that the host receives no writes from user-defined ports outside of the standard serial range appears to be a bug).
This prevents me from registering port 0x3f9 for my own use.
However, a pipe can interact with only one port, so reserving all 8 of them is not a valid behaviour when a pipe is used.
So, if a serial port is enabled and directed to a pipe, only the defined port should be reserved.
That would allow me to enable the second serial port and create a pipe for the second port of interest to me.
Am I correct in all of this?
Also, I tried LPT as an alternative, using a pipe as the path. It opens the pipe but no writes are detected on the host side.
Re: port range conflict
Posted: 11. Sep 2014, 01:14
by mpack
You have been confusing me with your use of the word "port" to mean an I/O register address, when what I thought you were talking about was an asynch serial port (a UART).
You use the VBox serial port feature to configure the base address of an emulated NS8250/NS16550 UART. Typically that would be 0x3F8 for an emulated COM1. The UART has 8 byte registers which will therefore map to 0x3F8..0x3FF. Obviously two UARTs can't overlap in the I/O map, and a guest OS may not recognize it at strange addresses anyway. And, though I don't know it for a fact, the base address probably is required to be aligned on an 8 or 16 byte boundary, and of course you can't use an address that conflicts with something else.
I see a number of problems with your plans, not least of which is that you don't seem to be familiar with standard UARTs?
If you insist on creating two half duplex serial ports (instead of a single full duplex one), then the standard base addresses are 0x3F8 for COM1 and 0x2F8 for COM2. I don't see a good reason to deviate from that. Note however that the UART TX and RX registers are at different offsets from the base.
Re: port range conflict
Posted: 11. Sep 2014, 02:53
by peterferrie
tl;dr: Is there a way that I can create one pipe to handle access to I/O register address X, and one pipe to handle access to I/O register address X+1?
--
>You have been confusing me with your use of the word "port" to mean an I/O register address
Intel calls them I/O ports, not I/O registers, and that's why I call them like that.
It reserves the term "I/O registers" for something else entirely.
>The UART has 8 byte registers which will therefore map to 0x3F8..0x3FF. Obviously two UARTs can't overlap in the I/O map
Okay, but I can't even create *one* device at a different base address within that range, because VirtualBox is hard-coded to reserve the x8-xF range.
However, that is beside the point.
>I see a number of problems with your plans, not least of which is that you don't seem to be familiar with standard UARTs?
>If you insist on creating two half duplex serial ports (instead of a single full duplex one)
What I'm asking about has nothing to do with UARTs, and I'm not attempting to create actual serial ports.
Even if I were, it is not possible to support 8 registers of a full UART with a pipe.
A pipe can map only one I/O port. If a pipe is in use, then VirtualBox should not reserve the other 7 I/O ports, because the host cannot send any data to them. That's the cause of my problem.
Let me try again to explain this:
What I am trying to do is support an existing legacy software, by intercepting writes to I/O port X, and reads from I/O port X+1, via pipes.
I need to create one pipe to handle I/O port X, and one pipe to handle I/O port X+1, because one pipe cannot be bidirectional to multiple I/O ports.
This is supposed to emulate a parallel port interface, but the VirtualBox LPT handler doesn't pass the I/O port write to the pipe.
So I'm looking for an alternative to the LPT support. The only other place where VirtualBox offers a pipe as an option is in the serial port interface.
However, that doesn't work, either, because I can't create the second pipe because VirtualBox has reserved 8 registers, even though a pipe can handle only one of them.
Is it clear now?
Re: port range conflict
Posted: 11. Sep 2014, 12:14
by mpack
Actually, I'll withdraw something I said above - I was thinking of a different UART. In the NS8250 family, the RX and TX registers both have an offset of 0. On write it causes a transmit, on read it reads the holding register and clears the RXREADY flag.
That means you should be both reading and writing to 0x3F8. Reads from 0x3F9 means you're reading the interrupt ID register (IIR).
peterferrie wrote:
A pipe can map only one I/O port.
That's a rather odd way to put it. The pipe is an analogue of a UART, hence is full duplex - I know that for a fact that because I'm looking right now at my own long-working code module for a full duplex Windows-hosted pipe. As it happens, the C module in question uses the pipe to simulate a UART, though not for a VM. In VirtualBox a pipe can be associated with virtual UART, the UART being identified by it's base address. So yes, a pipe maps to a single UART and therefore to a single base address.
I guess what I'm saying is (a) you're barking up the wrong tree looking to create two pipes, because (b) a single pipe can do full duplex. But as I said before, if you insist on having two pipes treated as if they were half dupliex then you'd need to map them to two different virtual UARTs - at 0x3F8 and 0x2F8. Personally I think you'll just find that you can't read from a half duplex tx-only pipe either, and your problem is something else.
And just to clear something up: whether or not a UART is what you want, the UART is what you have. You have no direct way to communicate with the host. Only the UART simulation can do that, so you do need to know how to talk to a UART.
Re: port range conflict
Posted: 11. Sep 2014, 17:28
by peterferrie
>That means you should be both reading and writing to 0x3F8. Reads from 0x3F9 means you're reading the interrupt ID register (IIR).
As I said before, I am not looking to simulate a UART. I am looking to simulate an *LPT* device, specifically this one:
PORT 0278-027A - PARALLEL PRINTER PORT (usually LPT1). And see here the use of PORT to describe it.
Hence, a write to I/O port X and a read from I/O port X+1.
However, VirtualBox does not write to the pipe when the LPT support is used, but it does write to the pipe when the serial interface is enabled and the UART base address is used.
Therefore, it seemed like the obvious candidate to achieve what I want to do.
>peterferrie wrote:
>A pipe can map only one I/O port.
>That's a rather odd way to put it. The pipe is an analogue of a UART, hence is full duplex ... So yes, a pipe maps to a single UART and therefore to a single base address.
Again with the mismatched terminology while talking about the same thing, and still the issue in VirtualBox remains: you cannot map the same pipe to the other registers, so why are they reserved? If VirtualBox did not reserve the full range which it can't use anyway if a pipe is enabled, then I could simulate the LPT device using the serial interface, and then we would not be having this conversation.
>I guess what I'm saying is (a) you're barking up the wrong tree looking to create two pipes, because (b) a single pipe can do full duplex.
Once again, I don't want full duplex on a single base address. I want to intercept the access to *two* different registers that are next to each other.
>if you insist on having two pipes treated as if they were half dupliex then you'd need to map them to two different virtual UARTs - at 0x3F8 and 0x2F8.
This software writes to I/O port X and reads from I/O port X+1. I do not have the option to force the software to use two separate values for X.
>And just to clear something up: whether or not a UART is what you want, the UART is what you have. You have no direct way to communicate with the host. Only the UART simulation can do that, so you do need to know how to talk to a UART.
You seem to be so focused on the idea of a UART that you can't see any alternative.
When the base address is mapped to a pipe, *it's not a UART anymore*. It is a single memory-mapped I/O register address.
I can create a pipe which intercepts access to that single I/O register address.
Now I want to create a pipe which intercepts access to the memory-mapped I/O register address that's right next to it.
I should be able to do this because when a pipe is used, the other registers should not be reserved because they can't be used.
However, it seems that I cannot do that in the released VirtualBox, because of the hard-coded behaviour to reserve the entire range.
It looks like I will have to build it myself to make it behave like I need it to.
Re: port range conflict
Posted: 11. Sep 2014, 17:35
by mpack
peterferrie wrote:As I said before, I am not looking to simulate a UART. I am looking to simulate an *LPT* device, specifically this one:
It doesn't matter what you are looking to do. You
are enabling a UART simulation and must therefore conform with it's expectations. I see no point in continuing this conversation if even that basic point is not accepted.
I am focused on the idea of a UART because in your first post that's the feature (serial port) which you said you were interested in using. However if any obvious alternative was available then I would have mentioned that too. But, apart from modifying the VBox source code on the host, I don't know of an alternative.
Re: port range conflict
Posted: 11. Sep 2014, 18:51
by peterferrie
>It doesn't matter what you are looking to do. You are enabling a UART simulation and must therefore conform with it's expectations. I see no point in continuing this conversation if even that basic point is not accepted.
Fine, let's pretend that it's really a UART, that's connected to a host pipe.
Please tell me how the host can supply the client with data on any of the other registers in that range? I'd really like to know.
How can the client meaningfully write to the interrupt enable register? That's an important one if I don't want to poll the base register.
How can the client meaningfully read the line status register? That's essential to set the parity and number of data bits.
Can you do that?
If the base address is mapped to a pipe, then it does not behave like a UART anymore. It behaves like a single memory-mapped I/O register.
Re: port range conflict
Posted: 12. Sep 2014, 12:37
by mpack
peterferrie wrote:Fine, let's pretend that it's really a UART, that's connected to a host pipe.
Since that sounds like a reasonably good definition of "virtual UART", I don't see how we could assume anything less.
peterferrie wrote:Please tell me how the host can supply the client with data on any of the other registers in that range? I'd really like to know.
I have not said that you can. In fact I'm pretty sure I've said that you can't. Writing to registers in that range
communicates with the UART - not with the host. It is the UART which communicates with the host, and you can't easily access the API which the UART uses.
I see no purpose in my continually repeating the same facts of life and you telling me it isn't what you want to hear, so I believe I'm done here.