Hi all,

this should be a short summary what we discussed on IRC.

The following MMU operations are considered for now:
 - TLB UPDATE
 - TLB INVALIDATE (one entry)
 - TLB FLUSH (invalidate all entries for the given TLB)
These operations work either on the ITLB or the DTLB.

To communicate these opertions to the MMU two new CSRs are introduced:
  TLBVADDR and
  TLBPADDR.

Additionally, one new processor status register PSW (processor status word)
is addded, which contains the bits IE, ITLB, DTLB and USR. All bits have an 
Exxx and Bxxx equivalent (eg. there are ITLB, EITLB and BITLB bits), which 
follow the IE semantics (see LM32 reference manual). IE, EIE and BIE are 
shadowed from the IE register. Therefore, legacy programs can still use the IE 
register, while new MMU aware programs use the PSW register.


TLB operations

Because TLB UPDATE is the only operation where a physical address is needed. 
Writing to TLBPADDR implicitly issues an TLB UPDATE (of course TLBVADDR have 
to be set before).

To choose between ITLB and DTLB, the lowest bit of TLBVADDR is used.
Any other operation are encoded into the free bits in TLBVADDR. Thus this 
operations can be performed atomically, except for the UPDATE, which should 
run from the TLB miss handler with MMU turned off (or the user must take 
special care to avoid any exception, eg. turn off interrupts, make sure there 
is no ITLB miss [don't cross page boundaries] and no DTLB miss [no load 
between setting VADDR and PADDR]).

The same TLB miss exception vector is used for both ITLB and DTLB. On a TLB 
miss exception TLBVADDR is preloaded with the correct TLB operation (that is 
either ITLB_NOP or DTLB_NOP, see below) and the virtual address there is no 
mapping for.

There may be other exception vectors for page permission fault or user mode 
exceptions.

The ITLB and DTLB bits are cleared when an exception occurs and saved to 
EITLB/BITLB rsp. EDTLB/BDTLB.


Kernel/User mode

In kernel mode all CPU operations are unrestricted. In user mode (USR bit is 
set) writing CSRs, reading (some) CSRs are prohibited. Exceptions clears the 
USR bit and saves the old state in EUSR or BUSR. Thus the only way to return 
to kernel mode is via scall opcode, interrupt or any other exception.

The following is a proposal for the CSR ids and its bits:

enum {
 ...
    CSR_PSW  = 0x1d,
    CSR_TLBVADDR  = 0x1e,
    CSR_TLBPADDR  = 0x1f,
};

enum {
    PSW_IE    = (1<<0),
    PSW_EIE   = (1<<1),
    PSW_BIE   = (1<<2),
    PSW_ITLB  = (1<<4),
    PSW_EITLB = (1<<5),
    PSW_BITLB = (1<<6),
    PSW_DTLB  = (1<<7),
    PSW_EDTLB = (1<<8),
    PSW_BDTLB = (1<<9),
    PSW_USR   = (1<<10),
    PSW_EUSR  = (1<<11),
    PSW_BUSR  = (1<<12),
};

/* commands, encoded into the lowest bits in TLBVADDR */
enum {
    ITLB_NOP          = 0x00,  /* used for UPDATE */
    DTLB_NOP          = 0x01,  /* used for UPDATE */
    ITLB_INVALIDATE   = 0x02,
    DTLB_INVALIDATE   = 0x03,
    ITLB_FLUSH        = 0x04,  /* actual vaddr bits are ignored */
    DTLB_FLUSH        = 0x05,  /* actual vaddr bits are ignored */
};

/* TLB properties, encoded into lowest bits in TLBPADDR */
enum {
    TLB_VALID = (1<<0),   /* set by hardware on update/invalidate */
    TLB_R     = (1<<1),
    TLB_W     = (1<<2),
    TLB_X     = (1<<3),
};

TBD: reading the entries back for debugging purposes:
 - writing TLBVADDR, with special command? maybe ITLB/DTLB_NOP is sufficient.
 - reading TLBVADDR  -> gets vfn
 - reading TLBPADDR  -> get pfn + permissions + valid bit

TBD: if the kernel is executing with MMU enabled, but MMU is turned off on 
exception, how do we handle interrupt/tlb miss handling, eg. how do we access 
the kernels page table?

TBD: introduce MMU bit in CFG2 CSR.

-- 
Michael
_______________________________________________
http://lists.milkymist.org/listinfo.cgi/devel-milkymist.org
IRC: #milkymist@Freenode

Reply via email to