22
33use core:: arch:: { asm, global_asm} ;
44
5- use aarch64_cpu:: registers:: { SCTLR_EL1 , Writeable } ;
5+ use aarch64_cpu:: asm:: { barrier, wfe} ;
6+ use aarch64_cpu:: registers:: {
7+ CPACR_EL1 , ID_AA64MMFR0_EL1 , MAIR_EL1 , MDSCR_EL1 , ReadWriteable , Readable , SCTLR_EL1 , TCR_EL1 ,
8+ TPIDR_EL0 , TPIDR_EL1 , Writeable ,
9+ } ;
610use log:: info;
11+ use tock_registers:: fields:: { FieldValue , TryFromValue } ;
712
813const BOOT_CORE_ID : u64 = 0 ; // ID of CPU for booting on SMP systems - this might be board specific in the future
914
10- /*
11- * Memory types available.
12- */
13- #[ allow( non_upper_case_globals) ]
14- const MT_DEVICE_nGnRnE : u64 = 0 ;
15- #[ allow( non_upper_case_globals) ]
16- const MT_DEVICE_nGnRE : u64 = 1 ;
17- const MT_DEVICE_GRE : u64 = 2 ;
18- const MT_NORMAL_NC : u64 = 3 ;
19- const MT_NORMAL : u64 = 4 ;
20-
21- #[ inline( always) ]
22- const fn mair ( attr : u64 , mt : u64 ) -> u64 {
23- attr << ( mt * 8 )
24- }
25-
26- /*
27- * TCR flags
28- */
29- const TCR_IRGN_WBWA : u64 = ( ( 1 ) << 8 ) | ( ( 1 ) << 24 ) ;
30- const TCR_ORGN_WBWA : u64 = ( ( 1 ) << 10 ) | ( ( 1 ) << 26 ) ;
31- const TCR_SHARED : u64 = ( ( 3 ) << 12 ) | ( ( 3 ) << 28 ) ;
32- const TCR_TBI0 : u64 = 1 << 37 ;
33- const TCR_TBI1 : u64 = 1 << 38 ;
34- const TCR_ASID16 : u64 = 1 << 36 ;
35- const TCR_TG1_16K : u64 = 1 << 30 ;
36- const TCR_TG1_4K : u64 = 0 << 30 ;
37- const TCR_FLAGS : u64 = TCR_IRGN_WBWA | TCR_ORGN_WBWA | TCR_SHARED ;
38-
3915/// Number of virtual address bits for 4KB page
4016const VA_BITS : u64 = 48 ;
4117
42- #[ inline( always) ]
43- const fn tcr_size ( x : u64 ) -> u64 {
44- ( ( 64 - x) << 16 ) | ( 64 - x)
45- }
46-
4718global_asm ! (
4819 include_str!( "entry.s" ) ,
4920 start_rust = sym start_rust,
@@ -59,14 +30,14 @@ unsafe fn pre_init() -> ! {
5930 info ! ( "Enter startup code" ) ;
6031
6132 /* disable interrupts */
33+ /* FIXME: Migrate to aarch64_cpu's DAIFSet definition once released */
6234 unsafe {
6335 asm ! ( "msr daifset, 0b111" , options( nostack) ) ;
6436 }
6537
6638 /* reset thread id registers */
67- unsafe {
68- asm ! ( "msr tpidr_el0, xzr" , "msr tpidr_el1, xzr" , options( nostack) ) ;
69- }
39+ TPIDR_EL0 . set ( 0 ) ;
40+ TPIDR_EL1 . set ( 0 ) ;
7041
7142 /*
7243 * Disable the MMU. We may have entered the kernel with it on and
@@ -75,87 +46,67 @@ unsafe fn pre_init() -> ! {
7546 * but in this case the code to find where we are running from
7647 * would have also failed.
7748 */
78- unsafe {
79- asm ! ( "dsb sy" ,
80- "mrs x2, sctlr_el1" ,
81- "bic x2, x2, 0x1" ,
82- "msr sctlr_el1, x2" ,
83- "isb" ,
84- out( "x2" ) _,
85- options( nostack) ,
86- ) ;
87- }
49+ barrier:: dsb ( barrier:: SY ) ;
50+ SCTLR_EL1 . modify ( SCTLR_EL1 :: M :: Disable ) ;
51+ barrier:: isb ( barrier:: SY ) ;
8852
8953 unsafe {
90- asm ! ( "ic iallu" , "tlbi vmalle1is" , "dsb ish" , options( nostack) ) ;
54+ asm ! ( "ic iallu" , "tlbi vmalle1is" , options( nostack) ) ;
9155 }
56+ barrier:: dsb ( barrier:: ISH ) ;
9257
9358 /*
9459 * Setup memory attribute type tables
95- *
96- * Memory regioin attributes for LPAE:
97- *
98- * n = AttrIndx[2:0]
99- * n MAIR
100- * DEVICE_nGnRnE 000 00000000 (0x00)
101- * DEVICE_nGnRE 001 00000100 (0x04)
102- * DEVICE_GRE 010 00001100 (0x0c)
103- * NORMAL_NC 011 01000100 (0x44)
104- * NORMAL 100 11111111 (0xff)
10560 */
106- let mair_el1 = mair ( 0x00 , MT_DEVICE_nGnRnE )
107- | mair ( 0x04 , MT_DEVICE_nGnRE )
108- | mair ( 0x0c , MT_DEVICE_GRE )
109- | mair ( 0x44 , MT_NORMAL_NC )
110- | mair ( 0xff , MT_NORMAL ) ;
111- unsafe {
112- asm ! ( "msr mair_el1, {}" ,
113- in( reg) mair_el1,
114- options( nostack) ,
115- ) ;
116- }
61+ MAIR_EL1 . write (
62+ MAIR_EL1 :: Attr0_Device :: nonGathering_nonReordering_noEarlyWriteAck
63+ + MAIR_EL1 :: Attr1_Device :: nonGathering_nonReordering_EarlyWriteAck
64+ + MAIR_EL1 :: Attr2_Device :: Gathering_Reordering_EarlyWriteAck
65+ + MAIR_EL1 :: Attr3_Normal_Inner :: NonCacheable
66+ + MAIR_EL1 :: Attr3_Normal_Outer :: NonCacheable
67+ + MAIR_EL1 :: Attr4_Normal_Inner :: WriteBack_NonTransient_ReadWriteAlloc
68+ + MAIR_EL1 :: Attr4_Normal_Outer :: WriteBack_NonTransient_ReadWriteAlloc ,
69+ ) ;
11770
11871 /*
11972 * Setup translation control register (TCR)
12073 */
12174
12275 // determine physical address size
123- unsafe {
124- asm ! ( "mrs x0, id_aa64mmfr0_el1" ,
125- "and x0, x0, 0xF" ,
126- "lsl x0, x0, 32" ,
127- "orr x0, x0, {tcr_bits}" ,
128- "mrs x1, id_aa64mmfr0_el1" ,
129- "bfi x0, x1, #32, #3" ,
130- "msr tcr_el1, x0" ,
131- tcr_bits = in( reg) tcr_size( VA_BITS ) | TCR_TG1_4K | TCR_FLAGS ,
132- out( "x0" ) _,
133- out( "x1" ) _,
134- ) ;
135- }
76+ let Some ( pa_range) = ID_AA64MMFR0_EL1
77+ . read_as_enum :: < ID_AA64MMFR0_EL1 :: PARange :: Value > ( ID_AA64MMFR0_EL1 :: PARange )
78+ else {
79+ panic ! ( "Unknown physical address range" )
80+ } ;
81+ let Some ( ips) = TCR_EL1 :: IPS :: Value :: try_from_value ( pa_range as u64 ) else {
82+ panic ! ( "Invalid physical address size" )
83+ } ;
84+
85+ TCR_EL1 . write (
86+ FieldValue :: from ( ips)
87+ + TCR_EL1 :: T1SZ . val ( 64 - VA_BITS )
88+ + TCR_EL1 :: T0SZ . val ( 64 - VA_BITS )
89+ + TCR_EL1 :: TG1 :: KiB_4
90+ + TCR_EL1 :: IRGN0 :: WriteBack_ReadAlloc_WriteAlloc_Cacheable
91+ + TCR_EL1 :: IRGN1 :: WriteBack_ReadAlloc_WriteAlloc_Cacheable
92+ + TCR_EL1 :: ORGN0 :: WriteBack_ReadAlloc_WriteAlloc_Cacheable
93+ + TCR_EL1 :: ORGN1 :: WriteBack_ReadAlloc_WriteAlloc_Cacheable
94+ + TCR_EL1 :: SH0 :: Inner
95+ + TCR_EL1 :: SH1 :: Inner ,
96+ ) ;
13697
13798 /*
13899 * Enable FP/ASIMD in Architectural Feature Access Control Register,
139100 */
140- let bit_mask: u64 = 3 << 20 ;
141- unsafe {
142- asm ! ( "msr cpacr_el1, {mask}" ,
143- mask = in( reg) bit_mask,
144- options( nostack) ,
145- ) ;
146- }
101+ CPACR_EL1 . write ( CPACR_EL1 :: FPEN :: TrapNothing ) ;
147102
148103 /*
149104 * Reset debug control register
150105 */
151- unsafe {
152- asm ! ( "msr mdscr_el1, xzr" , options( nostack) ) ;
153- }
106+ MDSCR_EL1 . set ( 0 ) ;
154107
155108 /* Memory barrier */
156- unsafe {
157- asm ! ( "dsb sy" , options( nostack) ) ;
158- }
109+ barrier:: dsb ( barrier:: SY ) ;
159110
160111 /*
161112 * Prepare system control register (SCTRL)
@@ -195,10 +146,8 @@ unsafe fn pre_init() -> ! {
195146 }
196147}
197148
198- pub unsafe fn wait_forever ( ) -> ! {
149+ pub fn wait_forever ( ) -> ! {
199150 loop {
200- unsafe {
201- asm ! ( "wfe" ) ;
202- }
151+ wfe ( ) ;
203152 }
204153}
0 commit comments