aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xelf.py25
-rw-r--r--examples/device_tree.format152
-rw-r--r--examples/device_tree.pack159
-rw-r--r--examples/device_tree.survey152
-rw-r--r--examples/device_tree.valid152
-rw-r--r--examples/ex.elfbin8224 -> 488 bytes
-rw-r--r--examples/ex.subv47
-rw-r--r--examples/hello_world.subv17
-rw-r--r--subv.py10
9 files changed, 686 insertions, 28 deletions
diff --git a/elf.py b/elf.py
index 62ba46d..8b7c6a7 100755
--- a/elf.py
+++ b/elf.py
@@ -191,27 +191,34 @@ def elf(iter):
out = ELF(
e_class=ELFCLASS.ELFCLASS32,
e_data=ELFDATA.ELFDATA2LSB,
- e_type=ET.ET_EXEC,
+ e_type=ET.ET_REL,
e_machine=EM(0xF3),
)
out.Elf.Ehdr.e_entry = next(s for s in segments if s["name"] == "code")["addr"]
- out.Elf.Ehdr.e_flags = 4
out.Elf.Phdr_table.clear()
- seg_ids = {}
+ sec_ids = {}
for seg in segments:
- flags = "rx" if seg["name"] == "code" else "rw"
name = SECTION_NAMES[seg["name"]]
- id = out._append_section(name, seg["content"], seg["addr"], sh_addralign=0x1000)
- out.append_segment(id, flags=flags)
- seg_ids[seg["name"]] = id
+ sec_flags = SHF.SHF_ALLOC
+ seg_flags = "w"
+ if seg["name"] == "code":
+ sec_flags |= SHF.SHF_EXECINSTR
+ seg_flags += "x"
+ else:
+ sec_flags |= SHF.SHF_WRITE
+ seg_flags += "w"
+
+ id = out._append_section(name, seg["content"], seg["addr"], sh_addralign=4, sh_flags=sec_flags)
+ # out.append_segment(id, flags=seg_flags)
+ sec_ids[seg["name"]] = id
for label in labels:
- sect_id = seg_ids[label["segment"]]
+ sect_id = sec_ids[label["segment"]]
out.append_symbol(
- label["name"], sect_id, label["offset"], 4, sym_type=STT.STT_FUNC
+ label["name"], sect_id, label["offset"], 4, sym_type=STT.STT_FUNC, sym_binding=STB.STB_GLOBAL
)
sys.stdout.buffer.write(bytes(out))
diff --git a/examples/device_tree.format b/examples/device_tree.format
new file mode 100644
index 0000000..ca4f2bd
--- /dev/null
+++ b/examples/device_tree.format
@@ -0,0 +1,152 @@
+== code 0x80400000
+# main:
+# print device tree info.
+# OpenSBI calls us with a1 set to the start of the DTB
+# load 0x10000000 (UART0) into a0
+37/7 0a/5 10000/20
+
+13/7 15/5 0/3 0b/5 000/12
+
+# check magic == 0xd00dfeed
+37/7 06/5 edfe1/20
+13/7 06/5 0/3 06/5 dd0/12
+03/7 05/5 2/3 15/5 000/12
+63/7 0/1 c/4 1/3 05/5 06/5 01/6 0/1
+
+37/7 0b/5 80500/20
+13/7 0b/5 0/3 0b/5 014/12
+6f/7 01/5 00/8 0/1 044/10 0/1
+
+03/7 0b/5 2/3 15/5 004/12
+6f/7 01/5 00/8 0/1 01a/10 0/1
+6f/7 01/5 00/8 0/1 050/10 0/1
+6f/7 01/5 00/8 0/1 030/10 0/1
+
+# exit:
+# system reset (via SBI extension SRST)
+# a7 = ext id, a6 = fid, a0 = 0, a1 = 0
+37/7 11/5 53525/20
+13/7 11/5 0/3 11/5 354/12
+33/7 10/5 0/3 00/5 00/5 00/7
+33/7 0a/5 0/3 00/5 00/5 00/7
+33/7 0b/5 0/3 00/5 00/5 00/7
+# ECALL
+73/7 00/5 0/3 00/5 000/12
+
+# err_magic:
+37/7 0b/5 80500/20
+13/7 0b/5 0/3 0b/5 000/12
+6f/7 01/5 00/8 0/1 02a/10 0/1
+6f/7 00/5 ff/8 1/1 3ee/10 1/1
+
+# bswapw:
+# byte-order-swap word in a1
+# srli a1, a0, 8
+# lui a2, 16
+# addi a2, a2, -256
+# and a1, a1, a2
+13/7 05/5 5/3 0b/5 008/12
+37/7 06/5 00016/20
+13/7 06/5 0/3 06/5 f00/12
+33/7 05/5 7/3 05/5 06/5 00/7
+# srli a2, a0, 24
+# or a1, a1, a2
+13/7 06/5 5/3 0b/5 018/12
+33/7 05/5 6/3 05/5 06/5 00/7
+# slli a2, a0, 8
+# lui a3, 4080
+# and a2, a2, a3
+13/7 06/5 1/3 0b/5 008/12
+37/7 07/5 00ff0/20
+33/7 06/5 7/3 06/5 07/5 00/7
+# slli a0, a0, 24
+# or a0, a0, a2
+# or a0, a0, a1
+13/7 0b/5 1/3 0b/5 018/12
+33/7 0b/5 6/3 0b/5 06/5 00/7
+33/7 0b/5 6/3 0b/5 05/5 00/7
+# ret
+67/7 00/5 0/3 01/5 000/12
+
+# printnl:
+13/7 06/5 0/3 00/5 00a/12
+# printnl:spin:
+# spin if FIFO is full (thr_emtpy = UART+5 & 0x20)
+03/7 07/5 4/3 0a/5 005/12
+13/7 07/5 7/3 07/5 020/12
+63/7 1/1 c/4 0/3 07/5 00/5 3f/6 1/1
+# print char
+23/7 00/5 2/3 0a/5 06/5 00/7
+# return
+67/7 00/5 0/3 01/5 000/12
+
+# print:
+# print:loop:
+# load unsigned byte at a1
+03/7 06/5 4/3 0b/5 000/12
+# break loop if zero
+63/7 0/1 e/4 0/3 06/5 00/5 00/6 0/1
+# print:spin:
+# spin if FIFO is full (thr_emtpy = UART+5 & 0x20)
+03/7 07/5 4/3 0a/5 005/12
+13/7 07/5 7/3 07/5 020/12
+63/7 1/1 c/4 0/3 07/5 00/5 3f/6 1/1
+# print char
+23/7 00/5 2/3 0a/5 06/5 00/7
+# increment a1
+13/7 0b/5 0/3 0b/5 001/12
+# jump back up
+6f/7 00/5 ff/8 1/1 3f2/10 1/1
+# print:break:
+# return
+67/7 00/5 0/3 01/5 000/12
+
+# print_hex_word:
+13/7 08/5 0/3 0b/5 000/12
+13/7 09/5 0/3 00/5 01c/12
+13/7 12/5 0/3 01/5 000/12
+# print_hex_word:loop:
+# shift
+33/7 0b/5 5/3 08/5 09/5 00/7
+6f/7 01/5 00/8 0/1 00a/10 0/1
+
+# break if last shift
+63/7 0/1 6/4 0/3 09/5 00/5 00/6 0/1
+
+# subtract shift count, loop
+13/7 09/5 0/3 09/5 ffc/12
+6f/7 00/5 ff/8 1/1 3f8/10 1/1
+# print_hex_word:break:
+# return
+67/7 00/5 0/3 12/5 000/12
+
+# print_hex_dgt:
+# a1 = a1 & 0xf
+13/7 0b/5 7/3 0b/5 00f/12
+# t1 = 0x40
+13/7 06/5 0/3 00/5 040/12
+
+# add 0x30 (ascii '0') / 0x61 (ascii 'a')
+13/7 0b/5 0/3 0b/5 030/12
+63/7 0/1 4/4 4/3 0b/5 06/5 00/6 0/1
+13/7 0b/5 0/3 0b/5 027/12
+
+# print_hex_dgt:spin:
+# spin if FIFO is full (thr_emtpy = UART+5 & 0x20)
+03/7 07/5 4/3 0a/5 005/12
+13/7 07/5 7/3 07/5 020/12
+63/7 1/1 c/4 0/3 07/5 00/5 3f/6 1/1
+
+# print char
+23/7 00/5 2/3 0a/5 0b/5 00/7
+
+# return
+67/7 00/5 0/3 01/5 000/12
+
+== data 0x80500000
+# E_MAGIC:
+# "Invalid DTB magic!\n\0"
+49/8 6e/8 76/8 61/8 6c/8 69/8 64/8 20/8 44/8 54/8 42/8 20/8 6d/8 61/8 67/8 69/8 63/8 21/8 a/8 0/8
+# S_TOTALSZ:
+54/8 6f/8 74/8 61/8 6c/8 20/8 53/8 69/8 7a/8 65/8 3a/8 20/8 0/8
+
diff --git a/examples/device_tree.pack b/examples/device_tree.pack
new file mode 100644
index 0000000..0d54554
--- /dev/null
+++ b/examples/device_tree.pack
@@ -0,0 +1,159 @@
+== code 0x80400000
+# main:
+# print device tree info.
+# OpenSBI calls us with a1 set to the start of the DTB
+# load 0x10000000 (UART0) into a0
+37 05 00 10
+
+93 8a 05 00
+
+# check magic == 0xd00dfeed
+37 13 fe ed
+13 03 03 dd
+83 a2 0a 00
+63 9c 62 02
+
+b7 05 50 80
+93 85 45 01
+ef 00 80 08
+
+83 a5 4a 00
+ef 00 40 03
+ef 00 00 0a
+ef 00 00 06
+
+# exit:
+# system reset (via SBI extension SRST)
+# a7 = ext id, a6 = fid, a0 = 0, a1 = 0
+b7 58 52 53
+93 88 48 35
+33 08 00 00
+33 05 00 00
+b3 05 00 00
+# ECALL
+73 00 00 00
+
+# err_magic:
+b7 05 50 80
+93 85 05 00
+ef 00 40 05
+6f f0 df fd
+
+# bswapw:
+# byte-order-swap word in a1
+# srli a1, a0, 8
+# lui a2, 16
+# addi a2, a2, -256
+# and a1, a1, a2
+93 d2 85 00
+37 63 01 00
+13 03 03 f0
+b3 f2 62 00
+# srli a2, a0, 24
+# or a1, a1, a2
+13 d3 85 01
+b3 e2 62 00
+# slli a2, a0, 8
+# lui a3, 4080
+# and a2, a2, a3
+13 93 85 00
+b7 03 ff 00
+33 73 73 00
+# slli a0, a0, 24
+# or a0, a0, a2
+# or a0, a0, a1
+93 95 85 01
+b3 e5 65 00
+b3 e5 55 00
+# ret
+67 80 00 00
+
+# printnl:
+13 03 a0 00
+# printnl:spin:
+# spin if FIFO is full (thr_emtpy = UART+5 & 0x20)
+83 43 55 00
+93 f3 03 02
+e3 8c 03 fe
+# print char
+23 20 65 00
+# return
+67 80 00 00
+
+# print:
+# print:loop:
+# load unsigned byte at a1
+03 c3 05 00
+# break loop if zero
+63 0e 03 00
+# print:spin:
+# spin if FIFO is full (thr_emtpy = UART+5 & 0x20)
+83 43 55 00
+93 f3 03 02
+e3 8c 03 fe
+# print char
+23 20 65 00
+# increment a1
+93 85 15 00
+# jump back up
+6f f0 5f fe
+# print:break:
+# return
+67 80 00 00
+
+# print_hex_word:
+13 84 05 00
+93 04 c0 01
+13 89 00 00
+# print_hex_word:loop:
+# shift
+b3 55 94 00
+ef 00 40 01
+
+# break if last shift
+63 86 04 00
+
+# subtract shift count, loop
+93 84 c4 ff
+6f f0 1f ff
+# print_hex_word:break:
+# return
+67 00 09 00
+
+# print_hex_dgt:
+# a1 = a1 & 0xf
+93 f5 f5 00
+# t1 = 0x40
+13 03 00 04
+
+# add 0x30 (ascii '0') / 0x61 (ascii 'a')
+93 85 05 03
+63 c4 65 00
+93 85 75 02
+
+# print_hex_dgt:spin:
+# spin if FIFO is full (thr_emtpy = UART+5 & 0x20)
+83 43 55 00
+93 f3 03 02
+e3 8c 03 fe
+
+# print char
+23 20 b5 00
+
+# return
+67 80 00 00
+
+== data 0x80500000
+# E_MAGIC:
+# "Invalid DTB magic!\n\0"
+49 6e 76 61
+6c 69 64 20
+44 54 42 20
+6d 61 67 69
+63 21 0a 00
+# S_TOTALSZ:
+54 6f 74 61
+6c 20 53 69
+7a 65 3a 20
+
+00
diff --git a/examples/device_tree.survey b/examples/device_tree.survey
new file mode 100644
index 0000000..7bee7df
--- /dev/null
+++ b/examples/device_tree.survey
@@ -0,0 +1,152 @@
+== code 0x80400000
+# main:
+# print device tree info.
+# OpenSBI calls us with a1 set to the start of the DTB
+# load 0x10000000 (UART0) into a0
+37/u a/rd 10000/imm20
+
+13/i 15/rd 0/funct3 b/rs 0/imm12
+
+# check magic == 0xd00dfeed
+37/u 6/rd edfe1/imm20
+13/i 6/rd 0/funct3 6/rs dd0/imm12
+3/i 5/rd 2/funct3 15/rs 0/imm12
+63/b 1/funct3 5/rs1 6/rs2 38/imm13
+
+37/u b/rd 80500/imm20
+13/i b/rd 0/funct3 b/rs 14/imm12
+6f/j 1/rd 88/imm21
+
+3/i b/rd 2/funct3 15/rs 4/imm12
+6f/j 1/rd 34/imm21
+6f/j 1/rd a0/imm21
+6f/j 1/rd 60/imm21
+
+# exit:
+# system reset (via SBI extension SRST)
+# a7 = ext id, a6 = fid, a0 = 0, a1 = 0
+37/u 11/rd 53525/imm20
+13/i 11/rd 0/funct3 11/rs 354/imm12
+33/r 10/rd 0/funct3 0/rs1 0/rs2 0/funct7
+33/r a/rd 0/funct3 0/rs1 0/rs2 0/funct7
+33/r b/rd 0/funct3 0/rs1 0/rs2 0/funct7
+# ECALL
+73/i 0/rd 0/funct3 0/rs 0/imm12
+
+# err_magic:
+37/u b/rd 80500/imm20
+13/i b/rd 0/funct3 b/rs 0/imm12
+6f/j 1/rd 54/imm21
+6f/j 0/rd -24/imm21
+
+# bswapw:
+# byte-order-swap word in a1
+# srli a1, a0, 8
+# lui a2, 16
+# addi a2, a2, -256
+# and a1, a1, a2
+13/i 5/rd 5/funct3 b/rs 8/imm12
+37/u 6/rd 16/imm20
+13/i 6/rd 0/funct3 6/rs -100/imm12
+33/r 5/rd 7/funct3 5/rs1 6/rs2 0/funct7
+# srli a2, a0, 24
+# or a1, a1, a2
+13/i 6/rd 5/funct3 b/rs 18/imm12
+33/r 5/rd 6/funct3 5/rs1 6/rs2 0/funct7
+# slli a2, a0, 8
+# lui a3, 4080
+# and a2, a2, a3
+13/i 6/rd 1/funct3 b/rs 8/imm12
+37/u 7/rd ff0/imm20
+33/r 6/rd 7/funct3 6/rs1 7/rs2 0/funct7
+# slli a0, a0, 24
+# or a0, a0, a2
+# or a0, a0, a1
+13/i b/rd 1/funct3 b/rs 18/imm12
+33/r b/rd 6/funct3 b/rs1 6/rs2 0/funct7
+33/r b/rd 6/funct3 b/rs1 5/rs2 0/funct7
+# ret
+67/i 0/rd 0/funct3 1/rs 0/imm12
+
+# printnl:
+13/i 6/rd 0/funct3 0/rs a/imm12
+# printnl:spin:
+# spin if FIFO is full (thr_emtpy = UART+5 & 0x20)
+3/i 7/rd 4/funct3 a/rs 5/imm12
+13/i 7/rd 7/funct3 7/rs 20/imm12
+63/b 0/funct3 7/rs1 0/rs2 -8/imm13
+# print char
+23/s 2/funct3 a/rs1 0/imm12 6/rs2
+# return
+67/i 0/rd 0/funct3 1/rs 0/imm12
+
+# print:
+# print:loop:
+# load unsigned byte at a1
+3/i 6/rd 4/funct3 b/rs 0/imm12
+# break loop if zero
+63/b 0/funct3 6/rs1 0/rs2 1c/imm13
+# print:spin:
+# spin if FIFO is full (thr_emtpy = UART+5 & 0x20)
+3/i 7/rd 4/funct3 a/rs 5/imm12
+13/i 7/rd 7/funct3 7/rs 20/imm12
+63/b 0/funct3 7/rs1 0/rs2 -8/imm13
+# print char
+23/s 2/funct3 a/rs1 0/imm12 6/rs2
+# increment a1
+13/i b/rd 0/funct3 b/rs 1/imm12
+# jump back up
+6f/j 0/rd -1c/imm21
+# print:break:
+# return
+67/i 0/rd 0/funct3 1/rs 0/imm12
+
+# print_hex_word:
+13/i 8/rd 0/funct3 b/rs 0/imm12
+13/i 9/rd 0/funct3 0/rs 1c/imm12
+13/i 12/rd 0/funct3 1/rs 0/imm12
+# print_hex_word:loop:
+# shift
+33/r b/rd 5/funct3 8/rs1 9/rs2 0/funct7
+6f/j 1/rd 14/imm21
+
+# break if last shift
+63/b 0/funct3 9/rs1 0/rs2 c/imm13
+
+# subtract shift count, loop
+13/i 9/rd 0/funct3 9/rs -4/imm12
+6f/j 0/rd -10/imm21
+# print_hex_word:break:
+# return
+67/i 0/rd 0/funct3 12/rs 0/imm12
+
+# print_hex_dgt:
+# a1 = a1 & 0xf
+13/i b/rd 7/funct3 b/rs f/imm12
+# t1 = 0x40
+13/i 6/rd 0/funct3 0/rs 40/imm12
+
+# add 0x30 (ascii '0') / 0x61 (ascii 'a')
+13/i b/rd 0/funct3 b/rs 30/imm12
+63/b 4/funct3 b/rs1 6/rs2 8/imm13
+13/i b/rd 0/funct3 b/rs 27/imm12
+
+# print_hex_dgt:spin:
+# spin if FIFO is full (thr_emtpy = UART+5 & 0x20)
+3/i 7/rd 4/funct3 a/rs 5/imm12
+13/i 7/rd 7/funct3 7/rs 20/imm12
+63/b 0/funct3 7/rs1 0/rs2 -8/imm13
+
+# print char
+23/s 2/funct3 a/rs1 0/imm12 b/rs2
+
+# return
+67/i 0/rd 0/funct3 1/rs 0/imm12
+
+== data 0x80500000
+# E_MAGIC:
+# "Invalid DTB magic!\n\0"
+49/8 6e/8 76/8 61/8 6c/8 69/8 64/8 20/8 44/8 54/8 42/8 20/8 6d/8 61/8 67/8 69/8 63/8 21/8 a/8 0/8
+# S_TOTALSZ:
+54/8 6f/8 74/8 61/8 6c/8 20/8 53/8 69/8 7a/8 65/8 3a/8 20/8 0/8
+
diff --git a/examples/device_tree.valid b/examples/device_tree.valid
new file mode 100644
index 0000000..41deb4a
--- /dev/null
+++ b/examples/device_tree.valid
@@ -0,0 +1,152 @@
+== code 0x80400000
+main:
+# print device tree info.
+# OpenSBI calls us with a1 set to the start of the DTB
+# load 0x10000000 (UART0) into a0
+37/u a/rd 10000/imm20
+
+13/i 15/rd 0/funct3 b/rs 0/imm12
+
+# check magic == 0xd00dfeed
+37/u 6/rd edfe1dd0/imm20hi
+13/i 6/rd 0/funct3 6/rs edfe0dd0/imm12lo
+3/i 5/rd 2/funct3 15/rs 0/imm12
+63/b 1/funct3 5/rs1 6/rs2 err_magic/off13
+
+37/u b/rd S_TOTALSZ/imm20hi
+13/i b/rd 0/funct3 b/rs S_TOTALSZ/imm12lo
+6f/j 1/rd print/off21
+
+3/i b/rd 2/funct3 15/rs 4/imm12
+6f/j 1/rd bswapw/off21
+6f/j 1/rd print_hex_word/off21
+6f/j 1/rd printnl/off21
+
+exit:
+# system reset (via SBI extension SRST)
+# a7 = ext id, a6 = fid, a0 = 0, a1 = 0
+37/u 11/rd 53525/imm20
+13/i 11/rd 0/funct3 11/rs 354/imm12
+33/r 10/rd 0/funct3 0/rs1 0/rs2 0/funct7
+33/r a/rd 0/funct3 0/rs1 0/rs2 0/funct7
+33/r b/rd 0/funct3 0/rs1 0/rs2 0/funct7
+# ECALL
+73/i 0/rd 0/funct3 0/rs 0/imm12
+
+err_magic:
+37/u b/rd E_MAGIC/imm20hi
+13/i b/rd 0/funct3 b/rs E_MAGIC/imm12lo
+6f/j 1/rd print/off21
+6f/j 0/rd exit/off21
+
+bswapw:
+# byte-order-swap word in a1
+# srli a1, a0, 8
+# lui a2, 16
+# addi a2, a2, -256
+# and a1, a1, a2
+13/i 5/rd 5/funct3 b/rs 8/imm12
+37/u 6/rd 16/imm20
+13/i 6/rd 0/funct3 6/rs -100/imm12
+33/r 5/rd 7/funct3 5/rs1 6/rs2 0/funct7
+# srli a2, a0, 24
+# or a1, a1, a2
+13/i 6/rd 5/funct3 b/rs 18/imm12
+33/r 5/rd 6/funct3 5/rs1 6/rs2 0/funct7
+# slli a2, a0, 8
+# lui a3, 4080
+# and a2, a2, a3
+13/i 6/rd 1/funct3 b/rs 8/imm12
+37/u 7/rd ff0/imm20
+33/r 6/rd 7/funct3 6/rs1 7/rs2 0/funct7
+# slli a0, a0, 24
+# or a0, a0, a2
+# or a0, a0, a1
+13/i b/rd 1/funct3 b/rs 18/imm12
+33/r b/rd 6/funct3 b/rs1 6/rs2 0/funct7
+33/r b/rd 6/funct3 b/rs1 5/rs2 0/funct7
+# ret
+67/i 0/rd 0/funct3 1/rs 0/imm12
+
+printnl:
+13/i 6/rd 0/funct3 0/rs a/imm12
+printnl:spin:
+# spin if FIFO is full (thr_emtpy = UART+5 & 0x20)
+3/i 7/rd 4/funct3 a/rs 5/imm12
+13/i 7/rd 7/funct3 7/rs 20/imm12
+63/b 0/funct3 7/rs1 0/rs2 printnl:spin/off13
+# print char
+23/s 2/funct3 a/rs1 0/imm12 6/rs2
+# return
+67/i 0/rd 0/funct3 1/rs 0/imm12
+
+print:
+print:loop:
+# load unsigned byte at a1
+3/i 6/rd 4/funct3 b/rs 0/imm12
+# break loop if zero
+63/b 0/funct3 6/rs1 0/rs2 print:break/off13
+print:spin:
+# spin if FIFO is full (thr_emtpy = UART+5 & 0x20)
+3/i 7/rd 4/funct3 a/rs 5/imm12
+13/i 7/rd 7/funct3 7/rs 20/imm12
+63/b 0/funct3 7/rs1 0/rs2 print:spin/off13
+# print char
+23/s 2/funct3 a/rs1 0/imm12 6/rs2
+# increment a1
+13/i b/rd 0/funct3 b/rs 1/imm12
+# jump back up
+6f/j 0/rd print:loop/off21
+print:break:
+# return
+67/i 0/rd 0/funct3 1/rs 0/imm12
+
+print_hex_word:
+13/i 8/rd 0/funct3 b/rs 0/imm12
+13/i 9/rd 0/funct3 0/rs 1c/imm12
+13/i 12/rd 0/funct3 1/rs 0/imm12
+print_hex_word:loop:
+# shift
+33/r b/rd 5/funct3 8/rs1 9/rs2 0/funct7
+6f/j 1/rd print_hex_dgt/off21
+
+# break if last shift
+63/b 0/funct3 9/rs1 0/rs2 print_hex_word:break/off13
+
+# subtract shift count, loop
+13/i 9/rd 0/funct3 9/rs -4/imm12
+6f/j 0/rd print_hex_word:loop/off21
+print_hex_word:break:
+# return
+67/i 0/rd 0/funct3 12/rs 0/imm12
+
+print_hex_dgt:
+# a1 = a1 & 0xf
+13/i b/rd 7/funct3 b/rs f/imm12
+# t1 = 0x40
+13/i 6/rd 0/funct3 0/rs 40/imm12
+
+# add 0x30 (ascii '0') / 0x61 (ascii 'a')
+13/i b/rd 0/funct3 b/rs 30/imm12
+63/b 4/funct3 b/rs1 6/rs2 print_hex_dgt:spin/off13
+13/i b/rd 0/funct3 b/rs 27/imm12
+
+print_hex_dgt:spin:
+# spin if FIFO is full (thr_emtpy = UART+5 & 0x20)
+3/i 7/rd 4/funct3 a/rs 5/imm12
+13/i 7/rd 7/funct3 7/rs 20/imm12
+63/b 0/funct3 7/rs1 0/rs2 print_hex_dgt:spin/off13
+
+# print char
+23/s 2/funct3 a/rs1 0/imm12 b/rs2
+
+# return
+67/i 0/rd 0/funct3 1/rs 0/imm12
+
+== data 0x80500000
+E_MAGIC:
+# "Invalid DTB magic!\n\0"
+49/8 6e/8 76/8 61/8 6c/8 69/8 64/8 20/8 44/8 54/8 42/8 20/8 6d/8 61/8 67/8 69/8 63/8 21/8 0a/8 00/8
+S_TOTALSZ:
+54/8 6f/8 74/8 61/8 6c/8 20/8 53/8 69/8 7a/8 65/8 3a/8 20/8 00/8
+
diff --git a/examples/ex.elf b/examples/ex.elf
index b06a01f..0a911c0 100644
--- a/examples/ex.elf
+++ b/examples/ex.elf
Binary files differ
diff --git a/examples/ex.subv b/examples/ex.subv
index a65643e..0c24a98 100644
--- a/examples/ex.subv
+++ b/examples/ex.subv
@@ -1,16 +1,47 @@
== code 0x80400000
# repeatedly print "Hi\n"
main:
- # load 0x10000000 (UART0) into t0
- 37/lui 5/rd/t0 10000/imm20
- # store 0x48 (H) in UART0+0
+ 13/opi 5/rd/t0 0/subop/add 0/rs/x0 0/imm12
+
+ 37/lui 5/rd/t0 10/imm20
+ 13/opi 6/rd/t1 0/subop/add 0/rs/x0 aa/imm12
+ 23/store 2/width/word 5/rs/t0 0/off12 6/rs/t1
+
+ # load 0x20000 (UART) into t0
+ 37/lui 5/rd/t0 20/imm20
+ # set UART_BAUD (UART+0) to 1666 (0x682)
+ 13/opi 6/rd/t1 0/subop/add 0/rs/x0 682/imm12
+ 23/store 2/width/word 5/rs/t0 0/off12 6/rs/t1
+
+spin:a:
+ # spin if FIFO is full (UART+4 < 0)
+ 03/load 7/rd/t2 2/width/w 5/rs/t0 4/imm12
+ 13/opi 7/rd/t2 7/subop/and 7/rs/t2 1/imm12
+ 63/branch 0/subop/== 7/rs/t2 0/rs/x0 spin:a/off13
+
+ # store 0x48 (H) in UART+8
13/opi 0/subop/add 6/rd/t1 0/rs/x0 48/imm12
- 23/store 0/width/byte 5/rs/t0 0/off12 6/rs/t1
- # store 0x69 (i) in UART0+0
+ 23/store 2/width/word 5/rs/t0 8/off12 6/rs/t1
+
+spin:b:
+ # spin if FIFO is full (UART+4 < 0)
+ 03/load 7/rd/t2 2/width/w 5/rs/t0 4/imm12
+ 13/opi 7/rd/t2 7/subop/and 7/rs/t2 1/imm12
+ 63/branch 0/subop/== 7/rs/t2 0/rs/x0 spin:b/off13
+
+ # store 0x69 (i) in UART+8
13/opi 0/subop/add 6/rd/t1 0/rs/x0 69/imm12
- 23/store 0/width/byte 5/rs/t0 0/off12 6/rs/t1
- # store 0x0a (\n) in UART0+0
+ 23/store 2/width/word 5/rs/t0 8/off12 6/rs/t1
+
+spin:c:
+ # spin if FIFO is full (UART+4 < 0)
+ 03/load 7/rd/t2 2/width/w 5/rs/t0 4/imm12
+ 13/opi 7/rd/t2 7/subop/and 7/rs/t2 1/imm12
+ 63/branch 0/subop/== 7/rs/t2 0/rs/x0 spin:c/off13
+
+ # store 0x0a (\n) in UART+8
13/opi 0/subop/add 6/rd/t1 0/rs/x0 0a/imm12
- 23/store 0/width/byte 5/rs/t0 0/off12 6/rs/t1
+ 23/store 2/width/word 5/rs/t0 8/off12 6/rs/t1
+
# jump back up to the top
6f/jal 0/rd/x0 main/off21
diff --git a/examples/hello_world.subv b/examples/hello_world.subv
index f74bc64..25a1cba 100644
--- a/examples/hello_world.subv
+++ b/examples/hello_world.subv
@@ -1,4 +1,4 @@
-== code 0x80400000
+== code 0x0
# load mhartid CSR into t0, trap all but first Hart
# 73/system 5/rd/t0 2/funct3/csrrs 0/rs/x0 f14/csr/mhartid
# 63/branch 1/subop/!= 5/rs/t0 0/rs/x0 0/off13
@@ -13,6 +13,7 @@ main:
6f/jal 1/rd/ra print/off21
exit:
+ 6f/jal 0/rd/x0 main/off21
# system reset (via SBI extension SRST)
# a7 = ext id, a6 = fid, a0 = 0, a1 = 0
37/lui 11/rd/a7 53525/imm20
@@ -24,20 +25,20 @@ exit:
73/system 0/subop/priv 0/funct12/ecall
print:
- # load 0x10000000 (UART0) into t0
- 37/lui 5/rd/t0 10000/imm20
+ # load 0x20000 (UART0) into t0
+ 37/lui 5/rd/t0 20/imm20
print:loop:
# load unsigned byte at a0
03/load 6/rd/t1 4/width/bu a/rs/a0 0/imm12
# break loop if zero
63/branch 0/subop/== 6/rs/t1 0/rs/x0 print:break/off13
print:spin:
- # spin if FIFO is full (thr_emtpy = UART+5 & 0x20)
- 03/load 7/rd/t2 4/width/bu 5/rs/t0 5/imm12
- 13/opi 7/rd/t2 7/subop/and 7/rs/t2 20/imm12
+ # spin if FIFO is full (UART+4 & 1 == 0)
+ 03/load 7/rd/t2 2/width/w 5/rs/t0 4/imm12
+ 13/opi 7/rd/t2 7/subop/and 7/rs/t2 1/imm12
63/branch 0/subop/== 7/rs/t2 0/rs/x0 print:spin/off13
# print char
- 23/store 2/width/w 5/rs/t0 0/off12 6/rs/t1
+ 23/store 2/width/w 5/rs/t0 8/off12 6/rs/t1
# increment a0
13/opi a/rd/a0 0/subop/add a/rs/a0 1/imm12
# jump back up
@@ -46,7 +47,7 @@ print:break:
# return
67/jalr 0/rd/x0 0/subop 1/rs/ra 0/off12
-== data 0x80500000
+== data 0x100
Message:
# "Hello World!\n\0"
48/8 65/8 6c/8 6c/8 6f/8 20/8 77/8 6f/8 72/8 6c/8 64/8 21/8 0a/8 00/8
diff --git a/subv.py b/subv.py
index 8cee596..9eccbea 100644
--- a/subv.py
+++ b/subv.py
@@ -1,7 +1,7 @@
import re
import bits
-white = re.compile(r"[ \t\.\n]+")
+white = re.compile(r"[ \t\n]+")
hex = re.compile(r"^\-?[0-9a-f]+$")
num = re.compile(r"^\d+$")
ref_re = re.compile(r"^([^\[+-]+)(?:([+-]\d+))?$")
@@ -67,6 +67,8 @@ def parse_segment(line):
('code', 32768)
>>> parse_segment('== text')
('text',)
+ >>> parse_segment('== .text 0x1234')
+ ('.text', 4660)
"""
parts = white.split(line)
if len(parts) == 3:
@@ -146,7 +148,7 @@ def classify(line):
'empty'
>>> classify('== code')
'segment'
- >>> classify('== text 0x1000')
+ >>> classify('== .text 0x1000')
'segment'
>>> classify('some_label:')
'label'
@@ -168,7 +170,9 @@ def classify(line):
def parse(line):
- """clean, classify and parse lines."""
+ """clean, classify and parse lines.
+ """
+
raw = line.strip()
split = raw.split("#", 1)
if len(split) == 1: