Skip to content

Commit 7710bea

Browse files
committed
should work
1 parent 4a906a2 commit 7710bea

File tree

37 files changed

+1552
-785
lines changed

37 files changed

+1552
-785
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[workspace]
22
members = ["examples/*", "xtasks", "xtasks/crates/*"]
3+
default-members = ["."]
34

45
[workspace.dependencies]
56
interface = { path = "interface" }

machine/api/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ pub trait Machinelike {
4747
fn bench_start();
4848
fn bench_end() -> (u32, f32);
4949

50+
fn monotonic_now() -> u64;
51+
fn monotonic_freq() -> u64;
52+
// Returns the frequency of the machine's systick timer in Hz.
53+
fn systick_freq() -> u64;
54+
5055
type ExcepBacktrace: Display;
5156
type ExcepStackFrame: Display;
5257
fn backtrace(initial_fp: *const usize, stack_ptr: *const usize) -> Self::ExcepBacktrace;

machine/api/src/mem.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use core::ops::{Add, Sub, Div, Rem};
1+
use core::{fmt::Display, ops::{Add, Div, Rem, Sub}, ptr::NonNull};
22

33
#[repr(transparent)]
4-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
4+
#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
55
pub struct PhysAddr(usize);
66

77
impl PhysAddr {
@@ -32,6 +32,29 @@ impl PhysAddr {
3232
pub fn is_multiple_of(&self, align: usize) -> bool {
3333
self.0.is_multiple_of(align)
3434
}
35+
36+
pub fn diff(&self, other: Self) -> usize {
37+
if self.0 >= other.0 {
38+
// Cannot underflow because of the check above.
39+
self.0.checked_sub(other.0).unwrap()
40+
} else {
41+
// Cannot underflow because of the check above.
42+
other.0.checked_sub(self.0).unwrap()
43+
}
44+
}
45+
}
46+
47+
impl<T> From<NonNull<T>> for PhysAddr {
48+
#[inline]
49+
fn from(ptr: NonNull<T>) -> Self {
50+
Self(ptr.as_ptr() as usize)
51+
}
52+
}
53+
54+
impl Display for PhysAddr {
55+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
56+
write!(f, "0x{:x}", self.0)
57+
}
3558
}
3659

3760
impl Add<usize> for PhysAddr {

machine/arm/common/CMakeLists.txt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,8 @@ foreach(var ${_cache_vars})
2828
endif()
2929
endforeach()
3030
31-
# This sets up PIC for .data/.bss access by making all accesses relative to r9.
32-
# r9 is initialized in crt0.S to point to the base of the .data section.
33-
# We need this because the offset between .text and .data is not known at compile time. (relocatable)
34-
add_compile_options(-msingle-pic-base -mpic-register=r9 -mno-pic-data-is-text-relative)
35-
3631
set_property(SOURCE ivt.S APPEND PROPERTY COMPILE_OPTIONS "-x" "assembler-with-cpp")
3732
set_property(SOURCE irq.S APPEND PROPERTY COMPILE_OPTIONS "-x" "assembler-with-cpp")
38-
set_property(SOURCE crt0.S APPEND PROPERTY COMPILE_OPTIONS "-fno-pic")
3933
4034
add_library(common STATIC
4135
ivt.S

machine/arm/common/crt0.S

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,6 @@
1010
.thumb_func
1111
.global bootstrap
1212
bootstrap:
13-
/*
14-
* Initialize r9 to point to the start of the .data section.
15-
* This is needed because all .data/.bss accesses are relative to r9.
16-
* We need this because the offset between .text and .data is not known at compile time (relocatable).
17-
*/
18-
ldr r9, =__data_start
19-
2013
@ Copy initialized data from flash to RAM.
2114
ldr r0, =__data
2215
ldr r1, =__data_start

machine/arm/src/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,18 @@ impl hal_api::Machinelike for ArmMachine {
6565
(cycles as u32, ns)
6666
}
6767

68+
fn monotonic_now() -> u64 {
69+
unsafe { bindings::monotonic_now() }
70+
}
71+
72+
fn monotonic_freq() -> u64 {
73+
unsafe { bindings::monotonic_freq() }
74+
}
75+
76+
fn systick_freq() -> u64 {
77+
unsafe { bindings::systick_freq() }
78+
}
79+
6880
type ExcepBacktrace = excep::ExcepBacktrace;
6981
type ExcepStackFrame = excep::ExcepStackFrame;
7082

machine/arm/stm32l4xx/CMakeLists.txt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,6 @@ foreach(var ${_cache_vars})
3030
endif()
3131
endforeach()
3232
33-
# This sets up PIC for .data/.bss access by making all accesses relative to r9.
34-
# r9 is initialized in crt0.S to point to the base of the .data section.
35-
# We need this because the offset between .text and .data is not known at compile time. (relocatable)
36-
add_compile_options(-msingle-pic-base -mpic-register=r9 -mno-pic-data-is-text-relative)
37-
3833
# this will compile our variant_stm32l4xx library
3934
add_subdirectory(${OSIRIS_ARM_STM32L4XX_VARIANT})
4035
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#include "lib.h"
2+
#include <stm32l4xx_hal.h>
3+
4+
static volatile uint64_t monotonic_hi = 0;
5+
6+
static void init_monotonic_timer(void)
7+
{
8+
const uint32_t target_hz = 1000000U;
9+
uint32_t tim_clk = HAL_RCC_GetPCLK1Freq();
10+
11+
monotonic_hi = 0;
12+
13+
// If APB1 prescaler is not 1, timer clocks run at 2x PCLK1.
14+
if ((RCC->CFGR & RCC_CFGR_PPRE1) != RCC_CFGR_PPRE1_DIV1) {
15+
tim_clk *= 2U;
16+
}
17+
18+
const uint32_t prescaler = (tim_clk / target_hz) - 1U;
19+
20+
__HAL_RCC_TIM2_CLK_ENABLE();
21+
__HAL_RCC_TIM2_FORCE_RESET();
22+
__HAL_RCC_TIM2_RELEASE_RESET();
23+
24+
HAL_NVIC_DisableIRQ(TIM2_IRQn);
25+
NVIC_ClearPendingIRQ(TIM2_IRQn);
26+
27+
// URS ensures update flags/interrupts are only from real overflows.
28+
TIM2->CR1 = TIM_CR1_URS;
29+
TIM2->PSC = prescaler;
30+
TIM2->ARR = 0xFFFFFFFFU;
31+
TIM2->CNT = 0;
32+
TIM2->EGR = TIM_EGR_UG;
33+
34+
// Clear pending flags and enable update interrupt for wrap extension.
35+
TIM2->SR = 0;
36+
TIM2->DIER = TIM_DIER_UIE;
37+
38+
HAL_NVIC_SetPriority(TIM2_IRQn, 15, 0);
39+
HAL_NVIC_EnableIRQ(TIM2_IRQn);
40+
41+
TIM2->CR1 |= TIM_CR1_CEN;
42+
43+
// Clear any latent startup update state before first read.
44+
TIM2->SR = 0;
45+
NVIC_ClearPendingIRQ(TIM2_IRQn);
46+
}
47+
48+
void tim2_hndlr(void)
49+
{
50+
if ((TIM2->SR & TIM_SR_UIF) != 0U) {
51+
TIM2->SR &= ~TIM_SR_UIF;
52+
monotonic_hi += (1ULL << 32);
53+
}
54+
}
55+
56+
void SystemClock_Config(void)
57+
{
58+
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
59+
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
60+
61+
/* 80 MHz on STM32L4+ => Range 1 normal mode, not boost */
62+
__HAL_RCC_PWR_CLK_ENABLE();
63+
64+
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) {
65+
while (1) {}
66+
}
67+
68+
/* HSI16 -> PLL -> 80 MHz SYSCLK */
69+
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
70+
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
71+
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
72+
73+
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
74+
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
75+
RCC_OscInitStruct.PLL.PLLM = 1;
76+
RCC_OscInitStruct.PLL.PLLN = 10;
77+
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
78+
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7; // arbitrary unless you use PLLP
79+
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; // arbitrary unless you use PLLQ
80+
81+
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
82+
while (1) {}
83+
}
84+
85+
RCC_ClkInitStruct.ClockType =
86+
RCC_CLOCKTYPE_SYSCLK |
87+
RCC_CLOCKTYPE_HCLK |
88+
RCC_CLOCKTYPE_PCLK1 |
89+
RCC_CLOCKTYPE_PCLK2;
90+
91+
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
92+
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
93+
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
94+
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
95+
96+
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) {
97+
while (1) {}
98+
}
99+
100+
SystemCoreClockUpdate();
101+
init_monotonic_timer();
102+
}
103+
104+
unsigned long long monotonic_now(void)
105+
{
106+
uint64_t hi_1;
107+
uint64_t hi_2;
108+
uint32_t lo;
109+
uint32_t sr;
110+
111+
// Retry if the overflow IRQ updates the high word while sampling.
112+
do {
113+
hi_1 = monotonic_hi;
114+
lo = TIM2->CNT;
115+
sr = TIM2->SR;
116+
hi_2 = monotonic_hi;
117+
} while (hi_1 != hi_2);
118+
119+
// If overflow is pending but IRQ has not run yet, include that wrap.
120+
if ((sr & TIM_SR_UIF) != 0U && lo < 0x80000000U) {
121+
hi_1 += (1ULL << 32);
122+
}
123+
124+
return hi_1 | (uint64_t)lo;
125+
}
126+
127+
unsigned long long monotonic_freq(void)
128+
{
129+
return 1000000ULL;
130+
}

machine/arm/stm32l4xx/interface/export.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
// lib.c
4+
unsigned long long systick_freq(void);
45
void init_hal(void);
56

67
// uart.c
@@ -16,3 +17,9 @@ void dwt_reset(void);
1617
long dwt_read(void);
1718
float dwt_read_ns(void);
1819
float dwt_cycles_to_ns(long cycles);
20+
21+
// clock.c
22+
void SystemClock_Config(void);
23+
24+
unsigned long long monotonic_now(void);
25+
unsigned long long monotonic_freq(void);

machine/arm/stm32l4xx/interface/lib.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,14 @@ static void enable_faults(void) {
1515
}
1616

1717
static void init_systick(void) {
18-
HAL_SYSTICK_Config(SystemCoreClock /
19-
10); // Configure SysTick to interrupt every 1 ms
18+
HAL_SYSTICK_Config(SystemCoreClock / 1000); // Configure SysTick to interrupt every 1 ms
2019
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
2120
}
2221

22+
unsigned long long systick_freq(void) {
23+
return 1000;
24+
}
25+
2326
void init_hal(void) {
2427
#if OSIRIS_TUNING_ENABLEFPU
2528
init_fpu();
@@ -28,6 +31,7 @@ void init_hal(void) {
2831

2932
enable_faults();
3033

34+
SystemClock_Config();
3135
init_systick();
3236
}
3337

0 commit comments

Comments
 (0)