Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Memory-mapped I/O and port-mapped I/O
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
{{Short description|Method of CPU communication}} {{Refimprove|date=August 2010}} {{About||more generic meanings of input/output ports|Computer port (hardware)|memory-mapped file I/O|Memory-mapped file}} {{Redirect|Port-mapped I/O|the related concept in computing|Programmed input–output}} {{Redirect|MMIO|the airport in Mexico with the code MMIO|Saltillo Airport}} {{Use dmy dates|date=December 2023|cs1-dates=y}} {{Use list-defined references|date=December 2023}} '''Memory-mapped I/O''' ('''MMIO''') and '''port-mapped I/O''' ('''PMIO''') are two complementary methods of performing [[input/output]] (I/O) between the [[central processing unit]] (CPU) and [[peripheral device]]s in a [[computer]] (often mediating access via [[chipset]]). An alternative approach is using dedicated I/O processors, commonly known as [[channel I/O|channels]] on [[mainframe computer]]s, which execute their own [[instruction (computer science)|instruction]]s. '''Memory-mapped I/O''' uses the same [[address space]] to address both [[main memory]]{{Efn|A memory that besides registers is directly accessible by the processor, e.g. [[DRAM]] in [[IBM PC compatible]] computers or Flash/SRAM in microcontrollers.}} and [[I/O device]]s.<ref name="Hayes_1978"/> The memory and [[register (computing)|register]]s of the I/O devices are mapped to (associated with) address values, so a memory address may refer to either a portion of [[physical memory|physical RAM]] or to memory and registers of the I/O device. Thus, the CPU instructions used to access the memory (e.g. {{Code|MOV ...}}) can also be used for accessing devices. Each I/O device either monitors the CPU's address bus and responds to any CPU access of an address assigned to that device, connecting the [[system bus]] to the desired device's [[hardware register]], or uses a dedicated bus. To accommodate the I/O devices, some areas of the address bus used by the CPU must be reserved for I/O and must not be available for normal physical memory; the range of addresses used for I/O devices is determined by the hardware. The reservation may be permanent, or temporary (as achieved via [[bank switching]]). An example of the latter is found in the [[Commodore 64]], which uses a form of memory mapping to cause [[random-access memory|RAM]] or I/O hardware to appear in the <code>0xD000</code>–<code>0xDFFF</code> range. '''Port-mapped I/O''' often uses a special class of CPU instructions designed specifically for performing I/O, such as the <code>in</code> and <code>out</code> instructions found on microprocessors based on the [[x86]] architecture. Different forms of these two instructions can copy one, two or four bytes (<code>outb</code>, <code>outw</code> and <code>outl</code>, respectively) between the [[EAX register]] or one of that register's subdivisions on the CPU and a specified I/O port address which is assigned to an I/O device. I/O devices have a separate address space from general memory, either accomplished by an extra "I/O" pin on the CPU's physical interface, or an entire [[computer bus|bus]] dedicated to I/O. Because the address space for I/O is isolated from that for main memory, this is sometimes referred to as isolated I/O.<ref name="Dandamudi"/> On the x86 architecture, index/data pair is often used for port-mapped I/O.<ref>{{Cite web|url=https://wiki.osdev.org/Bochs_VBE_Extensions|title=Bochs VBE Extensions - OSDev Wiki}}</ref> == Overview == Different CPU-to-device communication methods, such as memory mapping, do not affect the [[direct memory access]] (DMA) for a device, because, by definition, DMA is a memory-to-device communication method that bypasses the CPU. Hardware [[interrupt]]s are another communication method between the CPU and peripheral devices, however, for a number of reasons, interrupts are always treated separately. An interrupt is device-initiated, as opposed to the methods mentioned above, which are CPU-initiated. It is also unidirectional, as information flows only from device to CPU. Lastly, each interrupt line carries only one [[bit]] of information with a fixed meaning, namely "an event that requires attention has occurred in a device on this interrupt line". I/O operations can slow memory access if the address and data buses are shared. This is because the peripheral device is usually much slower than main memory. In some architectures, port-mapped I/O operates via a dedicated I/O bus, alleviating the problem.<!-- can MMIO operate via a dedicated bus too? (see south bridge, IOMMU, ...) --> One merit of memory-mapped I/O is that, by discarding the extra complexity that port I/O brings, a CPU requires less internal logic and is thus cheaper, faster, easier to build, consumes less power and can be physically smaller; this follows the basic tenets of [[RISC|reduced instruction set computing]], and is also advantageous in [[embedded system]]s. The other advantage is that, because regular memory instructions are used to address devices, all of the CPU's addressing modes are available for the I/O as well as the memory, and instructions that perform an [[Arithmetic logic unit|ALU]] operation directly on a memory operand (loading an operand from a memory location, storing the result to a memory location, or both) can be used with I/O device registers as well. In contrast, port-mapped I/O instructions are often very limited, often providing only for simple load-and-store operations between CPU registers and I/O ports, so that, for example, to add a constant to a port-mapped device register would require three instructions: read the port to a CPU register, add the constant to the CPU register, and write the result back to the port. As [[16-bit]] processors have become obsolete and replaced with [[32-bit]] and [[64-bit]] in general use, reserving ranges of memory address space for I/O is less of a problem, as the memory address space of the processor is usually much larger than the required space for all memory and I/O devices in a system. Therefore, it has become more frequently practical to take advantage of the benefits of memory-mapped I/O. However, even with address space being no longer a major concern, neither I/O mapping method is universally superior to the other, and there will be cases where using port-mapped I/O is still preferable. === x86 === Memory-mapped I/O is preferred in [[IA-32]] and [[x86-64]] based architectures because the instructions that perform port-based I/O are limited to one register: EAX, AX, and AL are the only registers that data can be moved into or out of, and either a byte-sized immediate value in the instruction or a value in register DX determines which port is the source or destination port of the transfer.<ref name="Intel_2010_1"/><ref name="Intel_2010_2"/> Since any general-purpose register can send or receive data to or from memory and memory-mapped I/O devices, memory-mapped I/O uses fewer instructions and can run faster than port I/O. [[AMD]] did not extend the port I/O instructions when defining the [[x86-64]] architecture to support 64-bit ports, so 64-bit transfers cannot be performed using port I/O.<ref name="AMD_2009"/> On newer Intel platforms beginning with 2008 [[Intel 5 Series|5 series]], I/O devices on the chipset directly communicate via a dedicated [[Direct Media Interface]] (DMI) bus.{{Efn|See Intel datasheets on specific CPU family e.g. 2014 {{Cite web |date=April 2020 |title=10th Generation Intel Processor Families |url=https://www.intel.com.tw/content/dam/www/public/us/en/documents/datasheets/10th-gen-core-families-datasheet-vol-2-datasheet.pdf |access-date=June 5, 2023 |publisher=[[Intel]]}};}}<ref name="Intel_DMI"/> == Memory barriers == Since the [[Cache (computing)|caches]] mediate accesses to memory addresses, data written to different addresses may reach the peripherals' memory or registers out of the program order, i.e. if software writes data to an address and then writes data to another address, the cache [[write buffer]] does not guarantee that the data will reach the peripherals in that order.<ref name="ARM_Cortex-A"/> Any program that does not include [[Memory barrier|cache-flushing]] instructions after each write in the sequence may see unintended IO effects if a cache system optimizes the write order. Writes to memory can often be reordered to reduce redundancy or to make better use of memory access cycles without changing the final state of what got stored; whereas, the same optimizations might completely change the meaning and effect of writes to memory-mapped I/O regions. Lack of foresight in the choice of memory-mapped I/O regions led to many of the RAM-capacity barriers in older generations of computers. Designers rarely expected machines to grow to make full use of an architecture's theoretical RAM capacity, and thus often used some of the high-order bits of the address-space as selectors for memory-mapped I/O functions. For example, the [[640 KB barrier]] in the IBM PC and derivatives is due to reserving the region between 640 and 1024 KB (64k segments 10 through 16) for the [[Upper Memory Area]]. This choice initially made little impact, but it eventually limited the total amount of RAM available within the 20-bit available address space. The [[3 GB barrier]] and [[PCI hole]] are similar manifestations of this with 32-bit address spaces, exacerbated by details of the [[x86]] boot process and [[Memory management unit|MMU]] design. 64-bit architectures often technically have similar issues, but these only rarely have practical consequences. == Examples == {|class="wikitable floatright" style="margin-left: 1.5em;" |+ A sample system memory map ! Address range ([[hexadecimal]]) ! Size ! Device |- ! 0000–7FFF | 32 KiB | RAM |- ! 8000–80FF | 256 bytes | General-purpose I/O |- ! 9000–90FF | 256 bytes | Sound controller |- ! A000–A7FF | 2 KiB | Video controller/text-mapped display RAM |- ! C000–FFFF | 16 KiB | ROM |} A simple system built around an [[8-bit]] [[microprocessor]] might provide 16-bit address lines, allowing it to address up to 64 [[kibibyte]]s (KiB) of memory. On such a system, the first 32 KiB of address space may be allotted to [[random access memory]] (RAM), another 16 KiB to [[read-only memory]] (ROM) and the remainder to a variety of other devices such as timers, counters, video display chips, sound generating devices, etc. The hardware of the system is arranged so that devices on the address bus will only respond to particular addresses which are intended for them, while all other addresses are ignored. This is the job of the [[address decoder|address decoding circuitry]], and that establishes the [[memory map]] of the system. As a result, system's memory map may look like in the table on the right. This memory map contains gaps, which is also quite common in actual system architectures. Assuming the fourth register of the video controller sets the background colour of the screen, the CPU can set this colour by writing a value to the memory location A003 using its standard memory write instruction. Using the same method, graphs can be displayed on a screen by writing character values into a special area of RAM within the video controller. Prior to cheap [[Random access memory|RAM]] that enabled [[bitmap|bit-mapped displays]], this character cell method was a popular technique for computer video displays (see [[Text user interface]]). == Basic types of address decoding == Address decoding types, in which a device may decode addresses completely or incompletely, include the following: ; {{anchor|Complete decoding}}Complete (exhaustive) decoding : 1:1 mapping of unique addresses to one hardware register (physical memory location). Involves checking every line of the [[address bus]]. ; {{anchor|Incomplete decoding}}Incomplete (partial) decoding : ''n'':1 mapping of n unique addresses to one hardware register. Partial decoding allows a memory location to have more than one address, allowing the programmer to reference a memory location using n different addresses. It may also be done to simplify the decoding hardware by using simpler and often cheaper logic that examines only some address lines, when not all of the CPU's address space is needed. Commonly, the decoding itself is programmable, so the system can reconfigure its own memory map as required, though this is a newer development and generally in conflict with the intent of being cheaper. :Synonyms: foldback, multiply mapped, partially mapped, address [[Aliasing (computing)|aliasing]].<ref name="Microsoft_2001"/><ref name="HP"/> ; Linear decoding : Address lines are used directly without any decoding logic. This is done with devices such as RAMs and ROMs that have a sequence of address inputs, and with peripheral chips that have a similar sequence of inputs for addressing a bank of registers. Linear addressing is rarely used alone (only when there are few devices on the bus, as using purely linear addressing for more than one device usually wastes a lot of address space) but instead is combined with one of the other methods to select a device or group of devices within which the linear addressing selects a single register or memory location. == Port I/O via device drivers == In Windows-based computers, memory can also be accessed via specific drivers such as DOLLx8KD which gives I/O access in 8-, 16- and 32-bit on most Windows platforms starting from Windows 95 up to Windows 7. Installing I/O port drivers will ensure memory access by activating the drivers with simple DLL calls allowing port I/O and when not needed, the driver can be closed to prevent unauthorized access to the I/O ports. Linux provides the {{mono|pcimem}} utility to allow reading from and writing to MMIO addresses. The Linux kernel also allows tracing MMIO access from kernel modules (drivers) using the kernel's ''mmiotrace'' debug facility. To enable this, the Linux kernel should be compiled with the corresponding option enabled. ''mmiotrace'' is used for debugging closed-source device drivers. == See also == * [[Programmed input–output]] * [[mmap]], not to be confused with memory-mapped I/O * [[Memory-mapped file]] * Early examples of computers with port-mapped I/O ** [[PDP-8]] ** [[Data General Nova|Nova]] * [[PDP-11]], an early example of a computer architecture using memory-mapped I/O ** [[Unibus]], a memory and I/O bus used by the PDP-11 * [[Bank switching]] * [[Ralf Brown's Interrupt List]] * [[Coprocessor]] * [[Direct memory access]] * [[Advanced Configuration and Power Interface]] (ACPI) * [[Speculative execution CPU vulnerabilities]] == Notes == {{Notelist}} == References == {{Reflist|refs= <ref name="Hayes_1978">{{cite book |title=Computer Architecture and Organization |author-last=Hayes |author-first=John P. |isbn=0-07-027363-4 |date=1978 |publisher=[[McGraw-Hill International Book Company]] |page=419}}</ref> <ref name="Dandamudi">{{cite book |chapter=Chapter 19 Input/Output Organization |chapter-url=https://people.scs.carleton.ca/~sivarama/org_book/org_book_web/solution_manual/org_soln_one/arch_book_solution_ch19.pdf |title=Fundamentals of Computer Organization and Design |author-first=Sivarama P. |author-last=Dandamudi |date=31 May 2006 |publisher=[[Springer Science+Business Media]] |isbn=978-0-387-21566-2}}</ref> <ref name="Intel_2010_1">{{cite web |url=http://www.intel.com/Assets/PDF/manual/253666.pdf |title=Intel 64 and IA-32 Architectures Software Developer's Manual: Volume 2A: Instruction Set Reference, A-M |date=June 2010 |work= Intel 64 and IA-32 Architectures Software Developer's Manual |publisher=[[Intel Corporation]] |pages=3–520 |access-date=2010-08-21}}</ref> <ref name="Intel_2010_2">{{cite web |url= http://www.intel.com/Assets/PDF/manual/253667.pdf |title=Intel 64 and IA-32 Architectures Software Developer's Manual: Volume 2B: Instruction Set Reference, N-Z |date=June 2010 |work= Intel 64 and IA-32 Architectures Software Developer's Manual |publisher=[[Intel Corporation]] |pages=4–22 |access-date=2010-08-21}}</ref> <ref name="AMD_2009">{{cite web |url=https://www.amd.com/system/files/TechDocs/24594.pdf |title=AMD64 Architecture Programmer's Manual: Volume 3: General-Purpose and System Instructions |date=November 2009 |work=AMD64 Architecture Programmer's Manual |publisher=[[Advanced Micro Devices]] |pages=117, 181 |access-date=2010-08-21}}</ref> <ref name="Intel_DMI">{{cite web |title=What Is the Direct Media Interface (DMI) of Intel Processors? |url=https://www.intel.com/content/www/in/en/support/articles/000094185/processors.html |access-date=2023-06-05 |website=Intel |language=en}}</ref> <ref name="ARM_Cortex-A">{{cite book |title=ARM Cortex-A Series Programmer's Guide. Literature number ARM DEN0013D |pages=10–13}}</ref> <ref name="Microsoft_2001">{{cite web |url=http://www.microsoft.com/whdc/system/sysinternals/partialaddress.mspx#EFD |publisher=[[Microsoft]] |date=2001-12-04 |title=Partial Address Decoding and I/O Space in Windows Operating Systems}}</ref> <ref name="HP">{{cite web |url=http://docs.hp.com/en/A3725-96022/ch03s03.html |publisher=[[Hewlett-Packard]] |title=Address aliasing}}</ref> }} {{Processor technologies|state=collapsed}} {{DEFAULTSORT:Memory-Mapped I O}} [[Category:Input/output]]
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)
Pages transcluded onto the current version of this page
(
help
)
:
Template:About
(
edit
)
Template:Anchor
(
edit
)
Template:Cite web
(
edit
)
Template:Code
(
edit
)
Template:Efn
(
edit
)
Template:Mono
(
edit
)
Template:Notelist
(
edit
)
Template:Processor technologies
(
edit
)
Template:Redirect
(
edit
)
Template:Refimprove
(
edit
)
Template:Reflist
(
edit
)
Template:Short description
(
edit
)
Template:Use dmy dates
(
edit
)
Template:Use list-defined references
(
edit
)