Skip to content

Commit 84b3e3c

Browse files
committedOct 10, 2014
convert the latex documention to rst
This will ease editing the documentation. For now only a HTML output is generated. Signed-off-by: Michael Walle <michael@walle.cc>
1 parent e9ea4b3 commit 84b3e3c

File tree

3 files changed

+484
-472
lines changed

3 files changed

+484
-472
lines changed
 

‎doc/Makefile

+5-9
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
1-
TEX=mmu.tex
1+
DOCS=mmu.html
22

33
RM ?= rm -f
44

5-
PDF=$(TEX:.tex=.pdf)
6-
AUX=$(TEX:.tex=.aux)
7-
LOG=$(TEX:.tex=.log)
5+
all: $(DOCS)
86

9-
all: $(PDF)
10-
11-
%.pdf: %.tex
12-
texi2pdf $<
7+
%.html: %.rst
8+
rst2html $< >$@
139

1410
clean:
15-
$(RM) $(PDF) $(LOG) $(AUX)
11+
$(RM) $(DOCS)
1612

1713
.PHONY: clean

‎doc/mmu.rst

+479
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,479 @@
1+
2+
LatticeMico32 Memory Managerment Unit
3+
=====================================
4+
5+
:Author: Yann Sionneau
6+
:Contact: yann.sionneau@gmail.com
7+
:Version: 1.0
8+
:Date: June 2013
9+
:Copyright: Permission is granted to copy, distribute and/or modify this
10+
document under the terms of the BSD License.
11+
12+
13+
Overview
14+
--------
15+
16+
This document describes the LatticeMico32 MMU (Memory Management Unit)
17+
features and how it can be configured.
18+
19+
This MMU is not part of the original LatticeMico32 CPU, it has been added
20+
by Yann Sionneau with the help of the Milkymist community in general and
21+
Michael Walle in particular.
22+
23+
The LM32 MMU has been designed with "simplicity" in head, KISS (Keep It
24+
Simple Stupid) is the motto.
25+
26+
Only the minimum has been implemented to have the minimalistic features
27+
which would allow a modern Operating System like Linux or \*BSD to run,
28+
providing virtual memory and memory protection.
29+
30+
The Caches are designed to be VIPT (Virtually Indexed Physically Tagged) to
31+
allow the TLB lookup to take place in parallel of the cache lookup so that
32+
we don't need to stale the pipeline.
33+
34+
35+
Features
36+
--------
37+
38+
* 1024 entries ITLB (Instruction Translation Lookaside Buffer)
39+
* 1024 entries DTLB (Data Translation Lookaside Buffer)
40+
* CPU exceptions generated upon
41+
42+
* ITLB miss
43+
* DTLB miss
44+
* DTLB page fault (writing to a read-only page)
45+
46+
* I/D TLB lookup in parallel of the I/D Cache lookup to avoid lookup penalties
47+
* 4 kB pages
48+
49+
As you can see, it is quite minimalistic, here is a list of what's not
50+
featured by this MMU:
51+
52+
* No hardware page tree walker
53+
* No dirty or present bit
54+
* No ASID (Address Space Identifier)
55+
* No lockable TLB entries
56+
* Only 1 page size supported: 4 kB
57+
58+
59+
TLB Layout
60+
----------
61+
62+
Let's name our 32 bits virtual address "vaddr".
63+
64+
Let's name our 32 bits physical address "paddr".
65+
66+
Let's say vaddr[0] is the Lowest Significant Bit and vaddr[31] the Most
67+
Significant Bit.
68+
69+
Let's say vaddr[11:0] is the part of vaddr represented by its 12 Lowest
70+
Significant Bits.
71+
72+
Deep inside, the TLB is a **Direct-mapped**, **VIVT** (Virtually Indexed
73+
Virtually Tagged) Cache.
74+
75+
When the LM32 core is synthetized with MMU support, the CPU pipeline Data
76+
and Instruction Caches turn into **VIPT** (Virtually Indexed Physically
77+
Tagged) Caches.
78+
79+
The TLB is indexed by vaddr[21:12]: The bottom 10 LSB of the virtual PFN
80+
(Page Frame Number).
81+
82+
A TLB entry holds: Physical PFN, Physical Tag, Cache inhibit flag (for
83+
DTLB), Read-only flag (for DTLB), Valid entry tag
84+
85+
More precisely:
86+
87+
* A valid DTLB entry: paddr[31:12], vaddr[31:22], paddr[2], paddr[1], 1
88+
* An invalid DTLB entry: paddr[31:12], vaddr[21:22], paddr[2], paddr[1], 0
89+
* A valid ITLB entry: paddr[31:12], vaddr[31:22], 1
90+
* An invalid ITLB entry: paddr[31:12], vaddr[31:22], 0
91+
92+
The meaning of paddr[2] and paddr[1] will be explained later on in the
93+
section which explains how to program the MMU using LM32 assembly
94+
instructions.
95+
96+
97+
Interact with the TLB
98+
---------------------
99+
100+
In order to interact with the TLB, three CSR (Control and Status Registers)
101+
have been added to the LM32 CPU:
102+
103+
+-------------+--------------------------------------------------+--------+
104+
| CSR | Description | R/W |
105+
+=============+==================================================+========+
106+
| TLBVADDR | You can write the virtual pfn of the entry you | R/W |
107+
| | want to update or invalidate or cause a TLB | |
108+
| | flush. You can read the virtual pfn causing a | |
109+
| | TLB miss or fault. | |
110+
+-------------+--------------------------------------------------+--------+
111+
| TLBPADDR | Your can write the physical pfn of the entry you | W only |
112+
| | want to update. | |
113+
+-------------+--------------------------------------------------+--------+
114+
| TLBBADVADDR | You can read the virtual address which caused | R only |
115+
| | the TLB exception. | |
116+
+-------------+--------------------------------------------------+--------+
117+
118+
* TLBVADDR: holds a virtual address
119+
* TLBPADDR: holds a physical address
120+
121+
A CSR register can be written to like this:
122+
123+
The following code writes the content of the R1 register to TLBVADDR CSR::
124+
125+
wcsr TLBVADDR, r1
126+
127+
A CSR register can be read from like this:
128+
129+
The following code writes the content of TLBPADDR CSR to the R1 register::
130+
131+
rcsr r1, TLBPADDR
132+
133+
134+
Add or Update a TLB entry
135+
~~~~~~~~~~~~~~~~~~~~~~~~~
136+
137+
First, make sure vaddr[2:0] == "000" (or 3'b0 in verilog) as those 3 bits
138+
will be used for other TLB operations.
139+
140+
Then, write the virtual address to the TLBVADDR CSR.
141+
142+
Then you need to do a logical "OR" operation on the physical address to set
143+
paddr[2:0] according to your needs:
144+
145+
* paddr[2] set to 1 means the page won't be cached by LM32 Data Cache
146+
(only for Data Cache / DTLB)
147+
* paddr[1] set to 1 means the Page is Read-only (only valid for DTLB)
148+
* paddr[0] set to 1 means you want to update DTLB, use 0 for ITLB
149+
150+
Then, you need to write the OR'ed physical address to the TLBPADDR CSR.
151+
152+
The TLB entry update will be triggered by the write to TLBPADDR CSR.
153+
154+
Code samples::
155+
156+
#define PAGE_SIZE (1 << 12)
157+
#define PAGE_MASK (PAGE_SIZE - 1)
158+
159+
void update_dtlb_entry(unsigned int vaddr, unsigned int paddr,
160+
bool read-only, bool not_cached)
161+
{
162+
paddr &= ~PAGE_MASK; /* Make sure page offset is zeroed */
163+
vaddr &= ~PAGE_MASK; /* Make sure page offset is zeroed */
164+
paddr |= 1; /* This means we are addressing DTLB */
165+
166+
if (read-only)
167+
paddr |= 2;
168+
169+
if (not_cached)
170+
paddr |= 4;
171+
172+
asm volatile("wcsr TLBVADDR, %0" :: "r"(vaddr) : );
173+
asm volatile("wcsr TLBPADDR, %0" :: "r"(paddr) : );
174+
}
175+
176+
void update_itlb_entry(unsigned int vaddr, unsigned int paddr)
177+
{
178+
paddr &= ~PAGE_MASK; /* Make sure page offset is zeroed */
179+
vaddr &= ~PAGE_MASK; /* Make sure page offset is zeroed */
180+
/* We don't set paddr[0] which means we are addressing ITLB */
181+
182+
asm volatile("wcsr TLBVADDR, %0" :: "r"(vaddr) : );
183+
asm volatile("wcsr TLBPADDR, %0" :: "r"(paddr) : );
184+
}
185+
186+
187+
Invalidate a TLB entry or flush the entire TLB
188+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
189+
190+
First, you need to do a logical "OR" operation on the virtual address to
191+
set vaddr[2:0] according to your needs:
192+
193+
* vaddr[2] set to 1 will trigger a flush of the entire selected TLB
194+
* vaddr[1] set to 1 will trigger the invalidation of the entry indexed by
195+
vaddr[21:12] inside the selected TLB
196+
* vaddr[0] set to 1 means you want to operate on DTLB, use 0 for ITLB
197+
198+
The action is triggered upon the write of the OR'ed virtual address to the
199+
TLBVADDR CSR.
200+
201+
Code samples::
202+
203+
#define PAGE_SIZE (1 << 12)
204+
#define PAGE_MASK (PAGE_SIZE - 1)
205+
206+
void invalidate_dtlb_entry(unsigned int vaddr)
207+
{
208+
vaddr &= ~PAGE_MASK; /* Make sure page offset is zeroed */
209+
/*
210+
* 1 because we are addressing DTLB
211+
* 2 because we want to invalidate a specific line
212+
*/
213+
vaddr |= 1 | 2;
214+
215+
asm volatile("wcsr TLBVADDR, %0" :: "r"(vaddr) : );
216+
}
217+
218+
void invalidate_itlb_entry(unsigned int vaddr)
219+
{
220+
vaddr &= ~PAGE_MASK; /* Make sure page offset is zeroed */
221+
vaddr |= 2; /* 2 because we want to invalidate a specific line */
222+
223+
asm volatile("wcsr TLBVADDR, %0" :: "r"(vaddr) : );
224+
}
225+
226+
void flush_dtlb(void)
227+
{
228+
unsigned int cmd = 1 | 4;
229+
asm volatile("wcsr TLBVADDR, %0" :: "r"(cmd) : );
230+
}
231+
232+
void flush_itlb(void)
233+
{
234+
unsigned int cmd = 4;
235+
asm volatile("wcsr TLBVADDR, %0" :: "r"(cmd) : );
236+
}
237+
238+
239+
A sum up of TLB actions
240+
~~~~~~~~~~~~~~~~~~~~~~~
241+
242+
To summarize all possible TLB actions:
243+
244+
* Writing to TLBPADDR triggers the update of a TLB entry according to the
245+
content of TLBVADDR and TLBPADDR
246+
* Writing to TLBVADDR either prepares for updating a TLB entry if it is
247+
followed by a write operation to TLBPADDR or immediately triggers an
248+
action determined by bits vaddr[2:0] written to TLBVADDR. In the latter
249+
case, the action is performed on the TLB entry indexed by vaddr[21:12].
250+
251+
Possible actions triggered by writing to TLBVADDR:
252+
253+
+------------+------------------------------------------------------------+
254+
| vaddr[2:0] | action |
255+
+============+============================================================+
256+
| 000 | No Operation, used for updating TLB entry by writting to |
257+
| | TLBPADDR |
258+
+------------+------------------------------------------------------------+
259+
| 011 | Invalidate DTLB entry indexed by vaddr[21:12] |
260+
+------------+------------------------------------------------------------+
261+
| 010 | Invalidate ITLB entry indexed by vaddr[21:12] |
262+
+------------+------------------------------------------------------------+
263+
| 101 | Flush DTLB |
264+
+------------+------------------------------------------------------------+
265+
| 100 | Flush ITLB |
266+
+------------+------------------------------------------------------------+
267+
| 11x | Not deterministic, do not use untill it's defined by a |
268+
| | future MMU revision |
269+
+------------+------------------------------------------------------------+
270+
271+
272+
Interact with the MMU
273+
---------------------
274+
275+
In order to interact with the MMU, a new CSR (Control and Status Register)
276+
has been added: PSW (Processor Status Word)
277+
278+
+-------+--------+--------------------------------------------------------+
279+
| Bits | Name | Description |
280+
+=======+========+========================================================+
281+
| 31:12 | | *unused* |
282+
+-------+--------+--------------------------------------------------------+
283+
| 11 | BUSR | Breakpoint backup of USR |
284+
+-------+--------+--------------------------------------------------------+
285+
| 10 | EUSR | Exception backup of USR |
286+
+-------+--------+--------------------------------------------------------+
287+
| 9 | USR | User mode bit |
288+
+-------+--------+--------------------------------------------------------+
289+
| 8 | BDTLBE | Breakpoint backup of DTLBE |
290+
+-------+--------+--------------------------------------------------------+
291+
| 7 | EDTLBE | Exception backup of DTLBE |
292+
+-------+--------+--------------------------------------------------------+
293+
| 6 | DTLBE | DTLB enabled |
294+
+-------+--------+--------------------------------------------------------+
295+
| 5 | BITLBE | Breakpoint backup of ITLBE |
296+
+-------+--------+--------------------------------------------------------+
297+
| 4 | EITLBE | Exception backup of ITLBE |
298+
+-------+--------+--------------------------------------------------------+
299+
| 3 | ITLBE | ITLB enabled |
300+
+-------+--------+--------------------------------------------------------+
301+
| 2 | IE.BIE | See note below |
302+
+-------+--------+ |
303+
| 1 | IE.EIE | |
304+
+-------+--------+ |
305+
| 0 | IE.IE | |
306+
+-------+--------+--------------------------------------------------------+
307+
308+
.. Note::
309+
310+
PSW[2:0] is a real mirror of IE[2:0] as described in the LatticeMico32
311+
Processor Reference Manual p. 10 Table 5 "Fields of the IE CSR". In any
312+
condition: PSW[2:0] == IE[2:0]. IE CSR is mirrored in the lower bits of
313+
PSW CSR for compatibility reasons. Old programs (ignorant of the MMU)
314+
will keep using IE CSR, newer programs can use PSW to deal with MMU and
315+
interrupts.
316+
317+
318+
Activate the MMU
319+
~~~~~~~~~~~~~~~~
320+
321+
Activating the MMU is done by activating each TLB by writing 1 into
322+
PSW[ITLBE] and PSW[DTLBE]::
323+
324+
void enable_mmu(void)
325+
{
326+
asm volatile("rcsr r1, PSW\n\t"
327+
"ori r1, r1, 72\n\t"
328+
"wcsr PSW, r1" ::: "r1");
329+
}
330+
331+
332+
Deactivate the MMU
333+
~~~~~~~~~~~~~~~~~~
334+
335+
Deactivating the MMU is done by deactivating each TLB by writing 0 into
336+
PSW[ITLBE] and PSW[DTLBE]::
337+
338+
void disable_mmu(void)
339+
{
340+
unsigned int mask = ~(72);
341+
asm volatile("rcsr r1, PSW\n\t"
342+
"and r1, r1, %0\n\t"
343+
"wcsr PSW, r1" :: "r"(mask) : "r1");
344+
}
345+
346+
347+
TLB lookups
348+
-----------
349+
350+
This section explains in details how the TLB lookup takes place: what
351+
happens in which condition.
352+
353+
If the TLBs are disabled, nothing special happens, LM32 will behave as if
354+
it has been synthetized without MMU support (except for the presence of
355+
PSW, TLBVADDR and TLBPADDR).
356+
357+
If DTLB is enabled:
358+
359+
In parallel of the Data Cache lookup, the DTLB lookup happens.
360+
361+
DTLB is indexed by vaddr[21:11].
362+
363+
If the DTLB entry is invalid (i.e. invalid bit is set), then the DTLB
364+
generates a DTLB miss exception.
365+
366+
If the DTLB entry is valid, the DTLB compares vaddr[31:22] with the DTLB
367+
entry tag, if this comparison fails: the DTLB generates a DTLB miss
368+
exception as well.
369+
370+
If the DTLB entry is valid and the vaddr[31:22] matches the DTLB entry tag:
371+
372+
* Then if the memory access was a READ (lb, lbu, lh, lhu, lw)
373+
374+
* the Data Cache compares the tag of its selected line with the
375+
paddr[31:12] extracted from the DTLB to check if we Hit or Miss the
376+
Data Cache
377+
* Then the usual Cache refill happens (using the physical address) in
378+
case of a cache miss
379+
* Then if the memory access was a WRITE (sb, sh, sw)
380+
381+
* The read-only bit flag contained in the DTLB entry is checked
382+
* If it is set: it triggers a DTLB fault CPU exception
383+
* If it's not set: The Data Cache does the same tag comparison as with
384+
the READ operation to check for Cache Hit/Miss
385+
386+
All these behaviours are summed up in the following table:
387+
388+
+------------+-----+------------------------------------------------------+
389+
| Exception | EID | Condition |
390+
+------------+-----+------------------------------------------------------+
391+
| ITLB miss | 8 | If **any** of these conditions holds: |
392+
| | | |
393+
| | | * ITLB entry is invalid |
394+
| | | * ITLB entry tag does not match vaddr[31:22] |
395+
+------------+-----+------------------------------------------------------+
396+
| DTLB miss | 9 | If **any** of these conditions holds: |
397+
| | | |
398+
| | | * DTLB entry is invalid |
399+
| | | * DTLB entry tag does not match vaddr[31:22] |
400+
+------------+-----+------------------------------------------------------+
401+
| DTLB fault | 10 | If **all** of these conditions holds: |
402+
| | | |
403+
| | | * DTLB entry is valid |
404+
| | | * the tag entry matches vaddr[31:22] |
405+
| | | * the read-only bit is set |
406+
| | | * the CPU is doing a memory store |
407+
+------------+-----+------------------------------------------------------+
408+
| Privilege | 11 | If PSW[USR] == 1 and one of these instructions is |
409+
| | | exeucted: |
410+
| | | |
411+
| | | * iret |
412+
| | | * bret |
413+
| | | * wcsr |
414+
+------------+-----+------------------------------------------------------+
415+
416+
417+
CSR registers special behaviours
418+
--------------------------------
419+
420+
Upon any exception, PSW CSR is modified automatically by the CPU pipeline
421+
itself:
422+
423+
* PSW[ITLBE] is saved in PSW[EITLBE] and the former is cleared
424+
* PSW[DTLBE] is saved in PSW[EDTLBE] and the former is cleared
425+
* PSW[USR] is saved in PSW[EUSR] and the former is cleared
426+
* TLBVADDR is pre-charged with the virtual PFN (page frame number) which
427+
caused an exception (in case of TLB miss or fault only)
428+
429+
* TLBVADDR[0] is set to 1 when then exception is caused by DTLB, else it
430+
is clear
431+
* In case of DTLB miss or fault, TLBVADDR[31:12] is pre-charged the
432+
virtual PFN whose load or store operation caused the exception
433+
* In case of ITLB miss, TLBVADDR[31:12] is pre-charged with the virtual
434+
PFN of the instruction whose fetch caused the exception
435+
* This mechanism allows for faster TLB miss handling because TLBVADDR is
436+
already pre-charged with the right value
437+
* Since TLBVADDR is pre-charged with the virtual PFN: page offset bits
438+
(TLBVADDR[11:1]) are not set
439+
440+
* TLBBADVADDR\ :sup:`\*\*` is written with a virtual address when an
441+
exception is caused by a TLB miss
442+
443+
* In case of ITLB miss, TLBBADVADDR[31:2] contains the PC address whose
444+
fetch triggered the ITLB miss exception. Instructions being 32 bits
445+
aligned, PC[1:0] is always 00.
446+
* In case of DTLB miss or fault, TLBBADVADDR[31:0] contains the virtual
447+
address whose load or store operation caused the exception
448+
* Unlike TLBVADDR, TLBBADVADDR page offset bits are set according to
449+
what caused the exception
450+
451+
(\*) In LM32 pipeline, exception happens in the e\ **X**\ ecute stage, even
452+
though they may be triggered in the **F**\ etch or **M**\ emory stage for
453+
example. Load and Store instructions therefore stall the pipeline for 1
454+
cycle during the e\ **X**\ ecute stage if the DTLB is activated.
455+
456+
(\*\*) TLBBADVADDR is the same CSR ID as TLBPADDR. The former is read-only
457+
and the latter is write-only.
458+
459+
Upon any breakpoint hit, PSW CSR is also modified by the CPU pipeline:
460+
461+
* PSW[ITLBE] is saved in PSW[BITLBE] and the former is cleared
462+
* PSW[DTLBE] is saved in PSW[BDTLBE] and the former is cleared
463+
* PSW[USR] is saved in PSW[BUSR] and the former is cleared
464+
465+
This means MMU is **turned off** upon CPU exception or breakpoint hit.
466+
467+
Upon return from exception (**iret** instruction), PSW CSR is also modified
468+
by the CPU pipeline:
469+
470+
* PSW[ITLBE] is restored using the value from PSW[EITLBE]
471+
* PSW[DTLBE] is restored using the value from PSW[EDTLBE]
472+
* PSW[USR] is restored using the value from PSW[EUSR]
473+
474+
Upon return from breakpoint (\textbf{bret} instruction), PSW CSR is also
475+
modified by the CPU pipeline:
476+
477+
* PSW[ITLBE] is restored using the value from PSW[BITLBE]
478+
* PSW[DTLBE] is restored using the value from PSW[BDTLBE]
479+
* PSW[USR] is restored using the value from PSW[BUSR]

‎doc/mmu.tex

-463
This file was deleted.

0 commit comments

Comments
 (0)
Please sign in to comment.