Oops, it looks like I forgot one patch. This is necessary to run RefOS but doesnt affect sel4-test. It enables all of the timer blocks so that they can be used from userland. Without it, refos will get an exception when it tries to use its timer (I guess nobody's tried running it yet :)
On Mon, Mar 16, 2015 at 11:04 AM, Tim Newsham <[email protected]> wrote: > RefOS is now working fine on am335x / beaglebone black. > Patches attached. > > Tim -- Tim Newsham | www.thenewsh.com/~newsham | @newshtwit | thenewsh.blogspot.com
From 01c13c0f67af3a082fe0cc3c14e7aa27a06b5e10 Mon Sep 17 00:00:00 2001 From: Tim Newsham <[email protected]> Date: Sun, 15 Mar 2015 21:07:37 -1000 Subject: [PATCH] - setup clock and enable dmtimer3 on am335x --- include/plat/am335x/plat/machine/devices.h | 8 ++++-- src/plat/am335x/machine/hardware.c | 46 ++++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/include/plat/am335x/plat/machine/devices.h b/include/plat/am335x/plat/machine/devices.h index adbe875..8c9704e 100644 --- a/include/plat/am335x/plat/machine/devices.h +++ b/include/plat/am335x/plat/machine/devices.h @@ -16,11 +16,12 @@ #define UART0_PPTR 0xfff02000 #define DMTIMER0_PPTR 0xfff03000 #define WDT1_PPTR 0xfff04000 +#define CMPER_PPTR 0xfff05000 /* Other devices on the SoC. */ -#define INTC_PADDR 0x48200000 -#define UART0_PADDR 0x44E09000 +#define INTC_PADDR 0x48200000 +#define UART0_PADDR 0x44E09000 #define DMTIMER0_PADDR 0x44E05000 #define DMTIMER2_PADDR 0x48040000 #define DMTIMER3_PADDR 0x48042000 @@ -28,7 +29,8 @@ #define DMTIMER5_PADDR 0x48046000 #define DMTIMER6_PADDR 0x48048000 #define DMTIMER7_PADDR 0x4804A000 -#define WDT1_PADDR 0x44e35000 +#define WDT1_PADDR 0x44e35000 +#define CMPER_PADDR 0x44e00000 #endif diff --git a/src/plat/am335x/machine/hardware.c b/src/plat/am335x/machine/hardware.c index 41a4eb1..005d2df 100644 --- a/src/plat/am335x/machine/hardware.c +++ b/src/plat/am335x/machine/hardware.c @@ -42,14 +42,15 @@ BOOT_CODE p_region_t get_avail_p_reg(unsigned int i) const p_region_t BOOT_RODATA dev_p_regs[] = { /* SoC devices: */ - { /* .start = */ UART0_PADDR, /* .end = */ UART0_PADDR + (1 << PAGE_BITS) }, + { /* .start = */ UART0_PADDR, /* .end = */ UART0_PADDR + (1 << PAGE_BITS) }, { /* .start = */ DMTIMER2_PADDR, /* .end = */ DMTIMER2_PADDR + (1 << PAGE_BITS) }, { /* .start = */ DMTIMER3_PADDR, /* .end = */ DMTIMER3_PADDR + (1 << PAGE_BITS) }, { /* .start = */ DMTIMER4_PADDR, /* .end = */ DMTIMER4_PADDR + (1 << PAGE_BITS) }, { /* .start = */ DMTIMER5_PADDR, /* .end = */ DMTIMER5_PADDR + (1 << PAGE_BITS) }, { /* .start = */ DMTIMER6_PADDR, /* .end = */ DMTIMER6_PADDR + (1 << PAGE_BITS) }, { /* .start = */ DMTIMER7_PADDR, /* .end = */ DMTIMER7_PADDR + (1 << PAGE_BITS) }, - { /* .start = */ WDT1_PADDR, /* .end = */ WDT1_PADDR + (1 << PAGE_BITS) }, + { /* .start = */ WDT1_PADDR, /* .end = */ WDT1_PADDR + (1 << PAGE_BITS) }, + { /* .start = */ CMPER_PADDR, /* .end = */ CMPER_PADDR + (1 << PAGE_BITS) }, /* Board devices. */ /* TODO: This should ultimately be replaced with a more general solution. */ }; @@ -104,6 +105,18 @@ map_kernel_devices(void) ) ); + /* map kernel device: CMPER */ + map_kernel_frame( + CMPER_PADDR, + CMPER_PPTR, + VMKernelOnly, + vm_attributes_new( + true, /* armExecuteNever */ + false, /* armParityEnabled */ + false /* armPageCacheable */ + ) + ); + #ifdef DEBUG /* map kernel device: UART */ map_kernel_frame( @@ -119,6 +132,13 @@ map_kernel_devices(void) #endif } +#define CMPER_REG(base, off) ((volatile uint32_t *)((base) + (off))) +#define CMPER_TIMER3_CLKCTRL 0x84 +#define CMPER_CLKCTRL_DISABLE 0 +#define CMPER_CLKCTRL_ENABLE 2 +#define CMPER_CLKSEL_TIMER3 0x50c +#define CMPER_CKLSEL_MOSC 1 + #define INTCPS_SYSCONFIG_SOFTRESET BIT(1) #define INTCPS_SYSSTATUS_RESETDONE BIT(0) @@ -295,6 +315,27 @@ disableWatchdog(void) } } +/* + * Enable DMTIMER clocks, otherwise their registers wont be accessible. + * This could be moved out of kernel. + */ +static BOOT_CODE void +enableTimers(void) +{ + uint32_t cmper = CMPER_PPTR; + + /* XXX repeat this for DMTIMER4..7 */ + /* select clock */ + *CMPER_REG(cmper, CMPER_CLKSEL_TIMER3) = CMPER_CKLSEL_MOSC; + while((*CMPER_REG(cmper, CMPER_CLKSEL_TIMER3) & 3) != CMPER_CKLSEL_MOSC) + continue; + + /* enable clock */ + *CMPER_REG(cmper, CMPER_TIMER3_CLKCTRL) = CMPER_CLKCTRL_ENABLE; + while((*CMPER_REG(cmper, CMPER_TIMER3_CLKCTRL) & 3) != CMPER_CLKCTRL_ENABLE) + continue; +} + /* Configure dmtimer0 as kernel preemption timer */ /** DONT_TRANSLATE @@ -305,6 +346,7 @@ initTimer(void) int timeout; disableWatchdog(); + enableTimers(); timer->cfg = TIOCP_CFG_SOFTRESET; -- 1.9.1
_______________________________________________ Devel mailing list [email protected] https://sel4.systems/lists/listinfo/devel
