74: Update IME to be `u16` sized, avoid newtype_enum r=Lokathor a=Lokathor

newtype_enum makes an enum, but an enum can be UB if it's no a valid bit pattern. We should avoid having registers mapped to enum types.

Co-authored-by: Lokathor <zefria@gmail.com>
This commit is contained in:
bors[bot] 2019-02-15 05:17:51 +00:00
commit 629a85ccf5
3 changed files with 20 additions and 9 deletions

View file

@ -44,7 +44,7 @@ fn main(_argc: isize, _argv: *const *const u8) -> isize {
irq::set_irq_handler(irq_handler); irq::set_irq_handler(irq_handler);
// Enable all interrupts that are set in the IE register. // Enable all interrupts that are set in the IE register.
IME.write(IrqEnableSetting::UseIE); IME.write(IrqEnableSetting::IRQ_YES);
// Request that VBlank, HBlank and VCount will generate IRQs. // Request that VBlank, HBlank and VCount will generate IRQs.
const DISPLAY_SETTINGS: DisplayStatusSetting = DisplayStatusSetting::new() const DISPLAY_SETTINGS: DisplayStatusSetting = DisplayStatusSetting::new()

View file

@ -204,7 +204,7 @@ pub fn interrupt_wait(ignore_current_flags: bool, target_flags: IrqFlags) {
unsafe { unsafe {
asm!(/* ASM */ "swi 0x04" asm!(/* ASM */ "swi 0x04"
:/* OUT */ // none :/* OUT */ // none
:/* INP */ "{r0}"(ignore_current_flags), "{r1}"(target_flags.0) :/* INP */ "{r0}"(ignore_current_flags), "{r1}"(target_flags)
:/* CLO */ // none :/* CLO */ // none
:/* OPT */ "volatile" :/* OPT */ "volatile"
); );

View file

@ -102,7 +102,8 @@ use super::*;
newtype!( newtype!(
/// A newtype over all interrupt flags. /// A newtype over all interrupt flags.
IrqFlags, pub u16 IrqFlags,
u16
); );
impl IrqFlags { impl IrqFlags {
@ -140,13 +141,23 @@ pub const IE: VolAddress<IrqFlags> = unsafe { VolAddress::new(0x400_0200) };
/// when it is called. /// when it is called.
pub const IF: VolAddress<IrqFlags> = unsafe { VolAddress::new(0x400_0200) }; pub const IF: VolAddress<IrqFlags> = unsafe { VolAddress::new(0x400_0200) };
newtype_enum! { newtype! {
/// Setting to control whether interrupts are enabled. /// Setting to control whether interrupts are enabled.
IrqEnableSetting = u32, IrqEnableSetting, u16
/// Disable all interrupts. }
DisableAll = 0,
/// Enable interrupts according to the flags set in the [`IE`](irq::IE) register. impl IrqEnableSetting {
UseIE = 1, phantom_fields! {
self.0: u16,
/// System-wide control for if interrupts of all kinds are enabled or not.
interrupts_enabled: 0,
}
/// Yes, you want to have interrupts.
pub const IRQ_YES: Self = Self::new().with_interrupts_enabled(true);
/// No, please do not have interrupts.
pub const IRQ_NO: Self = Self::new();
} }
/// Interrupt Master Enable Register. Read/Write. /// Interrupt Master Enable Register. Read/Write.