MM92x
MM92x

Reputation: 568

How to read or write an I/O port in arm64?

I was trying to write one byte to an I/O port, but I am failing finding the correct instructions in the instruction set of arm64 aarch64 architecture.

To do the same thing in i386, I'd do something of similar:

void dbg_io_write_8(uint16_t port, uint8_t val)
{
    asm volatile (
        "outb    %%al, %%dx;"
        /* Outputs  */ : /* None */
        /* Inputs   */ : "a" (val), "d" (port)
        /* Clobbers */ : /* None */
        );
}

And, for reading:

uint8_t dbg_io_read_8(uint16_t port)
{
    uint8_t val;

    asm volatile (
        "inb     %%dx, %%al;"
        /* Outputs  */ : "=a" (val)
        /* Inputs   */ : "d" (port)
        /* Clobbers */ : /* None */
        );

    return val;
}

This code refers to the NS16550 serial port.

Upvotes: 0

Views: 1595

Answers (2)

XYZ
XYZ

Reputation: 189

Take a look at outb(): https://elixir.bootlin.com/linux/latest/source/arch/arm/include/asm/io.h#L235

eventually the outb() access is converted to memory access using += PCI_IO_VIRT_BASE (=0xfee00000)

Upvotes: 1

Siguza
Siguza

Reputation: 23850

arm64 has no concept of I/O ports.

If you are both a CPU vendor and a SoC designer, and have a very good reason for it, you might opt to map a peripheral to a (set of) custom system register(s). In that case you'd talk to the peripheral via mrs/msr.

In all other cases, you memory-map it to some physical address. So you access it through simple loads and stores.

Upvotes: 4

Related Questions