@@ -12,15 +12,18 @@ mod start;
12
12
pub mod switch;
13
13
pub mod systemtime;
14
14
15
+ use alloc:: alloc:: { Layout , alloc} ;
15
16
use core:: arch:: global_asm;
16
- use core:: str;
17
- use core:: sync:: atomic:: { AtomicU32 , AtomicU64 , Ordering } ;
17
+ use core:: sync:: atomic:: { AtomicPtr , AtomicU32 , Ordering } ;
18
18
use core:: task:: Waker ;
19
+ use core:: { ptr, str} ;
19
20
20
21
use memory_addresses:: arch:: aarch64:: { PhysAddr , VirtAddr } ;
21
22
22
23
use crate :: arch:: aarch64:: kernel:: core_local:: * ;
23
24
use crate :: arch:: aarch64:: kernel:: serial:: SerialPort ;
25
+ use crate :: arch:: aarch64:: mm:: paging:: { BasePageSize , PageSize } ;
26
+ use crate :: config:: * ;
24
27
use crate :: env;
25
28
26
29
const SERIAL_PORT_BAUDRATE : u32 = 115_200 ;
@@ -69,12 +72,15 @@ impl Default for Console {
69
72
}
70
73
}
71
74
75
+ #[ repr( align( 8 ) ) ]
76
+ pub ( crate ) struct AlignedAtomicU32 ( AtomicU32 ) ;
77
+
72
78
/// `CPU_ONLINE` is the count of CPUs that finished initialization.
73
79
///
74
80
/// It also synchronizes initialization of CPU cores.
75
- pub ( crate ) static CPU_ONLINE : AtomicU32 = AtomicU32 :: new ( 0 ) ;
81
+ pub ( crate ) static CPU_ONLINE : AlignedAtomicU32 = AlignedAtomicU32 ( AtomicU32 :: new ( 0 ) ) ;
76
82
77
- pub ( crate ) static CURRENT_STACK_ADDRESS : AtomicU64 = AtomicU64 :: new ( 0 ) ;
83
+ pub ( crate ) static CURRENT_STACK_ADDRESS : AtomicPtr < u8 > = AtomicPtr :: new ( ptr :: null_mut ( ) ) ;
78
84
79
85
#[ cfg( target_os = "none" ) ]
80
86
global_asm ! ( include_str!( "start.s" ) ) ;
@@ -102,12 +108,25 @@ pub fn get_limit() -> usize {
102
108
103
109
#[ cfg( feature = "smp" ) ]
104
110
pub fn get_possible_cpus ( ) -> u32 {
105
- CPU_ONLINE . load ( Ordering :: Acquire )
111
+ use hermit_dtb:: Dtb ;
112
+
113
+ let dtb = unsafe {
114
+ Dtb :: from_raw ( core:: ptr:: with_exposed_provenance (
115
+ env:: boot_info ( ) . hardware_info . device_tree . unwrap ( ) . get ( ) as usize ,
116
+ ) )
117
+ . expect ( ".dtb file has invalid header" )
118
+ } ;
119
+
120
+ dtb. enum_subnodes ( "/cpus" )
121
+ . filter ( |name| name. contains ( "cpu@" ) )
122
+ . count ( )
123
+ . try_into ( )
124
+ . unwrap ( )
106
125
}
107
126
108
127
#[ cfg( feature = "smp" ) ]
109
128
pub fn get_processor_count ( ) -> u32 {
110
- 1
129
+ CPU_ONLINE . 0 . load ( Ordering :: Acquire )
111
130
}
112
131
113
132
#[ cfg( not( feature = "smp" ) ) ]
@@ -149,10 +168,16 @@ pub fn application_processor_init() {
149
168
150
169
fn finish_processor_init ( ) {
151
170
debug ! ( "Initialized Processor" ) ;
171
+
172
+ // Allocate stack for the CPU and pass the addresses.
173
+ let layout = Layout :: from_size_align ( KERNEL_STACK_SIZE , BasePageSize :: SIZE as usize ) . unwrap ( ) ;
174
+ let stack = unsafe { alloc ( layout) } ;
175
+ assert ! ( !stack. is_null( ) ) ;
176
+ CURRENT_STACK_ADDRESS . store ( stack, Ordering :: Relaxed ) ;
152
177
}
153
178
154
179
pub fn boot_next_processor ( ) {
155
- CPU_ONLINE . fetch_add ( 1 , Ordering :: Release ) ;
180
+ CPU_ONLINE . 0 . fetch_add ( 1 , Ordering :: Release ) ;
156
181
}
157
182
158
183
pub fn print_statistics ( ) {
0 commit comments