Skip to content

Commit

Permalink
updated lab6
Browse files Browse the repository at this point in the history
  • Loading branch information
2X-ercha committed Apr 25, 2022
1 parent 21c15bc commit 0b3759b
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 19 deletions.
22 changes: 11 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
[package]
name = "rui_armv8_os"
name = "blogos_armv8"
version = "0.1.0"
edition = "2021"
authors = ["Rui Li <rui@hnu.edu.cn>"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ https://os2022exps-doc.readthedocs.io/zh_CN/latest/index.html

4. [Lab5: 输入 - https://github.com/2X-ercha/blogOS-armV8/tree/lab5](https://github.com/2X-ercha/blogOS-armV8/tree/lab5)

4. [Lab6: GPIO关机 - https://github.com/2X-ercha/blogOS-armV8/tree/lab6](https://github.com/2X-ercha/blogOS-armV8/tree/lab6)

--------

## 实验环境
Expand Down Expand Up @@ -81,7 +83,7 @@ rm -rf gcc-arm-10*

```bash
cargo build
qemu-system-aarch64 -machine virt -m 1024M -cpu cortex-a53 -nographic -kernel target/aarch64-unknown-none-softfloat/debug/rui_armv8_os
qemu-system-aarch64 -machine virt,gic-version=2 -cpu cortex-a57 -nographic -kernel target/aarch64-unknown-none-softfloat/debug/blogos_armv8 -semihosting
```

如果你要进行`gdb`调试,可以在运行指令最后加上`-S -s`,默认端口为`1234`
Expand Down
45 changes: 40 additions & 5 deletions src/interrupts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ use core::ptr;
use core::arch::asm;
use core::arch::global_asm;

use tock_registers::interfaces::Readable;

/*
GIC 部分的设备树描述:
Expand Down Expand Up @@ -81,6 +79,10 @@ const ICFGR_LEVEL: u32 = 0;
const TIMER_IRQ: u32 = 30;
// 设备中断号33
const UART0_IRQ: u32 = 33;
// GPIO中断号39
const GPIO_IRQ: u32 = 39;

use tock_registers::interfaces::{Readable, Writeable};

static mut RUN_TIME: u32 = 0;

Expand Down Expand Up @@ -161,6 +163,23 @@ pub fn init_gicv2() {
// set_core(TIMER_IRQ, 0x1); // 单核实现无需设置中断目标核
clear(UART0_IRQ); //清除中断请求
enable(UART0_IRQ); //使能中断

// 初始化GPIO中断
set_config(GPIO_IRQ, ICFGR_LEVEL); //电平触发
set_priority(GPIO_IRQ, 0); //优先级设定
clear(GPIO_IRQ); //清除中断请求
enable(GPIO_IRQ); //使能中断

// 使能GPIO的poweroff key中断
use crate::pl061::*;
unsafe{
let pl061r: &PL061Regs = &*PL061REGS;

// 启用pl061 gpio中的3号线中断
// .write(): 写入一个或多个字段的值,将其他字段改写为零
pl061r.ie.write(GPIOIE::IO3::Enabled);

}
}

// 使能中断号为interrupt的中断
Expand Down Expand Up @@ -338,12 +357,13 @@ unsafe extern "C" fn el0_32_error(ctx: &mut ExceptionCtx) {
}

fn handle_irq_lines(ctx: &mut ExceptionCtx, _core_num: u32, irq_num: u32) {

if irq_num == TIMER_IRQ {
handle_timer_irq(ctx);
}else if irq_num == UART0_IRQ {
} else if irq_num == UART0_IRQ {
handle_uart0_rx_irq(ctx);
}else{
} else if irq_num == GPIO_IRQ {
handle_gpio_irq(ctx);
} else{
catch(ctx, EL1_IRQ);
}
}
Expand Down Expand Up @@ -389,3 +409,18 @@ fn handle_uart0_rx_irq(_ctx: &mut ExceptionCtx){
}
}
}

fn handle_gpio_irq(_ctx: &mut ExceptionCtx){
use crate::pl061::*;
crate::println!("power off!\n");
unsafe {
let pl061r: &PL061Regs = &*PL061REGS;

// 清除中断信号 此时get到的应该是0x8
// .set(): 设置原始寄存器值; .get(): 获取原始寄存器值
pl061r.ic.set(pl061r.ie.get());
// 关机
asm!("mov w0, #0x18");
asm!("hlt #0xF000");
}
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
mod panic;
mod uart_console;
mod interrupts;
mod pl061;

global_asm!(include_str!("start.s"));

Expand Down
33 changes: 33 additions & 0 deletions src/pl061.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use tock_registers::{registers::{ReadWrite, WriteOnly}, register_bitfields, register_structs};

pub const PL061REGS: *mut PL061Regs = (0x0903_0000) as *mut PL061Regs;

// https://developer.arm.com/documentation/ddi0190/b/programmer-s-model/summary-of-primecell-gpio-registers

register_bitfields![
u32,

// PrimeCell GPIO interrupt mask
pub GPIOIE [
IO3 OFFSET(3) NUMBITS(1) [
Disabled = 0,
Enabled = 1
]
],

// PrimeCell GPIO raw interrupt status, when system_powerdown, this reg: 0x00 -> 0x08
// pub GPIORIS [],

// PrimeCell GPIO interrupt clear
// pub GPIOIC []
];

register_structs! {
pub PL061Regs {
(0x000 => __reserved_0),
(0x410 => pub ie: ReadWrite<u32, GPIOIE::Register>),
(0x414 => __reserved_1),
(0x41c => pub ic: WriteOnly<u32>),
(0x420 => @END),
}
}

0 comments on commit 0b3759b

Please sign in to comment.