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

IO address spaces #9815

Open
Snektron opened this issue Sep 21, 2021 · 0 comments
Open

IO address spaces #9815

Snektron opened this issue Sep 21, 2021 · 0 comments
Labels
accepted This proposal is planned. arch-avr 8-bit AVR proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@Snektron
Copy link
Collaborator

Snektron commented Sep 21, 2021

Some CPU architectures have specific instructions to write to and read from IO ports, which are often used to communicate with peripherals attached to the machine. Typically, such instructions are not available from higher level languages, and programmers intending to write to or read from IO ports are required to use (inline) assembly to perform these operations. With the advent of pointer address spaces in the stage 2 compiler (see #653), these instructions could be supported without requiring inline assembly by introducing an IO address space. Writing a value to a pointer with the IO address space would output the value to the port number equal to the pointer's integer value. For example:

const LineStatus = packed struct {
    ...
    tx_buffer_empty: bool,
    ...
};

const serial_data = @intToPtr(*addrspace(.io) volatile u8, 0x3F8);
const serial_line_status = @intToPtr(*addrspace(.io) volatile LineStatus, 0x3F8 + 5);

fn busyWrite(data: u8) void {
    while (!serial_line_status.tx_buffer_empty)
        continue;
    serial_data.* = data;
}

There are two architectures i know of for which this is relevant, x86 and AVR. In the former case, the port index can be given both by an immediate and by a dynamic value (provided by a register). In the case of AVR, however, the port index must be passed as an immediate value. I believe that this can be resolved simply by enforcing that IO pointers are comptime known in the target architecture requires this.

In terms of implementation, LLVM does not support IO pointers, and so the compiler would be required to emit inline assembly for these. Pointer can then be represented in LLVM either as simple integers or as pointers tagged with a custom address space.

I do admit that this is a relatively niche feature, as most architectures use memory mapped IO nowadays, and a userland implementation that achieves the same effect usually isn't a lot of code either.

@andrewrk andrewrk added accepted This proposal is planned. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. arch-avr 8-bit AVR labels Nov 20, 2021
@andrewrk andrewrk added this to the 0.10.0 milestone Nov 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted This proposal is planned. arch-avr 8-bit AVR proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

2 participants