11use alloc:: collections:: { BTreeMap , VecDeque } ;
22use core:: arch:: asm;
3+ use core:: ptr:: NonNull ;
34use core:: sync:: atomic:: { AtomicU64 , Ordering } ;
45
56use aarch64:: regs:: * ;
67use ahash:: RandomState ;
7- use arm_gic:: gicv3:: { GicV3 , InterruptGroup , SgiTarget , SgiTargetGroup } ;
8- use arm_gic:: { IntId , Trigger } ;
8+ use arm_gic:: gicv3:: registers:: { Gicd , GicrSgi } ;
9+ use arm_gic:: gicv3:: { GicCpuInterface , GicV3 , InterruptGroup , SgiTarget , SgiTargetGroup } ;
10+ use arm_gic:: { IntId , Trigger , UniqueMmioPointer } ;
911use fdt:: standard_nodes:: Compatible ;
1012use free_list:: PageLayout ;
1113use hashbrown:: HashMap ;
@@ -127,7 +129,7 @@ pub(crate) fn install_handlers() {
127129
128130#[ unsafe( no_mangle) ]
129131pub ( crate ) extern "C" fn do_fiq ( _state : & State ) -> * mut usize {
130- if let Some ( irqid) = GicV3 :: get_and_acknowledge_interrupt ( InterruptGroup :: Group1 ) {
132+ if let Some ( irqid) = GicCpuInterface :: get_and_acknowledge_interrupt ( InterruptGroup :: Group1 ) {
131133 let vector: u8 = u32:: from ( irqid) . try_into ( ) . unwrap ( ) ;
132134
133135 debug ! ( "Receive fiq {vector}" ) ;
@@ -143,7 +145,7 @@ pub(crate) extern "C" fn do_fiq(_state: &State) -> *mut usize {
143145 crate :: executor:: run ( ) ;
144146 core_scheduler ( ) . handle_waiting_tasks ( ) ;
145147
146- GicV3 :: end_interrupt ( irqid, InterruptGroup :: Group1 ) ;
148+ GicCpuInterface :: end_interrupt ( irqid, InterruptGroup :: Group1 ) ;
147149
148150 return core_scheduler ( ) . scheduler ( ) . unwrap_or_default ( ) ;
149151 }
@@ -153,7 +155,7 @@ pub(crate) extern "C" fn do_fiq(_state: &State) -> *mut usize {
153155
154156#[ unsafe( no_mangle) ]
155157pub ( crate ) extern "C" fn do_irq ( _state : & State ) -> * mut usize {
156- if let Some ( irqid) = GicV3 :: get_and_acknowledge_interrupt ( InterruptGroup :: Group1 ) {
158+ if let Some ( irqid) = GicCpuInterface :: get_and_acknowledge_interrupt ( InterruptGroup :: Group1 ) {
157159 let vector: u8 = u32:: from ( irqid) . try_into ( ) . unwrap ( ) ;
158160
159161 debug ! ( "Receive interrupt {vector}" ) ;
@@ -169,7 +171,7 @@ pub(crate) extern "C" fn do_irq(_state: &State) -> *mut usize {
169171 crate :: executor:: run ( ) ;
170172 core_scheduler ( ) . handle_waiting_tasks ( ) ;
171173
172- GicV3 :: end_interrupt ( irqid, InterruptGroup :: Group1 ) ;
174+ GicCpuInterface :: end_interrupt ( irqid, InterruptGroup :: Group1 ) ;
173175
174176 trace ! ( "Disabling floating point" ) ;
175177
@@ -209,8 +211,10 @@ pub(crate) extern "C" fn do_sync(state: &State) {
209211 error ! ( "Table Base Register {:#x}" , TTBR0_EL1 . get( ) ) ;
210212 error ! ( "Exception Syndrome Register {esr:#x}" ) ;
211213
212- if let Some ( irqid) = GicV3 :: get_and_acknowledge_interrupt ( InterruptGroup :: Group1 ) {
213- GicV3 :: end_interrupt ( irqid, InterruptGroup :: Group1 ) ;
214+ if let Some ( irqid) =
215+ GicCpuInterface :: get_and_acknowledge_interrupt ( InterruptGroup :: Group1 )
216+ {
217+ GicCpuInterface :: end_interrupt ( irqid, InterruptGroup :: Group1 ) ;
214218 } else {
215219 error ! ( "Unable to acknowledge interrupt!" ) ;
216220 }
@@ -263,7 +267,7 @@ pub fn wakeup_core(core_id: CoreId) {
263267 debug ! ( "Wakeup core {core_id}" ) ;
264268 let reschedid = IntId :: sgi ( SGI_RESCHED . into ( ) ) ;
265269
266- GicV3 :: send_sgi (
270+ GicCpuInterface :: send_sgi (
267271 reschedid,
268272 SgiTarget :: List {
269273 affinity3 : 0 ,
@@ -272,7 +276,8 @@ pub fn wakeup_core(core_id: CoreId) {
272276 target_list : 1 << core_id,
273277 } ,
274278 SgiTargetGroup :: CurrentGroup1 ,
275- ) ;
279+ )
280+ . unwrap ( ) ;
276281}
277282
278283pub ( crate ) fn init ( ) {
@@ -337,16 +342,12 @@ pub(crate) fn init() {
337342 flags,
338343 ) ;
339344
340- let mut gic = unsafe {
341- GicV3 :: new (
342- gicd_address. as_mut_ptr ( ) ,
343- gicr_address. as_mut_ptr ( ) ,
344- num_cpus,
345- is_gic_v4,
346- )
347- } ;
345+ let gicd = NonNull :: new ( gicd_address. as_mut_ptr :: < Gicd > ( ) ) . unwrap ( ) ;
346+ let gicd = unsafe { UniqueMmioPointer :: new ( gicd) } ;
347+ let gicr_base = NonNull :: new ( gicr_address. as_mut_ptr :: < GicrSgi > ( ) ) . unwrap ( ) ;
348+ let mut gic = unsafe { GicV3 :: new ( gicd, gicr_base, num_cpus, is_gic_v4) } ;
348349 gic. setup ( cpu_id) ;
349- GicV3 :: set_priority_mask ( 0xff ) ;
350+ GicCpuInterface :: set_priority_mask ( 0xff ) ;
350351
351352 if let Some ( timer_node) = fdt. find_compatible ( & [ "arm,armv8-timer" , "arm,armv7-timer" ] ) {
352353 let irq_slice = timer_node. property ( "interrupts" ) . unwrap ( ) . value ;
@@ -380,15 +381,19 @@ pub(crate) fn init() {
380381 } else {
381382 panic ! ( "Invalid interrupt type" ) ;
382383 } ;
383- gic. set_interrupt_priority ( timer_irqid, Some ( cpu_id) , 0x00 ) ;
384+ gic. set_interrupt_priority ( timer_irqid, Some ( cpu_id) , 0x00 )
385+ . unwrap ( ) ;
384386 if ( irqflags & 0xf ) == 4 || ( irqflags & 0xf ) == 8 {
385- gic. set_trigger ( timer_irqid, Some ( cpu_id) , Trigger :: Level ) ;
387+ gic. set_trigger ( timer_irqid, Some ( cpu_id) , Trigger :: Level )
388+ . unwrap ( ) ;
386389 } else if ( irqflags & 0xf ) == 2 || ( irqflags & 0xf ) == 1 {
387- gic. set_trigger ( timer_irqid, Some ( cpu_id) , Trigger :: Edge ) ;
390+ gic. set_trigger ( timer_irqid, Some ( cpu_id) , Trigger :: Edge )
391+ . unwrap ( ) ;
388392 } else {
389393 panic ! ( "Invalid interrupt level!" ) ;
390394 }
391- gic. enable_interrupt ( timer_irqid, Some ( cpu_id) , true ) ;
395+ gic. enable_interrupt ( timer_irqid, Some ( cpu_id) , true )
396+ . unwrap ( ) ;
392397 }
393398
394399 if let Some ( uart_node) = fdt. find_compatible ( & [ "arm,pl011" ] ) {
@@ -418,20 +423,25 @@ pub(crate) fn init() {
418423 } else {
419424 panic ! ( "Invalid interrupt type" ) ;
420425 } ;
421- gic. set_interrupt_priority ( uart_irqid, Some ( cpu_id) , 0x00 ) ;
426+ gic. set_interrupt_priority ( uart_irqid, Some ( cpu_id) , 0x00 )
427+ . unwrap ( ) ;
422428 if ( irqflags & 0xf ) == 4 || ( irqflags & 0xf ) == 8 {
423- gic. set_trigger ( uart_irqid, Some ( cpu_id) , Trigger :: Level ) ;
429+ gic. set_trigger ( uart_irqid, Some ( cpu_id) , Trigger :: Level )
430+ . unwrap ( ) ;
424431 } else if ( irqflags & 0xf ) == 2 || ( irqflags & 0xf ) == 1 {
425- gic. set_trigger ( uart_irqid, Some ( cpu_id) , Trigger :: Edge ) ;
432+ gic. set_trigger ( uart_irqid, Some ( cpu_id) , Trigger :: Edge )
433+ . unwrap ( ) ;
426434 } else {
427435 panic ! ( "Invalid interrupt level!" ) ;
428436 }
429- gic. enable_interrupt ( uart_irqid, Some ( cpu_id) , true ) ;
437+ gic. enable_interrupt ( uart_irqid, Some ( cpu_id) , true )
438+ . unwrap ( ) ;
430439 }
431440
432441 let reschedid = IntId :: sgi ( SGI_RESCHED . into ( ) ) ;
433- gic. set_interrupt_priority ( reschedid, Some ( cpu_id) , 0x01 ) ;
434- gic. enable_interrupt ( reschedid, Some ( cpu_id) , true ) ;
442+ gic. set_interrupt_priority ( reschedid, Some ( cpu_id) , 0x01 )
443+ . unwrap ( ) ;
444+ gic. enable_interrupt ( reschedid, Some ( cpu_id) , true ) . unwrap ( ) ;
435445 IRQ_NAMES . lock ( ) . insert ( SGI_RESCHED , "Reschedule" ) ;
436446
437447 * GIC . lock ( ) = Some ( gic) ;
@@ -445,7 +455,7 @@ pub fn init_cpu() {
445455 debug ! ( "Mark cpu {cpu_id} as awake" ) ;
446456
447457 gic. setup ( cpu_id) ;
448- GicV3 :: set_priority_mask ( 0xff ) ;
458+ GicCpuInterface :: set_priority_mask ( 0xff ) ;
449459
450460 let fdt = env:: fdt ( ) . unwrap ( ) ;
451461
@@ -471,20 +481,25 @@ pub fn init_cpu() {
471481 } else {
472482 panic ! ( "Invalid interrupt type" ) ;
473483 } ;
474- gic. set_interrupt_priority ( timer_irqid, Some ( cpu_id) , 0x00 ) ;
484+ gic. set_interrupt_priority ( timer_irqid, Some ( cpu_id) , 0x00 )
485+ . unwrap ( ) ;
475486 if ( irqflags & 0xf ) == 4 || ( irqflags & 0xf ) == 8 {
476- gic. set_trigger ( timer_irqid, Some ( cpu_id) , Trigger :: Level ) ;
487+ gic. set_trigger ( timer_irqid, Some ( cpu_id) , Trigger :: Level )
488+ . unwrap ( ) ;
477489 } else if ( irqflags & 0xf ) == 2 || ( irqflags & 0xf ) == 1 {
478- gic. set_trigger ( timer_irqid, Some ( cpu_id) , Trigger :: Edge ) ;
490+ gic. set_trigger ( timer_irqid, Some ( cpu_id) , Trigger :: Edge )
491+ . unwrap ( ) ;
479492 } else {
480493 panic ! ( "Invalid interrupt level!" ) ;
481494 }
482- gic. enable_interrupt ( timer_irqid, Some ( cpu_id) , true ) ;
495+ gic. enable_interrupt ( timer_irqid, Some ( cpu_id) , true )
496+ . unwrap ( ) ;
483497 }
484498
485499 let reschedid = IntId :: sgi ( SGI_RESCHED . into ( ) ) ;
486- gic. set_interrupt_priority ( reschedid, Some ( cpu_id) , 0x01 ) ;
487- gic. enable_interrupt ( reschedid, Some ( cpu_id) , true ) ;
500+ gic. set_interrupt_priority ( reschedid, Some ( cpu_id) , 0x01 )
501+ . unwrap ( ) ;
502+ gic. enable_interrupt ( reschedid, Some ( cpu_id) , true ) . unwrap ( ) ;
488503 }
489504}
490505
0 commit comments