diff options
author | Padmarao Begari <padmarao.begari@microchip.com> | 2022-09-19 18:30:26 +0530 |
---|---|---|
committer | Joel Sherrill <joel@rtems.org> | 2022-09-20 12:00:51 -0500 |
commit | 6b0d3c987349d188b65e9fc8229daeba247928c5 (patch) | |
tree | 4f6f37aaab9be619b82612eb4f000a42549488ca /bsps/riscv | |
parent | spec/build/bsps: Add dtb support (diff) | |
download | rtems-6b0d3c987349d188b65e9fc8229daeba247928c5.tar.bz2 |
bsps/riscv: Add Microchip PolarFire SoC BSP variant
The Microchip PolarFire SoC support is implemented as a
riscv BSP variant to boot with any individual hart(cpu core)
or SMP based on the boot HARTID configurable and support
components are 4 CPU Cores (U54), Interrupt controller (PLIC),
Timer (CLINT), UART.
Diffstat (limited to 'bsps/riscv')
-rw-r--r-- | bsps/riscv/riscv/clock/clockdrv.c | 6 | ||||
-rw-r--r-- | bsps/riscv/riscv/config/mpfs64imafdc.cfg | 9 | ||||
-rw-r--r-- | bsps/riscv/riscv/include/bsp/riscv.h | 14 | ||||
-rw-r--r-- | bsps/riscv/riscv/irq/irq.c | 81 | ||||
-rw-r--r-- | bsps/riscv/riscv/start/bsp_fatal_halt.c | 3 | ||||
-rw-r--r-- | bsps/riscv/riscv/start/bspsmp.c | 2 | ||||
-rw-r--r-- | bsps/riscv/riscv/start/bspstart.c | 19 | ||||
-rw-r--r-- | bsps/riscv/shared/start/start.S | 2 |
8 files changed, 132 insertions, 4 deletions
diff --git a/bsps/riscv/riscv/clock/clockdrv.c b/bsps/riscv/riscv/clock/clockdrv.c index 65bc7c80ef..d183e65b94 100644 --- a/bsps/riscv/riscv/clock/clockdrv.c +++ b/bsps/riscv/riscv/clock/clockdrv.c @@ -95,6 +95,8 @@ static void riscv_clock_at_tick(riscv_timecounter *tc) uint64_t value; uint32_t cpu = rtems_scheduler_get_processor(); + cpu = _RISCV_Map_cpu_index_to_hardid(cpu); + clint = tc->clint; value = clint->mtimecmp[cpu].val_64; @@ -172,6 +174,8 @@ static void riscv_clock_secondary_action(void *arg) uint64_t *cmpval = arg; uint32_t cpu = _CPU_SMP_Get_current_processor(); + cpu = _RISCV_Map_cpu_index_to_hardid(cpu); + riscv_clock_clint_init(clint, *cmpval, cpu); } #endif @@ -214,7 +218,7 @@ static void riscv_clock_initialize(void) cmpval = riscv_clock_read_mtime(&clint->mtime); cmpval += interval; - riscv_clock_clint_init(clint, cmpval, 0); + riscv_clock_clint_init(clint, cmpval, RISCV_BOOT_HARTID); riscv_clock_secondary_initialization(clint, cmpval, interval); /* Initialize timecounter */ diff --git a/bsps/riscv/riscv/config/mpfs64imafdc.cfg b/bsps/riscv/riscv/config/mpfs64imafdc.cfg new file mode 100644 index 0000000000..b04e78b0e9 --- /dev/null +++ b/bsps/riscv/riscv/config/mpfs64imafdc.cfg @@ -0,0 +1,9 @@ +include $(RTEMS_ROOT)/make/custom/default.cfg + +RTEMS_CPU = riscv + +CPU_CFLAGS = -march=rv64imafdc -mabi=lp64d -mcmodel=medany + +LDFLAGS = -Wl,--gc-sections + +CFLAGS_OPTIMIZE_V ?= -O2 -g -ffunction-sections -fdata-sections diff --git a/bsps/riscv/riscv/include/bsp/riscv.h b/bsps/riscv/riscv/include/bsp/riscv.h index a469155865..2ef2f8d83d 100644 --- a/bsps/riscv/riscv/include/bsp/riscv.h +++ b/bsps/riscv/riscv/include/bsp/riscv.h @@ -34,17 +34,31 @@ extern "C" { #endif +static inline uint32_t _RISCV_Map_hardid_to_cpu_index(uint32_t hardid) +{ + return (hardid - RISCV_BOOT_HARTID); +} + +static inline uint32_t _RISCV_Map_cpu_index_to_hardid(uint32_t cpu_index) +{ + return (cpu_index + RISCV_BOOT_HARTID); +} + extern volatile RISCV_CLINT_regs *riscv_clint; void *riscv_fdt_get_address(const void *fdt, int node); uint32_t riscv_get_core_frequency(void); +#if RISCV_ENABLE_MPFS_SUPPORT != 0 +extern uint32_t riscv_hart_count; +#else #ifdef RTEMS_SMP extern uint32_t riscv_hart_count; #else #define riscv_hart_count 1 #endif +#endif uint32_t riscv_get_hart_index_by_phandle(uint32_t phandle); diff --git a/bsps/riscv/riscv/irq/irq.c b/bsps/riscv/riscv/irq/irq.c index 1b632289a6..1f383ebb89 100644 --- a/bsps/riscv/riscv/irq/irq.c +++ b/bsps/riscv/riscv/irq/irq.c @@ -136,6 +136,12 @@ static void riscv_clint_init(const void *fdt) Per_CPU_Control *cpu; hart_index = riscv_get_hart_index_by_phandle(fdt32_to_cpu(val[i / 4])); +#ifdef RTEMS_SMP + if (hart_index < RISCV_BOOT_HARTID) { + continue; + } + + hart_index = _RISCV_Map_hardid_to_cpu_index(hart_index); if (hart_index >= rtems_configuration_get_maximum_processors()) { continue; } @@ -143,6 +149,15 @@ static void riscv_clint_init(const void *fdt) cpu = _Per_CPU_Get_by_index(hart_index); cpu->cpu_per_cpu.clint_msip = &clint->msip[i / 16]; cpu->cpu_per_cpu.clint_mtimecmp = &clint->mtimecmp[i / 16]; +#else + if (hart_index != RISCV_BOOT_HARTID) { + continue; + } + + cpu = _Per_CPU_Get_by_index(0); + cpu->cpu_per_cpu.clint_msip = &clint->msip[i / 16]; + cpu->cpu_per_cpu.clint_mtimecmp = &clint->mtimecmp[i / 16]; +#endif } } @@ -183,8 +198,21 @@ static void riscv_plic_init(const void *fdt) for (i = 0; i < len; i += 8) { uint32_t hart_index; + uint8_t mie_regs; + + /* + * Interrupt enable registers with 32-bit alignment based on + * number of interrupts. + */ + mie_regs = (ndev + 0x1f) & ~(0x1f); hart_index = riscv_get_hart_index_by_phandle(fdt32_to_cpu(val[i / 4])); +#ifdef RTEMS_SMP + if (hart_index < RISCV_BOOT_HARTID) { + continue; + } + + hart_index = _RISCV_Map_hardid_to_cpu_index(hart_index); if (hart_index >= rtems_configuration_get_maximum_processors()) { continue; } @@ -199,6 +227,28 @@ static void riscv_plic_init(const void *fdt) cpu = _Per_CPU_Get_by_index(hart_index); cpu->cpu_per_cpu.plic_hart_regs = &plic->harts[i / 8]; cpu->cpu_per_cpu.plic_m_ie = &plic->enable[i / 8][0]; + + for (interrupt_index = 0; interrupt_index < mie_regs; ++interrupt_index) { + cpu->cpu_per_cpu.plic_m_ie[interrupt_index] = 0; + } +#else + if (hart_index != RISCV_BOOT_HARTID) { + continue; + } + + interrupt_index = fdt32_to_cpu(val[i / 4 + 1]); + if (interrupt_index != RISCV_INTERRUPT_EXTERNAL_MACHINE) { + continue; + } + plic->harts[i / 8].priority_threshold = 0; + + cpu = _Per_CPU_Get_by_index(0); + cpu->cpu_per_cpu.plic_hart_regs = &plic->harts[i / 8]; + cpu->cpu_per_cpu.plic_m_ie = &plic->enable[i / 8][0]; + for (interrupt_index = 0; interrupt_index < mie_regs; ++interrupt_index) { + cpu->cpu_per_cpu.plic_m_ie[interrupt_index] = 0; + } +#endif } cpu = _Per_CPU_Get_by_index(0); @@ -298,6 +348,7 @@ rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector) if (enable != NULL) { enable[group] |= bit; } else { +#ifdef RTEMS_SMP uint32_t cpu_max; uint32_t cpu_index; @@ -313,6 +364,16 @@ rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector) enable[group] |= bit; } } +#else + Per_CPU_Control *cpu; + + cpu = _Per_CPU_Get_by_index(0); + enable = cpu->cpu_per_cpu.plic_m_ie; + + if (enable != NULL) { + enable[group] |= bit; + } +#endif } rtems_interrupt_lock_release(&riscv_plic_lock, &lock_context); @@ -342,6 +403,7 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) if (enable != NULL) { enable[group] &= ~bit; } else { +#ifdef RTEMS_SMP uint32_t cpu_max; uint32_t cpu_index; @@ -357,6 +419,16 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) enable[group] &= ~bit; } } +#else + Per_CPU_Control *cpu; + + cpu = _Per_CPU_Get_by_index(0); + enable = cpu->cpu_per_cpu.plic_m_ie; + + if (enable != NULL) { + enable[group] &= ~bit; + } +#endif } rtems_interrupt_lock_release(&riscv_plic_lock, &lock_context); @@ -414,6 +486,7 @@ rtems_status_code bsp_interrupt_get_affinity( enable = riscv_plic_irq_to_cpu[interrupt_index - 1]; if (enable != NULL) { +#ifdef RTEMS_SMP uint32_t cpu_max; uint32_t cpu_index; @@ -429,6 +502,14 @@ rtems_status_code bsp_interrupt_get_affinity( break; } } +#else + Per_CPU_Control *cpu; + + cpu = _Per_CPU_Get_by_index(0); + + if (enable == cpu->cpu_per_cpu.plic_m_ie) + _Processor_mask_Set(affinity, 0); +#endif } else { _Processor_mask_Assign(affinity, _SMP_Get_online_processors()); } diff --git a/bsps/riscv/riscv/start/bsp_fatal_halt.c b/bsps/riscv/riscv/start/bsp_fatal_halt.c index d9708661a7..fb0787c606 100644 --- a/bsps/riscv/riscv/start/bsp_fatal_halt.c +++ b/bsps/riscv/riscv/start/bsp_fatal_halt.c @@ -41,6 +41,9 @@ void _CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr error ) #if RISCV_ENABLE_HTIF_SUPPORT != 0 htif_poweroff(); #endif +#if RISCV_ENABLE_MPFS_SUPPORT != 0 + for(;;); +#endif fdt = bsp_fdt_get(); node = fdt_node_offset_by_compatible(fdt, -1, "sifive,test0"); diff --git a/bsps/riscv/riscv/start/bspsmp.c b/bsps/riscv/riscv/start/bspsmp.c index 4f1b3c93cc..91f4f7b96a 100644 --- a/bsps/riscv/riscv/start/bspsmp.c +++ b/bsps/riscv/riscv/start/bspsmp.c @@ -49,7 +49,7 @@ void bsp_start_on_secondary_processor(Per_CPU_Control *cpu_self) uint32_t _CPU_SMP_Initialize(void) { - return riscv_hart_count; + return riscv_hart_count - RISCV_BOOT_HARTID; } bool _CPU_SMP_Start_processor(uint32_t cpu_index) diff --git a/bsps/riscv/riscv/start/bspstart.c b/bsps/riscv/riscv/start/bspstart.c index d33e9965f8..66e2934013 100644 --- a/bsps/riscv/riscv/start/bspstart.c +++ b/bsps/riscv/riscv/start/bspstart.c @@ -74,6 +74,10 @@ void *riscv_fdt_get_address(const void *fdt, int node) return (void *)(uintptr_t) addr; } +#if RISCV_ENABLE_MPFS_SUPPORT != 0 +uint32_t riscv_hart_count; +static uint32_t riscv_hart_phandles[5]; +#else #ifdef RTEMS_SMP uint32_t riscv_hart_count; @@ -81,6 +85,7 @@ static uint32_t riscv_hart_phandles[CPU_MAXIMUM_PROCESSORS]; #else static uint32_t riscv_hart_phandles[1]; #endif +#endif static void riscv_find_harts(void) { @@ -146,9 +151,13 @@ static void riscv_find_harts(void) riscv_hart_phandles[hart_index] = phandle; } +#if RISCV_ENABLE_MPFS_SUPPORT != 0 + riscv_hart_count = max_hart_index + 1; +#else #ifdef RTEMS_SMP riscv_hart_count = max_hart_index + 1; #endif +#endif } uint32_t riscv_get_hart_index_by_phandle(uint32_t phandle) @@ -166,7 +175,7 @@ uint32_t riscv_get_hart_index_by_phandle(uint32_t phandle) static uint32_t get_core_frequency(void) { -#if RISCV_ENABLE_FRDME310ARTY_SUPPORT != 0 +#if RISCV_ENABLE_FRDME310ARTY_SUPPORT != 0 || RISCV_ENABLE_MPFS_SUPPORT != 0 uint32_t node; const char *fdt; const char *tlclk; @@ -177,7 +186,13 @@ static uint32_t get_core_frequency(void) node = fdt_node_offset_by_compatible(fdt, -1,"fixed-clock"); tlclk = fdt_getprop(fdt, node, "clock-output-names", &len); - if (strcmp(tlclk,"tlclk") != 0) { +#if RISCV_ENABLE_FRDME310ARTY_SUPPORT != 0 + if (strcmp(tlclk,"tlclk") != 0) +#endif +#if RISCV_ENABLE_MPFS_SUPPORT != 0 + if (strcmp(tlclk,"msspllclk") != 0) +#endif + { bsp_fatal(RISCV_FATAL_NO_TLCLOCK_FREQUENCY_IN_DEVICE_TREE); } diff --git a/bsps/riscv/shared/start/start.S b/bsps/riscv/shared/start/start.S index 3702f8ac2f..47bb485847 100644 --- a/bsps/riscv/shared/start/start.S +++ b/bsps/riscv/shared/start/start.S @@ -65,6 +65,8 @@ SYM(_start): LADDR sp, _ISR_Stack_area_begin LADDR t2, _ISR_Stack_size csrr s0, mhartid + li t3, RISCV_BOOT_HARTID + sub s0, s0, t3 LADDR t0, _Per_CPU_Information slli t1, s0, PER_CPU_CONTROL_SIZE_LOG2 add s1, t0, t1 |