Commit 08b64b12 authored by Stefan Lankes's avatar Stefan Lankes
Browse files

use rustfmt to format the source code

parent 6d5d6e80
DisableFormat: true
-Ihermit/include
-Ihermit/arch/x86/include
-Ihermit/lwip/src/include
-Ihermit/lwip/src/include/ipv4
-Ihermit/drivers
-nostdinc
-ffreestanding
hard_tabs = true
......@@ -12,7 +12,10 @@ fn main() {
let _ = Command::new("pci_ids_parser").args(&["src/arch/x86_64/kernel/pci.ids", "src/arch/x86_64/kernel/pci_ids.rs"]).output().unwrap();*/
// determine git revision
let output = Command::new("git").args(&["rev-parse", "HEAD"]).output().unwrap();
let output = Command::new("git")
.args(&["rev-parse", "HEAD"])
.output()
.unwrap();
let git_hash = String::from_utf8(output.stdout).unwrap();
println!("cargo:rustc-env=GIT_HASH={}", git_hash);
}
\ No newline at end of file
}
use std::f64::consts::PI;
use std::thread;
use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::thread;
type Result<T> = std::result::Result<T, ()>;
......@@ -10,7 +10,7 @@ fn pi_sequential(num_steps: u64) -> Result<()> {
let step = 1.0 / num_steps as f64;
let mut sum = 0 as f64;
for i in 0..num_steps {
for i in 0..num_steps {
let x = (i as f64 + 0.5) * step;
sum += 4.0 / (1.0 + x * x);
}
......@@ -30,20 +30,21 @@ fn pi_parallel(nthreads: u64, num_steps: u64) -> Result<()> {
let mut sum = 0.0 as f64;
let threads: Vec<_> = (0..nthreads)
.map(|tid| {
thread::spawn(move || {
let mut partial_sum = 0 as f64;
let start = (num_steps / nthreads) * tid;
let end = (num_steps / nthreads) * (tid+1);
for i in start..end {
let x = (i as f64 + 0.5) * step;
partial_sum += 4.0 / (1.0 + x * x);
}
partial_sum
.map(|tid| {
thread::spawn(move || {
let mut partial_sum = 0 as f64;
let start = (num_steps / nthreads) * tid;
let end = (num_steps / nthreads) * (tid + 1);
for i in start..end {
let x = (i as f64 + 0.5) * step;
partial_sum += 4.0 / (1.0 + x * x);
}
partial_sum
})
})
}).collect();
.collect();
for t in threads {
sum += t.join().unwrap();
......@@ -114,15 +115,35 @@ fn threading() -> Result<()> {
fn test_result(result: Result<()>) -> &'static str {
match result {
Ok(_) => "ok",
Err(_) => "failed!"
Err(_) => "failed!",
}
}
fn main() {
println!("Test {} ... {}", stringify!(hello), test_result(hello()));
println!("Test {} ... {}", stringify!(read_file), test_result(read_file()));
println!("Test {} ... {}", stringify!(create_file), test_result(create_file()));
println!("Test {} ... {}", stringify!(threading), test_result(threading()));
println!("Test {} ... {}", stringify!(pi_sequential), test_result(pi_sequential(50000000)));
println!("Test {} ... {}", stringify!(pi_parallel), test_result(pi_parallel(2, 50000000)));
println!(
"Test {} ... {}",
stringify!(read_file),
test_result(read_file())
);
println!(
"Test {} ... {}",
stringify!(create_file),
test_result(create_file())
);
println!(
"Test {} ... {}",
stringify!(threading),
test_result(threading())
);
println!(
"Test {} ... {}",
stringify!(pi_sequential),
test_result(pi_sequential(50000000))
);
println!(
"Test {} ... {}",
stringify!(pi_parallel),
test_result(pi_parallel(2, 50000000))
);
}
......@@ -12,7 +12,9 @@ const IRQ_FLAG_A: usize = 1 << 8;
/// Enable Interrupts
#[inline]
pub fn enable() {
unsafe { asm!("msr daifclr, 0b111" ::: "memory" : "volatile"); }
unsafe {
asm!("msr daifclr, 0b111" ::: "memory" : "volatile");
}
}
/// Enable Interrupts and wait for the next interrupt (HLT instruction)
......@@ -28,7 +30,9 @@ pub fn enable_and_wait() {
/// Disable Interrupts
#[inline]
pub fn disable() {
unsafe { asm!("msr daifset, 0b111" ::: "memory" : "volatile"); }
unsafe {
asm!("msr daifset, 0b111" ::: "memory" : "volatile");
}
}
/// Disable IRQs (nested)
......@@ -40,7 +44,9 @@ pub fn disable() {
#[inline]
pub fn nested_disable() -> bool {
let flags: usize;
unsafe { asm!("mrs $0, daif" : "=r"(flags) :: "memory" : "volatile"); }
unsafe {
asm!("mrs $0, daif" : "=r"(flags) :: "memory" : "volatile");
}
let mut was_enabled = true;
if flags & (IRQ_FLAG_A | IRQ_FLAG_I | IRQ_FLAG_F) > 0 {
......@@ -63,8 +69,7 @@ pub fn nested_enable(was_enabled: bool) {
}
#[no_mangle]
pub extern "C" fn irq_install_handler(irq_number: u32, handler: usize)
{
pub extern "C" fn irq_install_handler(irq_number: u32, handler: usize) {
info!("Install handler for interrupt {}", irq_number);
// TODO
}
......@@ -13,13 +13,13 @@ pub mod percore;
pub mod processor;
pub mod scheduler;
pub mod serial;
pub mod systemtime;
pub mod stubs;
pub mod systemtime;
pub use arch::aarch64::kernel::stubs::*;
pub use arch::aarch64::kernel::systemtime::get_boot_time;
use arch::aarch64::kernel::percore::*;
use arch::aarch64::kernel::serial::SerialPort;
pub use arch::aarch64::kernel::stubs::*;
pub use arch::aarch64::kernel::systemtime::get_boot_time;
use core::ptr;
use environment;
use kernel_message_buffer;
......@@ -28,8 +28,7 @@ use synch::spinlock::Spinlock;
const SERIAL_PORT_BAUDRATE: u32 = 115200;
lazy_static! {
static ref COM1: SerialPort =
SerialPort::new(unsafe { KERNEL_HEADER.uartport });
static ref COM1: SerialPort = SerialPort::new(unsafe { KERNEL_HEADER.uartport });
static ref CPU_ONLINE: Spinlock<&'static mut u32> =
Spinlock::new(unsafe { &mut KERNEL_HEADER.cpu_online });
}
......@@ -59,7 +58,7 @@ struct KernelHeader {
hcip: [u8; 4],
hcgateway: [u8; 4],
hcmask: [u8; 4],
boot_stack: [u8; KERNEL_STACK_SIZE]
boot_stack: [u8; KERNEL_STACK_SIZE],
}
/// Kernel header to announce machine features
......@@ -82,13 +81,13 @@ static mut KERNEL_HEADER: KernelHeader = KernelHeader {
cpu_online: 0,
possible_cpus: 0,
current_boot_id: 0,
uartport: 0x9000000, // Initialize with QEMU's UART address
uartport: 0x9000000, // Initialize with QEMU's UART address
single_kernel: 1,
uhyve: 0,
hcip: [10,0,5,2],
hcgateway: [10,0,5,1],
hcmask: [255,255,255,0],
boot_stack: [0xCD; KERNEL_STACK_SIZE]
hcip: [10, 0, 5, 2],
hcgateway: [10, 0, 5, 1],
hcmask: [255, 255, 255, 0],
boot_stack: [0xCD; KERNEL_STACK_SIZE],
};
// FUNCTIONS
......@@ -127,7 +126,6 @@ pub fn get_cmdline() -> usize {
unsafe { ptr::read_volatile(&KERNEL_HEADER.cmdline) as usize }
}
/// Earliest initialization function called by the Boot Processor.
pub fn message_output_init() {
percore::init();
......@@ -204,7 +202,10 @@ pub fn boot_processor_init() {
// Enable PMCCNTR_EL0 using PMCR_EL0.
let mut pmcr_el0: u32 = 0;
asm!("mrs $0, pmcr_el0" : "=r"(pmcr_el0) :: "memory" : "volatile");
debug!("PMCR_EL0 (has RES1 bits and therefore musn't be zero): {:#X}", pmcr_el0);
debug!(
"PMCR_EL0 (has RES1 bits and therefore musn't be zero): {:#X}",
pmcr_el0
);
pmcr_el0 |= 1 << 0 | 1 << 2 | 1 << 6;
asm!("msr pmcr_el0, $0" :: "r"(pmcr_el0) :: "volatile");
}
......
......@@ -11,7 +11,6 @@ use scheduler::PerCoreScheduler;
#[no_mangle]
pub static mut PERCORE: PerCoreVariables = PerCoreVariables::new(0);
pub struct PerCoreVariables {
/// APIC ID of this CPU Core.
core_id: PerCoreVariable<usize>,
......@@ -28,7 +27,6 @@ impl PerCoreVariables {
}
}
#[repr(C)]
pub struct PerCoreVariable<T> {
data: T,
......@@ -48,7 +46,10 @@ impl<T> PerCoreVariable<T> {
// Treat all per-core variables as 64-bit variables by default. This is true for u64, usize, pointers.
// Implement the PerCoreVariableMethods trait functions using 64-bit memory moves.
// The functions are implemented as default functions, which can be overriden in specialized implementations of the trait.
impl<T> PerCoreVariableMethods<T> for PerCoreVariable<T> where T: Clone {
impl<T> PerCoreVariableMethods<T> for PerCoreVariable<T>
where
T: Clone,
{
#[inline]
default unsafe fn get(&self) -> T {
self.data.clone()
......@@ -60,7 +61,6 @@ impl<T> PerCoreVariableMethods<T> for PerCoreVariable<T> where T: Clone {
}
}
#[inline]
pub fn core_id() -> usize {
unsafe { PERCORE.core_id.get() }
......@@ -73,7 +73,9 @@ pub fn core_scheduler() -> &'static mut PerCoreScheduler {
#[inline]
pub fn set_core_scheduler(scheduler: *mut PerCoreScheduler) {
unsafe { PERCORE.scheduler.set(scheduler); }
unsafe {
PERCORE.scheduler.set(scheduler);
}
}
pub fn init() {
......
......@@ -11,7 +11,6 @@ extern "C" {
static mut cpu_freq: u32;
}
pub struct FPUState {
// TODO
}
......@@ -30,7 +29,6 @@ impl FPUState {
}
}
pub fn generate_random_number() -> Option<u32> {
None
}
......@@ -41,7 +39,9 @@ pub fn msb(value: u64) -> Option<u64> {
if value > 0 {
let ret: u64;
let u64_bits = 64;
unsafe { asm!("clz $0, $1; sub $0, $2, $0" : "=r"(ret) : "r"(value), "r"(u64_bits - 1) : "cc" : "volatile"); }
unsafe {
asm!("clz $0, $1; sub $0, $2, $0" : "=r"(ret) : "r"(value), "r"(u64_bits - 1) : "cc" : "volatile");
}
Some(ret)
} else {
None
......
......@@ -69,7 +69,6 @@ impl Drop for TaskStacks {
}
}
extern "C" fn leave_task() -> ! {
core_scheduler().exit(0);
}
......@@ -90,7 +89,11 @@ extern "C" fn task_entry(func: extern "C" fn(usize), arg: usize) {
// Associate the TLS memory to the current task.
let mut current_task_borrowed = core_scheduler().current_task.borrow_mut();
debug!("Set up TLS for task {} at address {:#X}", current_task_borrowed.id, tls.address());
debug!(
"Set up TLS for task {} at address {:#X}",
current_task_borrowed.id,
tls.address()
);
current_task_borrowed.tls = Some(Rc::new(RefCell::new(tls)));
}
......
......@@ -7,14 +7,15 @@
use core::ptr;
pub struct SerialPort {
port_address: u32
port_address: u32,
}
impl SerialPort {
pub const fn new(port_address: u32) -> Self {
Self { port_address: port_address }
Self {
port_address: port_address,
}
}
pub fn write_byte(&self, byte: u8) {
......@@ -22,10 +23,14 @@ impl SerialPort {
// LF newline characters need to be extended to CRLF over a real serial port.
if byte == b'\n' {
unsafe { ptr::write_volatile(port, b'\r'); }
unsafe {
ptr::write_volatile(port, b'\r');
}
}
unsafe { ptr::write_volatile(port, byte); }
unsafe {
ptr::write_volatile(port, byte);
}
}
pub fn init(&self, baudrate: u32) {
......
......@@ -16,49 +16,37 @@ pub fn wakeup_core(core_to_wakeup: usize) {
}
#[no_mangle]
pub extern "C" fn do_bad_mode() {
}
pub extern "C" fn do_bad_mode() {}
#[no_mangle]
pub extern "C" fn do_error() {
}
pub extern "C" fn do_error() {}
#[no_mangle]
pub extern "C" fn do_fiq() {
}
pub extern "C" fn do_fiq() {}
#[no_mangle]
pub extern "C" fn do_irq() {
}
pub extern "C" fn do_irq() {}
#[no_mangle]
pub extern "C" fn do_sync() {
}
pub extern "C" fn do_sync() {}
#[no_mangle]
pub extern "C" fn eoi() {
}
pub extern "C" fn eoi() {}
#[no_mangle]
pub extern "C" fn finish_task_switch() {
}
pub extern "C" fn finish_task_switch() {}
#[no_mangle]
pub extern "C" fn getcontext() {
}
pub extern "C" fn getcontext() {}
#[no_mangle]
pub extern "C" fn get_current_stack() {
}
pub extern "C" fn get_current_stack() {}
#[no_mangle]
pub extern "C" fn makecontext() {
}
pub extern "C" fn makecontext() {}
#[no_mangle]
pub extern "C" fn setcontext() {
}
pub extern "C" fn setcontext() {}
#[no_mangle]
pub extern "C" fn switch(_old_stack: *mut usize, _new_stack: usize) {
}
pub extern "C" fn switch(_old_stack: *mut usize, _new_stack: usize) {}
......@@ -5,22 +5,20 @@
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
use arch::aarch64::mm::physicalmem;
use arch::aarch64::mm::virtualmem;
use arch::aarch64::kernel::percore::*;
use arch::aarch64::kernel::processor;
use core::{fmt, ptr, usize};
use arch::aarch64::mm::physicalmem;
use arch::aarch64::mm::virtualmem;
use core::marker::PhantomData;
use core::{fmt, ptr, usize};
use mm;
use scheduler;
extern "C" {
#[linkage = "extern_weak"]
static runtime_osinit: *const u8;
}
/// Pointer to the root page table (called "Level 0" in ARM terminology).
/// Setting the upper bits to zero tells the MMU to use TTBR0 for the base address for the first table.
///
......@@ -36,7 +34,6 @@ const PAGE_MAP_BITS: usize = 9;
/// A mask where PAGE_MAP_BITS are set to calculate a table index.
const PAGE_MAP_MASK: usize = 0x1FF;
bitflags! {
/// Useful flags for an entry in either table (L0Table, L1Table, L2Table, L3Table).
///
......@@ -77,7 +74,7 @@ bitflags! {
/// Set if code execution shall be disabled for memory referenced by this entry in unprivileged mode.
const UNPRIVILEGED_EXECUTE_NEVER = 1 << 54;
}
}
}
impl PageTableEntryFlags {
......@@ -112,12 +109,11 @@ impl PageTableEntryFlags {
}
}
/// An entry in either table
#[derive(Clone, Copy)]
pub struct PageTableEntry {
/// Physical memory address this entry refers, combined with flags from PageTableEntryFlags.
physical_address_and_flags: usize
physical_address_and_flags: usize,
}
impl PageTableEntry {
......@@ -139,7 +135,11 @@ impl PageTableEntry {
/// * `flags` - Flags from PageTableEntryFlags (note that the PRESENT, INNER_SHAREABLE, and ACCESSED flags are set automatically)
fn set(&mut self, physical_address: usize, flags: PageTableEntryFlags) {
// Verify that the offset bits for a 4 KiB page are zero.
assert!(physical_address % BasePageSize::SIZE == 0, "Physical address is not on a 4 KiB page boundary (physical_address = {:#X})", physical_address);
assert!(
physical_address % BasePageSize::SIZE == 0,
"Physical address is not on a 4 KiB page boundary (physical_address = {:#X})",
physical_address
);
let mut flags_to_set = flags;
flags_to_set.insert(PageTableEntryFlags::PRESENT);
......@@ -215,7 +215,9 @@ impl<S: PageSize> Page<S> {
//
// We use "vale1is" instead of "vae1is" to always flush the last table level only (performance optimization).
// The "is" attribute broadcasts the TLB flush to all cores, so we don't need an IPI (unlike x86_64).
unsafe { asm!("dsb ishst; tlbi vale1is, $0; dsb ish; isb" :: "r"(self.virtual_address) : "memory" : "volatile"); }
unsafe {
asm!("dsb ishst; tlbi vale1is, $0; dsb ish; isb" :: "r"(self.virtual_address) : "memory" : "volatile");
}
}
/// Returns whether the given virtual address is a valid one in the AArch64 memory model.
......@@ -230,7 +232,11 @@ impl<S: PageSize> Page<S> {
/// Returns a Page including the given virtual address.
/// That means, the address is rounded down to a page size boundary.
fn including_address(virtual_address: usize) -> Self {
assert!(Self::is_valid_address(virtual_address), "Virtual address {:#X} is invalid", virtual_address);
assert!(
Self::is_valid_address(virtual_address),
"Virtual address {:#X} is invalid",
virtual_address
);
Self {
virtual_address: align_down!(virtual_address, S::SIZE),
......@@ -241,7 +247,10 @@ impl<S: PageSize> Page<S> {
/// Returns a PageIter to iterate from the given first Page to the given last Page (inclusive).
fn range(first: Self, last: Self) -> PageIter<S> {
assert!(first.virtual_address <= last.virtual_address);
PageIter { current: first, last: last }
PageIter {
current: first,
last: last,
}
}
/// Returns the index of this page in the table given by L.
......@@ -338,15 +347,30 @@ struct PageTable<L> {
/// implementation of some methods.
trait PageTableMethods {
fn get_page_table_entry<S: PageSize>(&self, page: Page<S>) -> Option<PageTableEntry>;
fn map_page_in_this_table<S: PageSize>(&mut self, page: Page<S>, physical_address: usize, flags: PageTableEntryFlags);
fn map_page<S: PageSize>(&mut self, page: Page<S>, physical_address: usize, flags: PageTableEntryFlags);
fn map_page_in_this_table<S: PageSize>(
&mut self,
page: Page<S>,
physical_address: usize,
flags: PageTableEntryFlags,
);
fn map_page<S: PageSize>(
&mut self,
page: Page<S>,
physical_address: usize,
flags: PageTableEntryFlags,
);
}
impl<L: PageTableLevel> PageTableMethods for PageTable<L> {
/// Maps a single page in this table to the given physical address.
///
/// Must only be called if a page of this size is mapped at this page table level!
fn map_page_in_this_table<S: PageSize>(&mut self, page: Page<S>, physical_address: usize, flags: PageTableEntryFlags) {
fn map_page_in_this_table<S: PageSize>(
&mut self,
page: Page<S>,
physical_address: usize,
flags: PageTableEntryFlags,
) {
assert!(L::LEVEL == S::MAP_LEVEL);
let index = page.table_index::<L>();
let flush = self.entries[index].is_present();
......@@ -377,12 +401,20 @@ impl<L: PageTableLevel> PageTableMethods for PageTable<L> {
///
/// This is the default implementation that just calls the map_page_in_this_table method.
/// It is overridden by a specialized implementation for all tables with sub tables (all except L3Table).
default fn map_page<S: PageSize>(&mut self, page: Page<S>, physical_address: usize, flags: PageTableEntryFlags) {
default fn map_page<S: PageSize>(
&mut self,
page: Page<S>,
physical_address: usize,
flags: PageTableEntryFlags,
) {
self.map_page_in_this_table::<S>(page, physical_address, flags)
}
}
impl<L: PageTableLevelWithSubtables> PageTableMethods for PageTable<L> where L::SubtableLevel: PageTableLevel {
impl<L: PageTableLevelWithSubtables> PageTableMethods for PageTable<L>
where
L::SubtableLevel: PageTableLevel,
{
/// Returns the PageTableEntry for the given page if it is present, otherwise returns None.
///
/// This is the implementation for all tables with subtables (L0Table, L1Table, L2Table).
......@@ -407,7 +439,12 @@ impl<L: PageTableLevelWithSubtables> PageTableMethods for PageTable<L> where L::
///
/// This is the implementation for all tables with subtables (L0Table, L1Table, L2Table).
/// It overrides the default implementation above.
fn map_page<S: PageSize>(&mut self, page: Page<S>, physical_address: usize, flags: PageTableEntryFlags) {
fn map_page<S: PageSize>(
&mut self,
page: Page<S>,
physical_address: usize,
flags: PageTableEntryFlags,
) {
assert!(L::LEVEL <= S::MAP_LEVEL);
if L::LEVEL < S::MAP_LEVEL {
......@@ -417,7 +454,10 @@ impl<L: PageTableLevelWithSubtables> PageTableMethods for PageTable<L> where L::
if !self.entries[index].is_present() {
// Allocate a single 4 KiB page for the new entry and mark it as a valid, writable subtable.
let physical_address = physicalmem::allocate(BasePageSize::SIZE);
self.entries[index].set(physical_address, PageTableEntryFlags::NORMAL | PageTableEntryFlags::TABLE_OR_4KIB_PAGE);
self.entries[index].set(
physical_address,
PageTableEntryFlags::NORMAL | PageTableEntryFlags::TABLE_OR_4KIB_PAGE,
);
// Mark all entries as unused in the newly created table.
let subtable = self.subtable::<S>(page);
......@@ -436,7 +476,10 @@ impl<L: PageTableLevelWithSubtables> PageTableMethods for PageTable<L> where L::
}
}
impl<L: PageTableLevelWithSubtables> PageTable<L> where L::SubtableLevel: PageTableLevel {
impl<L: PageTableLevelWithSubtables> PageTable<L>