Skip to content

Commit dc5af21

Browse files
committed
Move reset vector back to 0x0, add MLOGSYS instruction to initialize icache instead of doing it automatically at boot
1 parent fde15bb commit dc5af21

File tree

7 files changed

+65
-54
lines changed

7 files changed

+65
-54
lines changed

README.md

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ RISC-V processor in Mindustry logic. Requires Mindustry build 149+.
66

77
## Architecture
88

9-
Physical memory consists of three sections. Two are directly accessible by code: ROM (rx) and RAM (rwx). The third section is an instruction cache which is 4x less dense than main memory. The instruction cache is updated at reset, and whenever an instruction writes to RAM that is covered by the icache. If executing from memory not covered by the icache, the processor manually fetches and decodes the instruction from main memory.
9+
Physical memory consists of three sections. Two are directly accessible by code: ROM (rx) and RAM (rwx). The third section is an instruction cache which is 4x less dense than main memory.
1010

11-
Code begins executing at address `0x4`. Address `0x0` must contain the size of the `.text` section (ie. `__etext`) to tell the processor how much data to decode from ROM. If this value is `0`, no ROM data will be decoded.
11+
The instruction cache should be initialized at boot using the MLOGSYS instruction. It is also updated whenever an instruction writes to RAM that is covered by the icache. If executing from memory not covered by the icache, the processor manually fetches and decodes the instruction from main memory.
12+
13+
Code begins executing at address `0x00000000` (ie. the start of ROM).
1214

1315
The main CPU code is generated from `src/main.mlog.jinja` using a custom Jinja-based preprocessor (`python/src/mlogv32/preprocessor`).
1416

@@ -60,15 +62,16 @@ This non-standard extension adds instructions to control the mlogv32 processor's
6062

6163
The MLOG instructions are encoded with an I-type instruction format using the _custom-0_ opcode. The zero-extended immediate is used as a minor opcode (funct12) for implementation reasons.
6264

63-
The MLOGSYS instruction is used for simple system controls, including halt, `printchar`, `printflush`, `drawflush`, and sortKB/kbconv integration.
65+
The MLOGSYS instruction is used for simple system controls, including halt, `printchar`, `printflush`, `drawflush`, sortKB/kbconv integration, and icache initialization.
6466

65-
| funct12 | rd | rs1 | name |
66-
| ------- | ----------------------- | ------- | -------------------------- |
67-
| 0 | `00000` | `00000` | Halt |
68-
| 1 | `00000` | char | `printchar` |
69-
| 2 | `00000` | `00000` | `printflush` |
70-
| 3 | `00000` | `00000` | `drawflush` |
71-
| 4 | char (0 if no new data) | `00000` | Read next char from sortKB |
67+
| funct12 | rd | rs1 | name |
68+
| ------- | ----------------------- | --------- | -------------------------- |
69+
| 0 | `00000` | `00000` | Halt |
70+
| 1 | `00000` | char | `printchar` |
71+
| 2 | `00000` | `00000` | `printflush` |
72+
| 3 | `00000` | `00000` | `drawflush` |
73+
| 4 | char (0 if no new data) | `00000` | Read next char from sortKB |
74+
| 5 | `00000` | \_\_etext | Decode ROM .text section |
7275

7376
The MLOGDRAW instruction is used for drawing graphics using the Mlog `draw` instruction. Arguments are passed to this instruction using registers a0 to a5 as necessary, and any return value is placed in _rd_. If _rd_ is specified as `00000` in the below table, no value will be written to `rd` in any case.
7477

coremark/mlogv32/entry.s

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
.global _start
44
_start:
5+
# initialize icache
6+
la t0, __etext
7+
.insn i CUSTOM_0, 0, zero, t0, 5
8+
59
# reset mtime/mcycle/minstret
610
li t0, 0xf0000000 # mtime
711
sw zero, 4(t0)

riscof/mlogv32/env/model_test.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
#define RVMODEL_HALT \
1111
.insn i CUSTOM_0, 0, zero, zero, 0;
1212

13+
// initialize icache, .data, and .bss
1314
#define RVMODEL_BOOT \
1415
.option norelax; \
15-
.word __etext; \
16+
la t0, __etext; \
17+
.insn i CUSTOM_0, 0, zero, t0, 5; \
1618
la t0, __sidata; \
1719
la t1, __sdata; \
1820
la t2, __edata; \
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
reset:
2-
address: 0x4
2+
address: 0x0
33
nmi:
44
label: nmi_vector # we don't have an nmi vector, but riscof gets mad if this is removed

rust/mlogv32/link.x

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ SECTIONS {
3434
.text : {
3535
__stext = .;
3636

37-
LONG(__etext);
38-
3937
KEEP(*(.text.start));
4038
*(.text.reset);
4139
*(.text .text.*);

rust/mlogv32/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,13 @@ pub mod prelude;
2525
#[global_allocator]
2626
static HEAP: Heap = Heap::empty();
2727

28-
// init global/stack/frame pointers
28+
// init icache and global/stack/frame pointers
2929
#[rustfmt::skip]
3030
global_asm!("
3131
.section .text.start
32+
la t0, __etext
33+
.insn i CUSTOM_0, 0, zero, t0, 5
34+
3235
la gp, __global_pointer$
3336
3437
la t1, _stack_start

src/main.mlog.jinja

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -58,44 +58,9 @@ reset__find_lookup_start:
5858

5959
set LOOKUP_START i
6060

61-
# read __etext from address 0, or default to ROM_SIZE if __etext is 0
62-
set address 0
63-
op add ret @counter 1
64-
jump load_rom_word_unchecked always
65-
set __etext result
66-
67-
jump reset__valid_etext lessThanEq __etext ROM_SIZE
68-
print "Invalid __etext found at address 0x0, must be <={0}"
69-
format ROM_SIZE
70-
jump halt always
71-
reset__valid_etext:
72-
73-
# decode .text
74-
set STATE "decoding"
75-
set decode_address 4
76-
set decode_var null
77-
78-
reset__decode:
79-
set address decode_address
80-
op add ret @counter 1
81-
jump load_rom_word_unchecked always
82-
set instruction result
83-
84-
op add decode_ret @counter 1
85-
jump decode always
86-
87-
op add decode_address decode_address 4
88-
jump reset__decode lessThan decode_address __etext
89-
90-
set STATE "running"
91-
9261
# clear LR/SC reservation set
9362
set reservation_set null
9463

95-
# start executing code at address 4 (address 0 is __etext)
96-
set pc 4
97-
set icache_var null
98-
9964
# read initial CSR values
10065
read mtime {{CSRS}} "{{ 'time'|csr }}"
10166
read mtimeh {{CSRS}} "{{ 'timeh'|csr }}"
@@ -104,6 +69,12 @@ reset__decode:
10469
read minstret {{CSRS}} "{{ 'minstret'|csr }}"
10570
read minstreth {{CSRS}} "{{ 'minstreth'|csr }}"
10671

72+
# start executing code at address 0
73+
set pc 0
74+
set icache_var null
75+
set __etext 0
76+
set STATE "running"
77+
10778
# schedule time update
10879
set last_time_update @time
10980
set last_cycle_update @tick
@@ -314,7 +285,6 @@ end_instruction_preserve_instret:
314285
# enable the reset switch, wait until it's disabled, then reset the processor
315286
# this must stay directly after end_instruction
316287
halt:
317-
printflush {{ERROR_OUTPUT}}
318288
control enabled {{RESET_SWITCH}} true
319289
jump reset always
320290

@@ -327,6 +297,7 @@ illegal_instruction:
327297
trap:
328298
print "Unhandled trap: "
329299
print mcause
300+
printflush {{ERROR_OUTPUT}}
330301
jump halt always
331302

332303
# helper functions
@@ -1712,8 +1683,8 @@ read_modify_write_csr__minstreth:
17121683
jump end_instruction_with_result always
17131684

17141685
MLOGSYS:
1715-
# I-type: arg1=rs1, arg2=imm, arg3=rd
1716-
jump illegal_instruction greaterThanEq arg2 5
1686+
# I-type: arg1=rs1, arg2=funct12, arg3=rd
1687+
jump illegal_instruction greaterThan arg2 5
17171688

17181689
op mul jump arg2 2
17191690
op add @counter @counter jump
@@ -1735,8 +1706,38 @@ MLOGSYS:
17351706
jump end_instruction always
17361707

17371708
# read sortKB
1709+
jump MLOGSYS__read_sortKB always
1710+
stop
1711+
1712+
# initialize icache
17381713
# NOTE: if we add more instructions to MLOGSYS, this needs to move to its own label
17391714

1715+
# TODO: is this the right trap to use here?
1716+
jump illegal_instruction greaterThan rs1 ROM_SIZE
1717+
1718+
set __etext rs1
1719+
1720+
# decode .text
1721+
set STATE "decoding"
1722+
set decode_address 0
1723+
set decode_var null
1724+
1725+
MLOGSYS__init_icache__loop:
1726+
set address decode_address
1727+
op add ret @counter 1
1728+
jump load_rom_word_unchecked always
1729+
set instruction result
1730+
1731+
op add decode_ret @counter 1
1732+
jump decode always
1733+
1734+
op add decode_address decode_address 4
1735+
jump MLOGSYS__init_icache__loop lessThan decode_address __etext
1736+
1737+
set STATE "running"
1738+
jump end_instruction always
1739+
1740+
MLOGSYS__read_sortKB:
17401741
# check the current ptr and return 0 if we've already reached it
17411742
# NOTE: this will fail if the user has typed 63 characters since we last checked
17421743
set result 0
@@ -1754,7 +1755,7 @@ MLOGSYS:
17541755

17551756
MLOGDRAW:
17561757
# I-type: arg1=rs1, arg2=imm, arg3=rd
1757-
jump illegal_instruction greaterThanEq arg2 16
1758+
jump illegal_instruction greaterThan arg2 15
17581759

17591760
read a0 {{REGISTERS}} 10
17601761
read a1 {{REGISTERS}} 11

0 commit comments

Comments
 (0)