Created
February 9, 2019 14:37
-
-
Save cheery/5b2466edc4007a4f932a16d7a1c0b1df to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This program draws 100 frames of noise to the screen and then stops. | |
# Using linux framebuffers. | |
# https://content.riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf | |
# https://en.wikichip.org/wiki/risc-v/registers | |
# https://rv8.io/syscalls.html | |
.section .text | |
.globl _start # stop ld from nagging. | |
.org 0 | |
load_address = 0x010000 # can also use: 0x08048000 | |
ehdr: | |
.byte 0x7f, 0x45, 0x4c, 0x46, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 | |
.half 2 # e_type | |
.half 0xf3 # e_machine | |
.word 1 # e_version | |
.quad load_address + _start - ehdr # e_entry | |
.quad phdr - ehdr # e_phoff | |
.quad 0 # e_shoff | |
.word 0 # e_flags | |
.half ehdrsize # e_ehsize (64) | |
.half phdrsize # e_phentsize (56) | |
.half 1 # e_phnum | |
.half 0 # e_shentsize (64) | |
.half 0 # e_shnum | |
.half 0 # e_shstrndx | |
ehdrsize = . - ehdr | |
phdr: | |
.word 1 # p_type | |
.word 5 # p_flags | |
.quad 0 # p_offset | |
.quad load_address # p_vaddr | |
.quad load_address # p_paddr | |
.quad filesize # p_filesz | |
.quad filesize # p_memsz | |
.quad 0x1000 # p_align | |
phdrsize = . - phdr | |
# Linux system call numbers we are using, https://rv8.io/syscalls.html | |
sys_ioctl = 29 | |
sys_close = 57 | |
sys_read = 63 | |
sys_write = 64 | |
sys_exit = 93 | |
sys_brk = 214 | |
sys_munmmap = 215 | |
sys_mmap = 222 | |
sys_open = 1024 | |
# standard file numbers | |
stdin = 0 | |
stdout = 1 | |
stderr = 2 | |
# Some file flags we need | |
O_RDWR = 0x0002 | |
PROT_READ = 0x1 | |
PROT_WRITE = 0x2 | |
PROT_EXEC = 0x4 | |
PROT_READ_WRITE = 0x3 | |
MAP_SHARED = 0x1 | |
MAP_PRIVATE = 0x2 | |
MAP_FIXED = 0x10 | |
MAP_ANON = 0x20 | |
# Some framebuffer flags we need | |
FBIOGET_VSCREENINFO = 0x4600 | |
FBIOGET_FSCREENINFO = 0x4602 | |
GET_VSCREENINFO = 0x80A04600 | |
GET_FSCREENINFO = 0x80504602 | |
fb_var_screeninfo_size = 160 | |
# struct fb_var_screeninfo { | |
# 0 __u32 xres; /* visible resolution */ | |
# 4 __u32 yres; | |
# 8 __u32 xres_virtual; /* virtual resolution */ | |
# 12 __u32 yres_virtual; | |
# 16 __u32 xoffset; /* offset from virtual to visible */ | |
# 20 __u32 yoffset; /* resolution */ | |
# | |
# 24 __u32 bits_per_pixel; /* guess what */ | |
# 28 __u32 grayscale; /* 0 = color, 1 = grayscale, */ | |
# /* >1 = FOURCC */ | |
# 32 struct fb_bitfield red; /* bitfield in fb mem if true color, */ | |
# 44 struct fb_bitfield green; /* else only length is significant */ | |
# 56 struct fb_bitfield blue; | |
# 68 struct fb_bitfield transp; /* transparency */ | |
# | |
# 80 __u32 nonstd; /* != 0 Non standard pixel format */ | |
# | |
# 84 __u32 activate; /* see FB_ACTIVATE_* */ | |
# | |
# 88 __u32 height; /* height of picture in mm */ | |
# 92 __u32 width; /* width of picture in mm */ | |
# | |
# 96 __u32 accel_flags; /* (OBSOLETE) see fb_info.flags */ | |
# | |
# /* Timing: All values in pixclocks, except pixclock (of course) */ | |
# 100 __u32 pixclock; /* pixel clock in ps (pico seconds) */ | |
# 104 __u32 left_margin; /* time from sync to picture */ | |
# 108 __u32 right_margin; /* time from picture to sync */ | |
# 112 __u32 upper_margin; /* time from sync to picture */ | |
# 116 __u32 lower_margin; | |
# 120 __u32 hsync_len; /* length of horizontal sync */ | |
# 124 __u32 vsync_len; /* length of vertical sync */ | |
# 128 __u32 sync; /* see FB_SYNC_* */ | |
# 132 __u32 vmode; /* see FB_VMODE_* */ | |
# 136 __u32 rotate; /* angle we rotate counter clockwise */ | |
# 140 __u32 colorspace; /* colorspace for FOURCC-based modes */ | |
# __u32 reserved[4]; /* Reserved for future compatibility */ | |
fb_bitfield_size = 12 | |
# struct fb_bitfield { | |
# 0 __u32 offset; /* beginning of bitfield */ | |
# 4 __u32 length; /* length of bitfield */ | |
# 8 __u32 msb_right; /* != 0 : Most significant bit is */ | |
# /* right */ | |
# }; | |
fb_fix_screeninfo_size = 80 | |
# struct fb_fix_screeninfo { | |
# 0 char id[16]; /* identification string eg "TT Builtin" */ | |
# 16 unsigned long smem_start; /* Start of frame buffer mem */ | |
# /* (physical address) */ | |
# 24 __u32 smem_len; /* Length of frame buffer mem */ | |
# 28 __u32 type; /* see FB_TYPE_* */ | |
# 32 __u32 type_aux; /* Interleave for interleaved Planes */ | |
# 36 __u32 visual; /* see FB_VISUAL_* */ | |
# 40 __u16 xpanstep; /* zero if no hardware panning */ | |
# 42 __u16 ypanstep; /* zero if no hardware panning */ | |
# 44 __u16 ywrapstep; /* zero if no hardware ywrap */ | |
# 48 __u32 line_length; /* length of a line in bytes */ | |
# 56 unsigned long mmio_start; /* Start of Memory Mapped I/O */ | |
# /* (physical address) */ | |
# 64 __u32 mmio_len; /* Length of Memory Mapped I/O */ | |
# 68 __u32 accel; /* Indicate to driver which */ | |
# /* specific chip/card we have */ | |
# 72 __u16 capabilities; /* see FB_CAP_* */ | |
# __u16 reserved[2]; /* Reserved for future compatibility */ | |
# }; | |
_start: | |
lla a0, fb0_path | |
li a1, O_RDWR | |
li a2, 0 | |
li a7, sys_open | |
ecall | |
blt a0, zero, fail # Fail if cannot open the file. | |
mv gp, a0 # gp = fbfd | |
addi sp, sp, -fb_fix_screeninfo_size | |
mv a0, gp # fbfd | |
li a1, FBIOGET_VSCREENINFO | |
mv a2, sp # The screeninfo size pointer. | |
li a7, sys_ioctl | |
ecall | |
blt a0, zero, fail | |
li a0, stdout | |
lla a1, greeting | |
li a2, 6 | |
li a7, sys_write | |
ecall | |
addi sp, sp, -fb_var_screeninfo_size | |
mv a0, gp # fbfd | |
li a1, FBIOGET_VSCREENINFO | |
mv a2, sp # The screeninfo size pointer. | |
li a7, sys_ioctl | |
ecall | |
blt a0, zero, fail | |
# screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8 | |
lw a0, 0(sp) # xres | |
lw a1, 4(sp) # yres | |
lw a2, 24(sp) # bits_per_pixel | |
mul a0, a0, a1 # t = xres * yres | |
mul a0, a0, a2 # t = t * bits_per_pixel | |
srl t0, a0, 3 # >> 8 | |
#t0 = screen size | |
#li t0, 16588800 | |
li a0, 0 | |
mv a1, t0 # The screen size. | |
li a2, PROT_READ_WRITE | |
li a3, MAP_SHARED | |
mv a4, gp # fbfd | |
li a5, 0 # offset | |
li a7, sys_mmap | |
ecall | |
blt a0, zero, fail # Fail if mapping failed. | |
mv tp, a0 # tp = screenbuffer | |
# seed for the random number generator. | |
rdtime a0 | |
lcg_multiplier = 1664525 | |
lui a1, %hi(lcg_multiplier) | |
addi a1, a1, %lo(lcg_multiplier) | |
lcg_increment = 1013904223 | |
lui a2, %hi(lcg_increment) | |
addi a2, a2, %lo(lcg_increment) | |
li a7, 100 # do 100 times. | |
repeat_fill: | |
blt a7, zero, repeat_done | |
# the current pointer. | |
li a3, 0 | |
fill_screen_with_garbage: | |
bge a3, t0, fill_screen_with_garbage_done | |
mul a4, a0, a1 # seed = (a * seed + c) % m | |
add a0, a4, a2 | |
srl a6, a0, 24 | |
add a5, tp, a3 # screenbuffer + index | |
sb a6, 0(a5) | |
# location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + | |
# (y+vinfo.yoffset) * finfo.line_length; | |
addi a3, a3, 1 | |
j fill_screen_with_garbage | |
fill_screen_with_garbage_done: | |
addi a7, a7, -1 | |
j repeat_fill | |
repeat_done: | |
# li a0, stdout | |
# lla a1, greeting | |
# li a2, 6 | |
# li a7, sys_write | |
# ecall | |
li a0, 0 | |
li a7, sys_exit | |
ecall | |
fail: | |
li a0, 1 | |
li a7, sys_exit | |
ecall | |
loop: j loop | |
greeting: | |
.string "Hello\n" | |
fb0_path: | |
.string "/dev/fb0" | |
.byte 0 | |
filesize = . - ehdr |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# There was a bug in the riscv toolchain preventing use of --oformat binary. | |
# Use of objcopy is a workaround for it. | |
noise: noise.elf | |
riscv64-unknown-elf-objcopy -O binary $^ $@ | |
chmod +x $@ | |
noise.elf: listing.s | |
riscv64-unknown-elf-gcc -nostartfiles $^ -o $@ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment