Initial commit

This commit is contained in:
gil 2024-05-13 17:31:37 -05:00
commit 63a2a76b0b
10 changed files with 170 additions and 0 deletions

13
.cargo/config.toml Normal file
View file

@ -0,0 +1,13 @@
# .cargo/config.toml
[build]
target = "riscv32imac-unknown-none-elf"
[target.riscv32imac-unknown-none-elf]
runner = """ qemu-system-riscv32
-cpu rv32
-machine virt
-m 150M
-s
-nographic
-bios """

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

6
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,6 @@
{
"rust-analyzer.check.allTargets": false,
"rust-analyzer.check.targets": [
"riscv32imac-unknown-none-elf"
]
}

26
.vscode/workspace.code-snippets vendored Normal file
View file

@ -0,0 +1,26 @@
{
"Current Timestamp": {
"scope": "markdown,plaintext,yaml",
"prefix": "date",
"body": [
"$CURRENT_YEAR-$CURRENT_MONTH-${CURRENT_DATE}T$CURRENT_HOUR:$CURRENT_MINUTE:$CURRENT_SECOND-05:00"
],
"description": "Add Current date & time"
}
// Place your journal workspace snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
// used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
// Placeholders with the same ids are connected.
// Example:
// "Print to console": {
// "scope": "javascript,typescript",
// "prefix": "log",
// "body": [
// "console.log('$1');",
// "$2"
// ],
// "description": "Log output to console"
// }
}

7
Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "riscv-uefi"
version = "0.1.0"

6
Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "riscv-uefi"
version = "0.1.0"
edition = "2021"
[dependencies]

8
README.md Normal file
View file

@ -0,0 +1,8 @@
---
created: 2024-05-13T14:28:49-05:00
modified: 2024-05-13T14:28:52-05:00
---
Started here: https://www.meyerzinn.tech/posts/2023/03/05/running-rust-code-on-risc-v-in-qemu/
Then here: https://www.meyerzinn.tech/posts/2023/03/08/p1-printing-and-allocating/

8
build.rs Normal file
View file

@ -0,0 +1,8 @@
// build.rs
fn main() {
// Use the linker script.
println!("cargo:rustc-link-arg=-Tsrc/script.ld");
// Don't do any magic linker stuff.
println!("cargo:rustc-link-arg=--omagic");
}

53
src/main.rs Normal file
View file

@ -0,0 +1,53 @@
#![no_std]
#![no_main]
#![feature(naked_functions)]
use core::panic::PanicInfo;
#[naked]
#[no_mangle]
#[link_section = ".text.init"]
unsafe extern "C" fn _start() -> ! {
use core::arch::asm;
asm!(
// before we use the `la` pseudo-instruction for the first time,
// we need to set `gp` (google linker relaxation)
".option push",
".option norelax",
"la gp, _global_pointer",
".option pop",
// set the stack pointer
"la sp, _init_stack_top",
// "tail-call" to {entry} (call without saving a return address)
"tail {entry}",
entry = sym entry, // {entry} refers to the function [entry] below
options(noreturn) // we must handle "returning" from assembly
);
}
extern "C" fn entry() -> ! {
use core::ptr::write_volatile;
let addr = 0x1000_0000 as *mut u8;
{
// Set data size to 8 bits.
unsafe { write_volatile(addr.offset(3), 0b11) };
// Enable FIFO.
unsafe { write_volatile(addr.offset(2), 0b1) };
// Enable receiver buffer interrupts.
unsafe { write_volatile(addr.offset(1), 0b1) };
}
// UART is now set up! Let's print a message.
for byte in "Hello, world!\n".bytes() {
unsafe { write_volatile(addr, byte) };
}
loop {}
}
#[panic_handler]
fn on_panic(_info: &PanicInfo) -> ! {
loop {}
}

42
src/script.ld Normal file
View file

@ -0,0 +1,42 @@
# src/script.ld
OUTPUT_ARCH("riscv")
ENTRY(_start)
MEMORY {
ram (wxa) : ORIGIN = 0x80000000, LENGTH = 128M
}
PHDRS {
text PT_LOAD;
data PT_LOAD;
bss PT_LOAD;
}
SECTIONS {
. = ORIGIN(ram); # start at 0x8000_0000
.text : { # put code first
*(.text.init) # start with anything in the .text.init section
*(.text .text.*) # then put anything else in .text
} >ram AT>ram :text # put this section into the text segment
PROVIDE(_global_pointer = .); # this is magic, google "linker relaxation"
.rodata : { # next, read-only data
*(.rodata .rodata.*)
} >ram AT>ram :text # goes into the text segment as well (since instructions are generally read-only)
.data : { # and the data section
*(.sdata .sdata.*) *(.data .data.*)
} >ram AT>ram :data # this will go into the data segment
.bss :{ # finally, the BSS
PROVIDE(_bss_start = .); # define a variable for the start of this section
*(.sbss .sbss.*) *(.bss .bss.*)
PROVIDE(_bss_end = .); # ... and one at the end
} >ram AT>ram :bss # and this goes into the bss segment
. = ALIGN(16) # our stack needs to be 16-byte aligned, per the C calling convention
PROVIDE(_init_stack_top = . + 0x1000) # reserve 0x1000 bytes for the initialisation stack
}