33//! The official documentation: <https://developer.arm.com/documentation/ihi0048/latest/>
44
55use aarch64_cpu:: registers:: MPIDR_EL1 ;
6+ use log:: { debug, info, trace} ;
67use core:: hint:: spin_loop;
78use core:: ptr:: NonNull ;
89use tock_registers:: interfaces:: { Readable , Writeable } ;
@@ -250,13 +251,10 @@ impl GicDistributor {
250251 for i in ( IntId :: SPI_START ..self . support_irqs ) . step_by ( 32 ) {
251252 self . regs ( ) . ICACTIVER [ i / 32 ] . set ( u32:: MAX ) ;
252253 self . regs ( ) . ICENABLER [ i / 32 ] . set ( u32:: MAX ) ;
254+ self . regs ( ) . ICPENDR [ i / 32 ] . set ( u32:: MAX ) ;
253255 }
254256
255- // Enable affinity routing and group1
256- self . regs ( )
257- . CTLR
258- . set ( ( GicdCtlr :: ARE_S | GicdCtlr :: EnableGrp1NS ) . bits ( ) ) ;
259- self . wait_rwp ( ) ;
257+
260258
261259 // Set all global interrupts to current cpu.
262260 let mpidr: u64 = MPIDR_EL1 . get ( ) & 0xff00ffffff ;
@@ -270,6 +268,10 @@ impl GicDistributor {
270268 // Set external interrupts to target cpu 0
271269 self . regs ( ) . IROUTERnE [ i] . set ( Self :: mpidr_to_affinity_level ( mpidr) ) ;
272270 }
271+
272+ // Enable affinity routing and group1
273+ self . regs ( ) . CTLR . set ( ( GicdCtlr :: ARE_S | GicdCtlr :: EnableGrp1NS ) . bits ( ) ) ;
274+ self . wait_rwp ( ) ;
273275 }
274276
275277 /// Configures the trigger type for the interrupt with the given ID.
@@ -289,6 +291,31 @@ impl GicDistributor {
289291 }
290292}
291293
294+
295+ impl core:: ops:: Index < usize > for GicRedistributor {
296+ type Output = GicRedistributor ;
297+
298+ fn index ( & self , index : usize ) -> & Self :: Output {
299+ if index >= 9 {
300+ panic ! ( "GicRedistributor index out of range" ) ;
301+ }
302+ // SAFRTY: GicRedistributor has constructed with correct address,and we have checked the index
303+ unsafe { & * ( self as * const GicRedistributor ) . add ( index) }
304+ }
305+ }
306+
307+ use core:: arch:: asm;
308+ fn get_mpidr ( ) -> u64 {
309+ let mpidr: u64 ;
310+ unsafe {
311+ asm ! (
312+ "mrs {mpidr}, MPIDR_EL1" , // 从 MPIDR_EL1 读取
313+ mpidr = out( reg) mpidr
314+ ) ;
315+ }
316+ mpidr
317+ }
318+
292319impl GicRedistributor {
293320 /// Construct a new GIC Redistributor instance from the base address.
294321 pub const fn new ( base : * mut u8 ) -> Self {
@@ -300,6 +327,8 @@ impl GicRedistributor {
300327
301328 const fn gicr_regs ( & self ) -> & GicRedistributorRegs {
302329 unsafe { self . gicr_base . as_ref ( ) }
330+ // let current_cpu_id = (get_mpidr() >> 8) as usize;
331+ // unsafe {self[current_cpu_id]}
303332 }
304333
305334 const fn sgi_regs ( & self ) -> & GicSgiRegs {
@@ -312,21 +341,42 @@ impl GicRedistributor {
312341 }
313342 }
314343
344+ fn get_current_cpu_id ( & self ) -> usize {
345+ ( ( get_mpidr ( ) & 0xfff ) >> 8 ) as usize
346+ }
347+
348+ fn get_gicr_regs ( & self ) -> & GicRedistributorRegs {
349+ let mpidr = get_mpidr ( ) ;
350+ // unsafe {trace!("this is my cpu_id {:x} gicr {:?} mpidr {:x}",self.get_current_cpu_id(),self.gicr_base.as_ptr().byte_add(self.get_current_cpu_id() * 0x2_0000 ), mpidr);}
351+ unsafe { NonNull :: new ( self . gicr_base . as_ptr ( ) . byte_add ( self . get_current_cpu_id ( ) * 0x2_0000 ) ) . unwrap ( ) . cast ( ) . as_ref ( ) }
352+ }
353+
354+ fn get_sgi_regs ( & self ) -> & GicSgiRegs {
355+ // SAFETY: Writing to this system register doesn't access memory in any way
356+ unsafe {
357+ let gicr_addr = self . gicr_base . as_ptr ( ) . byte_add ( self . get_current_cpu_id ( ) * 0x2_0000 ) ;
358+ let sgi_base: NonNull < GicSgiRegs > =
359+ NonNull :: new ( gicr_addr. byte_add ( SGI_OFFSET ) ) . unwrap ( ) . cast ( ) ;
360+ sgi_base. as_ref ( )
361+
362+ }
363+ }
364+
315365 fn redis_enable ( & self ) {
316- let mut waker = self . gicr_regs ( ) . WAKER . get ( ) ;
366+ let mut waker = self . get_gicr_regs ( ) . WAKER . get ( ) ;
317367 // Wake up this CPU redistributor
318368 waker &= !( WakerFlags :: PROCESSOR_SLEEP . bits ( ) ) ;
319- self . gicr_regs ( ) . WAKER . set ( waker) ;
369+ self . get_gicr_regs ( ) . WAKER . set ( waker) ;
320370
321- while WakerFlags :: from_bits_truncate ( self . gicr_regs ( ) . WAKER . get ( ) )
371+ while WakerFlags :: from_bits_truncate ( self . get_gicr_regs ( ) . WAKER . get ( ) )
322372 . contains ( WakerFlags :: CHILDREN_ASLEEP )
323373 {
324374 spin_loop ( ) ;
325375 }
326376 }
327377
328378 fn base_init ( & mut self ) {
329- let typer = self . gicr_regs ( ) . TYPER . get ( ) as usize ;
379+ let typer = self . get_gicr_regs ( ) . TYPER . get ( ) as usize ;
330380 let mut ppinum = typer >> 27 & 0x1f ;
331381 ppinum = match ppinum {
332382 0 => 16 ,
@@ -338,23 +388,24 @@ impl GicRedistributor {
338388 }
339389
340390 fn init ( & mut self ) {
391+ // debug!("this is my gicr {:?}",self.gicr_base.as_ptr());
341392 self . base_init ( ) ;
342393 self . redis_enable ( ) ;
343394 // Configure SGIs/PPIs as non-secure Group-1
344395 for i in ( 0 ..self . support_ppi + 16 ) . step_by ( 32 ) {
345- self . sgi_regs ( ) . IGROUPR0 [ i / 32 ] . set ( u32:: MAX ) ;
396+ self . get_sgi_regs ( ) . IGROUPR0 [ i / 32 ] . set ( u32:: MAX ) ;
346397 }
347398
348399 // Deactivate and disable all private interrupts
349400 for i in ( 0 ..self . support_ppi + 16 ) . step_by ( 32 ) {
350- self . sgi_regs ( ) . ICACTIVER [ i / 32 ] . set ( u32:: MAX ) ;
351- self . sgi_regs ( ) . ICENABLER [ i / 32 ] . set ( u32:: MAX ) ;
401+ self . get_sgi_regs ( ) . ICACTIVER [ i / 32 ] . set ( u32:: MAX ) ;
402+ self . get_sgi_regs ( ) . ICENABLER [ i / 32 ] . set ( u32:: MAX ) ;
352403 }
353404
354405 // Set priority on private interrupts
355406 for i in ( 0 ..self . support_ppi + 16 ) . step_by ( 4 ) {
356407 // once time set 4 interrupts
357- self . sgi_regs ( ) . IPRIORITYR [ i / 4 ] . set ( 0xa0_a0_a0_a0 ) ;
408+ self . get_sgi_regs ( ) . IPRIORITYR [ i / 4 ] . set ( 0xa0_a0_a0_a0 ) ;
358409 }
359410 }
360411
@@ -365,13 +416,13 @@ impl GicRedistributor {
365416 let index = id >> 4 ;
366417 let bit_shift = ( ( id & 0xf ) << 1 ) + 1 ;
367418
368- let mut reg_val = self . sgi_regs ( ) . ICFGR [ index] . get ( ) ;
419+ let mut reg_val = self . get_sgi_regs ( ) . ICFGR [ index] . get ( ) ;
369420 match tm {
370421 TriggerMode :: Edge => reg_val |= 1 << bit_shift,
371422 TriggerMode :: Level => reg_val &= !( 1 << bit_shift) ,
372423 }
373424
374- self . sgi_regs ( ) . ICFGR [ index] . set ( reg_val) ;
425+ self . get_sgi_regs ( ) . ICFGR [ index] . set ( reg_val) ;
375426 }
376427}
377428
@@ -403,25 +454,31 @@ impl GicV3 {
403454 // SAFETY: Writing to this system register doesn't access memory in any way.
404455 unsafe {
405456 // Enable system register access.
406- write_sysreg ! ( icc_sre_el1 , 0x01 ) ;
457+ write_sysreg ! ( icc_sre_el2 , 0x01 ) ;
407458 }
408459
409460 unsafe {
410461 // Enable system register access.
411462 write_sysreg ! ( icc_pmr_el1, 0xf0 ) ;
412463 }
413-
414- // SAFETY: Writing to this system register doesn't access memory in any way.
415464 unsafe {
416- // Disable use of `ICC_PMR_EL1` as a hint for interrupt distribution, configure a write
417- // to an EOI register to also deactivate the interrupt, and configure preemption groups
418- // for group 0 and group 1 interrupts separately.
419- write_sysreg ! ( icc_ctlr_el1, 0x00 ) ;
465+ write_sysreg ! ( icc_bpr1_el1 , 0x0 ) ;
466+ }
467+ unsafe {
468+ write_sysreg ! ( icc_ctlr_el1, 0x02 ) ;
420469 }
421470
471+ // SAFETY: Writing to this system register doesn't access memory in any way.
472+ // unsafe {
473+ // // Disable use of `ICC_PMR_EL1` as a hint for interrupt distribution, configure a write
474+ // // to an EOI register to also deactivate the interrupt, and configure preemption groups
475+ // // for group 0 and group 1 interrupts separately.
476+ // write_sysreg!(icc_ctlr_el1, 0x00);
477+ // }
478+
422479 unsafe {
423480 // Enable non-secure group 1.
424- write_sysreg ! ( icc_igrpen1_el1, 0x00000001 ) ;
481+ write_sysreg ! ( icc_igrpen1_el1, 0x01 ) ;
425482 }
426483 }
427484}
@@ -442,9 +499,9 @@ impl GenericArmGic for GicV3 {
442499 fn enable_interrupt ( & mut self , intid : IntId ) {
443500 let index = intid. 0 / 32 ;
444501 let bit = 1 << ( intid. 0 % 32 ) ;
445-
502+ // let mpidr = get_mpidr();
446503 if intid. is_private ( ) {
447- self . gicr . sgi_regs ( ) . ISENABLER [ index] . set ( bit) ;
504+ self . gicr . get_sgi_regs ( ) . ISENABLER [ index] . set ( bit) ;
448505 } else {
449506 self . gicd . regs ( ) . ISENABLER [ index] . set ( bit) ;
450507 }
@@ -455,7 +512,7 @@ impl GenericArmGic for GicV3 {
455512 let bit = 1 << ( intid. 0 % 32 ) ;
456513
457514 if intid. is_private ( ) {
458- self . gicr . sgi_regs ( ) . ICENABLER [ index] . set ( bit) ;
515+ self . gicr . get_sgi_regs ( ) . ICENABLER [ index] . set ( bit) ;
459516 } else {
460517 self . gicd . regs ( ) . ICENABLER [ index] . set ( bit) ;
461518 }
@@ -488,5 +545,7 @@ impl GenericArmGic for GicV3 {
488545 fn end_interrupt ( & self , intid : IntId ) {
489546 // SAFETY: Writing to this system register doesn't access memory in any way.
490547 unsafe { write_sysreg ! ( icc_eoir1_el1, intid. 0 as u64 ) }
548+ unsafe { write_sysreg ! ( icc_dir_el1, intid. 0 as u64 ) }
491549 }
492550}
551+
0 commit comments