7

If I have a Memory-mapped I/O device, and I want to write to a register for this device located at address 0x16D34, the 0x16D34 address is actually a virtual address, and the CPU will translate it to a physical address first, and then write the data to the physical address.

But what about Port-mapped I/O devices (for example: a serial port), so if I want to write to a register for a serial port located at address 0x3F8, is the 0x3F8 address a physical address or a virtual address?


Edit: I am on x86 architecture.

Steve
  • 691
  • 5
  • 18
  • 2
    That looks like x86 and not an memory mapped peripheral at all. This particular question will not help you understand. You needd to get the whole picture. A good book about PC architecture would be a good reading. And what do you ask about? virtual memory/memory mapping **or** devicce drivers? They are two very different approaches! – too honest for this site Jun 03 '17 at 11:44
  • @Olaf What does not seem like a peripheral, you mean the address `0x16D34`? it is just a number example I gave, it does not point to anything. – Steve Jun 03 '17 at 12:13
  • IO ports are not memory addresses, so you can't ask whether they're physical or virtual. – harold Jun 03 '17 at 12:19
  • @harold But I thought that when using Memory-mapped I/O, an IO device registers and memory will be considered as memory addresses by the CPU. – Steve Jun 03 '17 at 12:25
  • @Steve: I did not say that. Please read **and comprehend** full sentences! – too honest for this site Jun 03 '17 at 12:27
  • @Steve memory mapped IO is the opposite of IO ports – harold Jun 03 '17 at 12:51
  • @harold Oh! I thought by "IO ports" you meant the registers for a device (for example: serial port). – Steve Jun 03 '17 at 12:55
  • 1
    @harold *"IO ports are not memory addresses, so you can't ask whether they're physical or virtual."* But effectively I can assume that IO ports are physical addresses, as in if I am writing to the address `0x3F8`, data will be written to the address `0x3F8` and not to some translated address, right? – Steve Jun 03 '17 at 12:58
  • 1
    @Cody Gray So what is the number `0x3F8` if it is not an address? I have read everywhere that it is the base **address** for a serial/COM port. – Steve Jun 03 '17 at 13:26
  • 2
    I also have always called them *addresses*. Even the PCI spec, with its BARs (Base Address Registers), call them addresses. They are IO ports addresses but still addresses. Anyway, the IO address space has never been virtualized since 1) it is not a GP address space 2) it is always privileged unless a bitmap of allowed ports is set. Also, the Intel manuals say that writing a word to an aligned port X will write port X and port X+1 in a single bus cycle, exactly like a memory write. It's worth noting that a device can treat a word write to X differently. Writing words were usual in VGA progr. – Margaret Bloom Jun 03 '17 at 14:48
  • @Steve it's the base address in the IO map. This is NOT the same as memory address 0x3F8. Read up on x86 architecture. – ThingyWotsit Jun 03 '17 at 14:48
  • In short: a port address is **not the same** as a memory address. They live in different address-spaces. (except in architectures that use memory mapped i/O , which x86 does not) – wildplasser Jun 03 '17 at 15:24
  • @Margaret Bloom *"the IO address space has never been virtualized"* This answers my question, but you should probably write it in an answer, because this question could be deleted if it only contains comments and no answers *"for reasons of moderation"*. – Steve Jun 04 '17 at 04:18

2 Answers2

5

Port-mapped I/O on x86/x86-64 (most other modern architectures don't even support it) happens in an entirely separate address space. This address space is not subject to memory mapping, so there are no virtual port addresses, only physical ones. Special in and out instructions must be used to perform port I/O, simple memory access (e.g. with mov) can't access this separate address space. Access protection based on privilege level is possible; most modern OSes prevent user space processes from accessing I/O ports by default.

For details, you can for example check the chapter "INPUT/OUTPUT" of Intel's "Intel® 64 and IA-32 Architectures Developer's Manual: Vol. 1" (chapter 18 as of this writing).

Note that in the early days of x86, port addresses were hardwired in each device, including ISA add-in cards. If you were lucky, the card had a set of jumpers for selecting one of a limited set of possible port ranges for the device, in order to avoid range clashes between devices. Later, Plug & Play was introduced to make the selection dynamically during system boot. PCI further refined this, so that I/O BARs can pretty much be mapped anywhere within the 0x0000-0xffff address space by the operating system and/or firmware. Port-mapped I/O is now strongly discouraged when designing new hardware due to its many inherent limitations.

pmdj
  • 22,018
  • 3
  • 52
  • 103
  • 2
    Do x86 CPU's still include a pin to select either memory or I/O when an address is on the bus? This is how I remember things, but college was many years ago for me (from [Memory-Mapped I/O](https://www.cs.umd.edu/class/sum2003/cmsc311/Notes/IO/mapped.html)): *"The only difference between IN and OUT and loading and storing from memory was a single pin of output on the CPU. This pin would be output, say, 0, if the address on the address bus was a memory address, and output 1 if the address was an I/O address"*. – jww Jun 05 '17 at 02:49
  • 2
    @jww I doubt it, today's CPUs have the memory controller built in so there are a lot of pins that go directly to the memory modules, no need for I/O addressing there. They also have direct PCI Express lanes. PCIe uses very few pins, with messages (including address and payload data) being transmitted serially on just a pair of wires (for each direction) for using differential signalling. Maybe for some legacy peripherals, but they're probably in the southbridge anyway. – pmdj Jun 05 '17 at 05:46
0

It seems your question would be the differences between memory-mapped I/O and Port-mapped IO. There normally two methods for processor to connect external devices, which are memory-mapped or port mapped I/O.

Memory-mapped I/O

Memory-mapped I/O uses the same address space to address both memory and I/O devices. So when an address is accessed by the CPU, it may refer to a portion of physical RAM, but it can also refer to memory of the I/O device (Based on Memory-mapped I/O on Wiki).

The value 0x16D34 in your first example would be virtual memory, and would be mapped to the physical memory. The I/O device would refer the same physical memory as well to allow the access from CPU.

Port mapped I/O

Port mapped I/O uses a separate, dedicated address space and is accessed via a dedicated set of microprocessor instructions. For 0x3F8 in your second example, it's the address of the own address specific to Memory and I/O devices. It's not the address shared between memory and I/O devices as we previously mentioned in Memory-mapped I/O. You might get more detailed in Memory-mapped IO vs Port-mapped IO

CWLiu
  • 3,913
  • 1
  • 10
  • 14