Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions so3/so3/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,9 @@ export KBUILD_ARFLAGS
ifeq ($(CONFIG_VIRT32),y)
TARGET = virt32
endif
ifeq ($(CONFIG_RPI4),y)
TARGET = rpi4
endif
ifeq ($(CONFIG_RPI4_64),y)
TARGET = rpi4_64
endif
Expand Down
4 changes: 4 additions & 0 deletions so3/so3/arch/arm32/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ choice
bool "QEMU virt 32-bit machine"
select GIC_V2

config RPI4
bool "Raspberry Pi 4 Model B 32-bit"
select GIC_V2

endchoice

endmenu
Expand Down
5 changes: 5 additions & 0 deletions so3/so3/arch/arm32/rpi4/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#
# Makefile
#

obj-$(CONFIG_SMP) += platsmp.o
82 changes: 82 additions & 0 deletions so3/so3/arch/arm32/rpi4/include/mach/io.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright (C) 2020-2026 Daniel Rossier <daniel.rossier@heig-vd.ch>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/

#ifndef MACH_IO_H
#define MACH_IO_H

/*
* ARM local interrupt controller, which carries the per-CPU mailboxes.
* Unlike arm64, which releases the secondaries through the spin table,
* the 32-bit boot path wakes them by writing the entry point into
* mailbox 3 (see platsmp.c) — hence the mapping below.
*/
#define LOCAL_INTC_PHYS 0xff800000
#define LOCAL_INTC_SIZE 0x100

/*
* From BCM2835 ARM peripherals documentation.
*
* Mini UART register offsets.
*/

#define MU_IO_REG 0x00
#define MU_IER_REG 0x04
#define MU_IIR_REG 0x08
#define MU_LCR_REG 0x0C
#define MU_MCR_REG 0x10
#define MU_LSR_REG 0x14
#define MU_MSR_REG 0x18
#define MU_SCRATCH 0x1C
#define MU_CNTL_REG 0x20
#define MU_STAT_REG 0x24
#define MU_BAUD_REG 0x28

#define MU_IO_DATA (0xFF << 0)
#define MU_STAT_SP_AVAIL (1 << 0)
#define MU_STAT_RX_FIFO_FILL (0xF << 16)
#define MU_LSR_TX_EMPTY (1 << 5)
#define MU_LSR_DATA_READY (1 << 0)
/* TODO : all other bit offsets */

/*
* The low 4 bits of this are the CPU's per-mailbox IRQ enables, and
* the next 4 bits are the CPU's per-mailbox FIQ enables (which
* override the IRQ bits).
*/
#define LOCAL_MAILBOX_INT_CONTROL0 0x050

/*
* Mailbox write-to-set bits. There are 16 mailboxes, 4 per CPU, and
* these bits are organized by mailbox number and then CPU number. We
* use mailbox 0 for IPIs. The mailbox's interrupt is raised while
* any bit is set.
*/
#define LOCAL_MAILBOX0_SET0 0x080
#define LOCAL_MAILBOX3_SET0 0x08c

/* Mailbox write-to-clear bits. */
#define LOCAL_MAILBOX0_CLR0 0x0c0
#define LOCAL_MAILBOX3_CLR0 0x0cc

/* CPU Release address to be woken up following spin table method. */
#define CPU0_RELEASE_ADDR 0xd8
#define CPU1_RELEASE_ADDR 0xe0
#define CPU2_RELEASE_ADDR 0xe8
#define CPU3_RELEASE_ADDR 0xf0

#endif /* MACH_IO_H */
46 changes: 46 additions & 0 deletions so3/so3/arch/arm32/rpi4/platsmp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (C) 2016,2017 Daniel Rossier <daniel.rossier@heig-vd.ch>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/

#include <smp.h>
#include <spinlock.h>
#include <memory.h>

#include <asm/cacheflush.h>
#include <asm/processor.h>
#include <asm/io.h>

#include <device/arch/gic.h>

#include <mach/io.h>

extern void secondary_startup(void);

void smp_boot_secondary(unsigned int cpu)
{
unsigned long secondary_startup_phys = (unsigned long) __pa((void *) secondary_startup);
void *intc_vaddr; /* We will add bytes to this pointer */

printk("%s: booting CPU: %d...\n", __func__, cpu);

intc_vaddr = (void *) io_map(LOCAL_INTC_PHYS, LOCAL_INTC_SIZE);

iowrite32(intc_vaddr + LOCAL_MAILBOX3_SET0 + 16 * cpu, secondary_startup_phys);

dsb(sy);
sev();
}
88 changes: 88 additions & 0 deletions so3/so3/configs/rpi4_defconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#
# Automatically generated make config: don't edit
# SO3 Polymorphic OS Configuration
#
CONFIG_ARCH_ARM32=y
# CONFIG_ARCH_ARM64 is not set
CONFIG_ARCH="arm32"
CONFIG_CROSS_COMPILE="arm-none-eabi-"
# CONFIG_ARM_TRUSTZONE is not set

#
# Platform
#
CONFIG_KERNEL_VADDR=0xc0000000
# CONFIG_VIRT32 is not set
CONFIG_RPI4=y
# CONFIG_THREAD_ENV is not set
CONFIG_PROC_ENV=y

#
# Kernel & CPU features
#
CONFIG_MAX_THREADS=32
# CONFIG_SMP is not set
CONFIG_NR_CPUS=1
CONFIG_HZ=100
CONFIG_SCHED_FLIP_SCHEDFREQ=30

#
# SO3 Scheduling configuration
#
CONFIG_SCHED_RR=y
# CONFIG_SCHED_PRIO is not set
CONFIG_SCHED_FREQ_PREEMPTION=y

#
# Drivers
#
CONFIG_UART=y
CONFIG_IO_MAPPING_BASE=0xe0000000
# CONFIG_I2C is not set
# CONFIG_NET is not set
# CONFIG_FB is not set
# CONFIG_INPUT is not set
# CONFIG_NS16550 is not set
CONFIG_BCM283x_MU_UART=y
CONFIG_UART_LL_PADDR=0xfe215040
# CONFIG_MMC is not set
CONFIG_RAMDEV=y
CONFIG_ARM_TIMER=y
CONFIG_GIC=y
CONFIG_GIC_V2=y

#
# SO3 Applications
#
# CONFIG_APP_SAMPLE is not set
# CONFIG_APP_REFSO3 is not set

#
# Filesystems
#
CONFIG_FS_FAT=y
# CONFIG_ROOTFS_NONE is not set
# CONFIG_ROOTFS_MMC is not set
CONFIG_ROOTFS_RAMDEV=y

#
# IPC
#
CONFIG_IPC_SIGNAL=y
CONFIG_IPC_PIPE=y
CONFIG_HEAP_SIZE_MB=8
CONFIG_SYS_STACK_SIZE_KB=64
CONFIG_THREAD_STACK_SIZE_KB=64
# CONFIG_RTOS is not set
# CONFIG_AVZ is not set
CONFIG_USER_INIT_PROGRAM="init.elf"
# CONFIG_LOG_LEVEL_CRITICAL is not set
# CONFIG_LOG_LEVEL_ERROR is not set
# CONFIG_LOG_LEVEL_WARNING is not set
CONFIG_LOG_LEVEL_INFO=y
# CONFIG_LOG_LEVEL_DEBUG is not set
# CONFIG_LOG_LEVEL_TRACE is not set
# CONFIG_LOG_LEVEL_NONE is not set
CONFIG_LOG_LEVEL=4
# CONFIG_SOO is not set
CONFIG_MMU=y
1 change: 1 addition & 0 deletions so3/so3/dts/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

dtb-$(CONFIG_RPI4) += rpi4.dtb
dtb-$(CONFIG_RPI4_64) += rpi4_64.dtb rpi4_64_avz.dtb rpi4_64_capsule.dtb
dtb-$(CONFIG_VIRT64) += virt64.dtb virt64_avz.dtb virt64_capsule.dtb virt64_lvperf.dtb
dtb-$(CONFIG_VIRT32) += virt32.dtb virt32_lvperf.dtb
Expand Down
123 changes: 123 additions & 0 deletions so3/so3/dts/rpi4.dts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright (C) 2014-2026 REDS Institute, HEIG-VD, Yverdon
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/

/dts-v1/;

/ {
model = "SO3 RPi4 32-bit";
compatible = "arm,rpi4";

/*
* Single address/size cell, unlike rpi4_64.dts: this is the 32-bit
* platform, so every reg below carries one address cell instead of two.
*/
#address-cells = <1>;
#size-cells = <1>;

cpus {
device_type = "cpu";
compatible = "arm,cortex-a72";
};

memory {
device_type = "memory";
reg = <0x01000000 0x20000000>; /* 512 MB; base = ITS load 0x01008000 - 0x8000 text offset */
};

mem {
compatible = "mem";
status = "ok";
};

/* GIC interrupt controller */
gic:interrupt-controller@ff841000 {
compatible = "intc,gic";
interrupt-controller;
#interrupt-cells = <3>;

reg = <0xff841000 0x1000
0xff842000 0x1000>;
status = "ok";
};

/* RPi4 miniuart NS16550 console */
serial@fe215040 {
compatible = "serial,bcm283x-mu";
reg = <0xfe215040 0x1000>;
interrupt-parent = <&gic>;

/*
* AUX (mini UART) — SPI 93, the value Broadcom's
* bcm2711-rpi-4-b.dtb gives for /soc/serial@7e215040.
*/
interrupts = <0 93 4>;
status = "ok";
};

/* I2C1 controller (Broadcom Serial Controller BSC1) */
i2c1:i2c1@fe804000 {
compatible = "bcm,i2c_bsc";
reg = <0xfe804000 0x400>;
status = "disabled";
interrupt-parent = <&gic>;

/* IRQ 53 of VC which start at SPI96 -> 96 + 53 = 149 */
interrupts = <0 117 4>;
};

/* Periodic timer based on ARM CP15 timer */
periodic-timer {
compatible = "arm,periodic-timer";
interrupt-parent = <&gic>;

/* IRQ 10 with VT support or 11 without */
interrupts = <1 11 4>;
status = "ok";
};

/* Clocksource free-running timer based on ARM CP15 timer */
clocksource-timer {
compatible = "arm,clocksource-timer";
status = "ok";
};

rpisense {
compatible = "bcm,rpisense";
interrupt-parent = <&gic>;
interrupts = <0 113 4>;
status = "disabled";
};

/*
* Present only so U-Boot's RPi 4 bootm fixup can copy the
* firmware-corrected dma-ranges into this static DT (see u-boot
* boot/bootm.c, CONFIG_BCM2711). Silences the "Can't find emmc2bus in
* the DT stored in the ITB" warning. SO3 boots from ramfs and does not
* drive emmc2 itself, so the child controller node is intentionally
* omitted. The parent address in ranges/dma-ranges is a single cell
* here, matching this tree's #address-cells.
*/
emmc2bus {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <1>;
ranges = <0x0 0x7e000000 0xfe000000 0x01800000>;
dma-ranges = <0x0 0xc0000000 0x00000000 0x40000000>;
};

};
Loading