Code Monkey home page Code Monkey logo

Comments (11)

isaac2-lee avatar isaac2-lee commented on July 21, 2024

Current : pause the system after setting the SCTLR_EL2
(refer branch/commit: 'dev/isaac2.lee/enable_mmu')

suspected points

  1. physical address was wrong (why did old islet set the uart address)
  2. not make translation table well (MMU_PAGE)
  3. miss register settings such as ttbr1?

from islet.

isaac2-lee avatar isaac2-lee commented on July 21, 2024
  1. not make translation table well (MMU_PAGE)

making table process looks just wrong
(* others should be checked)

below is from test with 512 pages
I can check the overlapping address

[DEBUG]monitor::mm::page_table -- max enries: 512          
[DEBUG]monitor::mm::page_table -- page[0]: FDC16000     // LEVEL1
[DEBUG]monitor::mm::page_table -- max enries: 512
[DEBUG]monitor::mm::page_table -- page[224]: FDC17000 // LEVEL2
[DEBUG]monitor::mm::page_table -- max enries: 512
[DEBUG]monitor::mm::page_table -- page[160]: FDC00000 // LEVEL3
[DEBUG]monitor::mm::page_table -- page[161]: FDC01000
[DEBUG]monitor::mm::page_table -- page[162]: FDC02000
[DEBUG]monitor::mm::page_table -- page[163]: FDC03000
[DEBUG]monitor::mm::page_table -- page[164]: FDC04000
[DEBUG]monitor::mm::page_table -- page[165]: FDC05000
[DEBUG]monitor::mm::page_table -- page[166]: FDC06000
[DEBUG]monitor::mm::page_table -- page[167]: FDC07000
[DEBUG]monitor::mm::page_table -- page[168]: FDC08000
[DEBUG]monitor::mm::page_table -- page[169]: FDC09000
[DEBUG]monitor::mm::page_table -- page[170]: FDC0A000
[DEBUG]monitor::mm::page_table -- page[171]: FDC0B000
[DEBUG]monitor::mm::page_table -- page[172]: FDC0C000
[DEBUG]monitor::mm::page_table -- page[173]: FDC0D000
[DEBUG]monitor::mm::page_table -- page[174]: FDC0E000
[DEBUG]monitor::mm::page_table -- page[175]: FDC0F000
[DEBUG]monitor::mm::page_table -- page[176]: FDC10000
[DEBUG]monitor::mm::page_table -- page[177]: FDC11000
[DEBUG]monitor::mm::page_table -- page[178]: FDC12000
[DEBUG]monitor::mm::page_table -- page[179]: FDC13000
[DEBUG]monitor::mm::page_table -- page[180]: FDC14000
[DEBUG]monitor::mm::page_table -- page[181]: FDC15000
[DEBUG]monitor::mm::page_table -- page[182]: FDC16000
[DEBUG]monitor::mm::page_table -- page[183]: FDC17000
[DEBUG]monitor::mm::page_table -- page[184]: FDC18000
[DEBUG]monitor::mm::page_table -- page[185]: FDC19000
[DEBUG]monitor::mm::page_table -- page[186]: FDC1A000
....

it means I have to implement PageTranslation trait newly(translate address, mapping), not using old one.

from islet.

isaac2-lee avatar isaac2-lee commented on July 21, 2024

최종 entry 에 입력될 때 RawPTE의 TABLE_OR_PAGE bit에 맞추어 주소가 set되고 있지 않은데
이것이 정상적인것인지 확인필요.. 임의로 bit를 올려 세팅시에 system hang 발생

mm/pte.rs

impl page_table::Entry for Entry {
...
    fn set(&mut self, addr: PhysAddr, flags: u64) {
        self.0
            .set(addr.as_u64() | flags) // <----------- ?
            .set_masked_value(RawPTE::SH, attr::shareable::INNER)
            .set_bits(RawPTE::AF)
            .set_bits(RawPTE::VALID);

        unsafe {
            core::arch::asm!(
                "dsb ishst",
                "dc civac, {}",
                "dsb ish",
                "isb",
                in(reg) &self.0 as *const _ as usize,
            );
        }


    fn set_with_page_table_flags(&mut self, addr: PhysAddr) {
        self.set(
            addr,  <-------------------------------- ?
            bits_in_reg(RawPTE::ATTR, attr::attribute::NORMAL) //?
                | bits_in_reg(RawPTE::TYPE, attr::page_type::TABLE_OR_PAGE),
        )
    }

from islet.

isaac2-lee avatar isaac2-lee commented on July 21, 2024
  • physical address was wrong (why did old islet set the uart address)
    -> in the table, inital physical address modified the rmm base address
    let device_flags = helper::bits_in_reg(RawPTE::ATTR, attr::attribute::DEVICE_NGNRE)
        | helper::bits_in_reg(RawPTE::AP, attr::permission::RW);
    let virt = Page::<BasePageSize, VirtualAddr>::range_with_size(
        VirtualAddr::from(PAGE_OFFSET),
        LARGE_PAGE_SIZE,
    );
    unsafe {
        let phys = Page::<BasePageSize, PhysAddr>::range_with_size(
            PhysAddr::from(rmm_base),
            LARGE_PAGE_SIZE,
        );
        root.set_pages(virt, phys, device_flags as u64);
    }
  • not make translation table well (MMU_PAGE)
    -> last commit looks good, IMO
    ref.
  • miss register settings such as ttbr1?
    -> ???

from islet.

isaac2-lee avatar isaac2-lee commented on July 21, 2024

unit-test

check the unit test codes.
on the previous unit-test, it was tested with only rmm/monitor
when I checked rmm/armv9a path, it returned error such as below
IMO, test developer can't fix this error and tested only rmm/montor path

error: the `#[alloc_error_handler]` in this crate conflicts with allocation error handler in: std

error: invalid register `x0`: unknown register
  --> rmm/armv9a/src/helper/mod.rs:82:9
   |
82 |         inlateout("x0") args[0] => ret[0],
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: invalid register `x1`: unknown register
  --> rmm/armv9a/src/helper/mod.rs:83:9
   |
83 |         inlateout("x1") args[1] => ret[1],
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: invalid register `x2`: unknown register
  --> rmm/armv9a/src/helper/mod.rs:84:9
   |
84 |         inlateout("x2") args[2] => ret[2],
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: invalid register `x3`: unknown register
  --> rmm/armv9a/src/helper/mod.rs:85:9
   |
85 |         inlateout("x3") args[3] => ret[3],
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: invalid register `x0`: unknown register
  --> rmm/armv9a/src/smc.rs:31:17
   |
31 |                 inlateout("x0") command => ret[0],
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: invalid register `x1`: unknown register
  --> rmm/armv9a/src/smc.rs:32:17
   |
32 |                 inlateout("x1") args[0] => ret[1],
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: invalid register `x2`: unknown register
  --> rmm/armv9a/src/smc.rs:33:17
   |
33 |                 inlateout("x2") args[1] => ret[2],
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: invalid register `x3`: unknown register
  --> rmm/armv9a/src/smc.rs:34:17
   |
34 |                 inlateout("x3") args[2] => ret[3],
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: invalid register `x4`: unknown register
  --> rmm/armv9a/src/smc.rs:35:17
   |
35 |                 inlateout("x4") args[3] => ret[4],
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: invalid register `x5`: unknown register
  --> rmm/armv9a/src/smc.rs:36:17
   |
36 |                 out("x5") ret[5],
   |                 ^^^^^^^^^^^^^^^^

error: invalid register `x6`: unknown register
  --> rmm/armv9a/src/smc.rs:37:17
   |
37 |                 out("x6") ret[6],
   |                 ^^^^^^^^^^^^^^^^

error: invalid register `x7`: unknown register
  --> rmm/armv9a/src/smc.rs:38:17
   |
38 |                 out("x7") ret[7],
   |                 ^^^^^^^^^^^^^^^^

error[E0152]: found duplicate lang item `panic_impl`
 --> rmm/armv9a/src/panic.rs:7:1
  |
7 | pub extern "C" fn panic_handler(_info: &core::panic::PanicInfo<'_>) -> ! {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

from islet.

isaac2-lee avatar isaac2-lee commented on July 21, 2024

Current page table descriptor look up following figure.

image
[Armv8-A Address Translation Version 1.1]

from islet.

isaac2-lee avatar isaac2-lee commented on July 21, 2024

tf-rmm

TCR_EL2

	/* Recompute the value for TCR_EL2 */
	tcr = (uint64_t)t0sz << TCR_EL2_T0SZ_SHIFT;
	tcr |= (uint64_t)t1sz << TCR_EL2_T1SZ_SHIFT;

	/*
	 * Set the cacheability and shareability attributes for memory
	 * associated with translation table walks.
	 */
	/* Inner & outer WBWA & shareable for both halfs. */
	tcr |= TCR_EL2_IRGN0_WBWA | TCR_EL2_ORGN0_WBWA | TCR_EL2_SH0_IS;
	tcr |= TCR_EL2_IRGN1_WBWA | TCR_EL2_ORGN1_WBWA | TCR_EL2_SH1_IS;

	/*
	 * ASID and hierarchical permissions.
	 */
	tcr |= TCR_EL2_AS | TCR_EL2_HPD0 | TCR_EL2_HPD1;

	/*
	 * Granule size. Only 4K supported on both halfs.
	 */
	tcr |= TCR_EL2_TG0_4K | TCR_EL2_TG1_4K;

accoding to specification, when HCR_EL2.E2H == 1, tcr register descriptor will be changed.
tf-rmm is turned on HCR_EL2.E2H, islet don't. just follow up the IRGN0, ORGN0, SH0, HDP0.

from islet.

isaac2-lee avatar isaac2-lee commented on July 21, 2024

MAIR_EL2 : tf-rmm

	mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX);
	mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, ATTR_IWBWA_OWBWA_NTR_INDEX);
	mair |= MAIR_ATTR_SET(ATTR_NON_CACHEABLE, ATTR_NON_CACHEABLE_INDEX);

00000000_01000100_00000100_11111111 (32bit)

일단은 tf-rmm 참고해서 세팅중

from islet.

isaac2-lee avatar isaac2-lee commented on July 21, 2024

Current page table descriptor look up following figure.

image

Page table descriptor, rmm/page_table/entry.rs

define_bits!(
    PTDesc,
    Reserved[58 - 55],
    UXN[54 - 54],
    PXN[53 - 53],
    ADDR_BLK_L1[47 - 30],      // block descriptor; level 1
    ADDR_BLK_L2[47 - 21],      // block descriptor; level 2
    ADDR_TBL_OR_PAGE[47 - 12], // table descriptor(level 0-2) || page descriptor(level3)
    AF[10 - 10],               // access flag
    SH[9 - 8],                 // pte_shareable
    AP[7 - 6],                 // pte_access_perm
    NS[5 - 5],                 // security bit
    INDX[4 - 2],               // the index into the Memory Attribute Indirection Register MAIR_ELn
    TYPE[1 - 1],
    VALID[0 - 0]
);

attribute setting

    fn set(&mut self, addr: PhysAddr, flags: u64) {
        self.0
            .set(addr.as_u64() | flags)
            .set_masked_value(PTDesc::SH, attr::shareable::INNER)
            .set_bits(PTDesc::AF)
            .set_bits(PTDesc::VALID);
....

    fn set_with_page_table_flags(&mut self, addr: PhysAddr) {
        self.set(
            addr,
            bits_in_reg(PTDesc::TYPE, attr::page_type::TABLE_OR_PAGE),
        )
    }

in case of stage2_translation, it has one more bit setting
bits_in_reg(RawPTE::ATTR, pte::attribute::NORMAL)

from islet.

isaac2-lee avatar isaac2-lee commented on July 21, 2024

memory from EL3 should be set on NS[5-5] bit.
in case of disable NS bit, can't access L3 table. (occured fault)

-> It's wrong analysis. NS bit should be not set

from islet.

isaac2-lee avatar isaac2-lee commented on July 21, 2024

for log,
UART address also should be set in page table.

islet has a uart physical address, 0x1c0c0000.

            self.set_pages(
                VirtAddr::from(uart_phys),
                PhysAddr::from(uart_phys),
                1,
                rw_flags,
            );

from islet.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.