Skip to content
Open
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
2 changes: 1 addition & 1 deletion libplatsupport/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ config_option(
mark_as_advanced(LibPlatSupportHaveTimer)

set(LibPlatSupportMach "")
if(KernelPlatformRpi3 OR KernelPlatformRpi4)
if(KernelPlatformRpi3 OR KernelPlatformRpi4 OR KernelPlatformRpi5)
set(LibPlatSupportMach "bcm")
elseif(KernelPlatformCheshire OR KernelPlatformAriane)
set(LibPlatSupportMach "cva6")
Expand Down
4 changes: 2 additions & 2 deletions libplatsupport/include/platsupport/fdt.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
* RISCV does have 128 bits but there are no platforms that use that bit length (yet) */
#define READ_CELL32(addr) fdt32_ld(addr)
#define READ_CELL64(addr) fdt64_ld(addr)
#define READ_CELL(size, addr, offset) (size == 2 ? READ_CELL64(addr + (offset * sizeof(uint32_t))) : \
READ_CELL32(addr + (offset * sizeof(uint32_t))))
#define READ_CELL(size, addr, offset) (size == 2 ? READ_CELL64((addr) + ((offset) * sizeof(uint32_t))) : \
READ_CELL32((addr) + ((offset) * sizeof(uint32_t))))

/*
* Type of the callback function that is called for each device register instance
Expand Down
17 changes: 17 additions & 0 deletions libplatsupport/plat_include/bcm2712/platsupport/plat/clock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
* Copyright (C) 2021, Hensoldt Cyber GmbH
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once

enum clk_id {
CLK_MASTER,
/* ----- */
NCLOCKS,
};

enum clock_gate {
NCLKGATES
};
10 changes: 10 additions & 0 deletions libplatsupport/plat_include/bcm2712/platsupport/plat/gpio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright (C) 2021, HENSOLDT Cyber GmbH
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#pragma once

#include <utils/util.h>
#include <platsupport/gpio.h>
11 changes: 11 additions & 0 deletions libplatsupport/plat_include/bcm2712/platsupport/plat/i2c.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
* Copyright (C) 2021, Hensoldt Cyber GmbH
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once

enum i2c_id {
NI2C
};
12 changes: 12 additions & 0 deletions libplatsupport/plat_include/bcm2712/platsupport/plat/mailbox.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright (C) 2021, HENSOLDT Cyber GmbH
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#pragma once

#include <platsupport/mach/mailbox.h>

#define MAILBOX_PADDR 0x107c013880
#define MAILBOX_SIZE 0x1000
34 changes: 34 additions & 0 deletions libplatsupport/plat_include/bcm2712/platsupport/plat/serial.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2025, UNSW
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#pragma once

#include <autoconf.h>
#include <platsupport/gen_config.h>

/* Corresponds to the Device Tree node '/soc@107c000000/serial@7d001000' */
#define PL011_UART_BASE 0x107d001000

#define UART0_OFFSET 0x0 // UART0: PL011

#define UART0_PADDR (PL011_UART_BASE)

#define UART0_IRQ 153

#define DEFAULT_SERIAL_PADDR UART0_PADDR
#define DEFAULT_SERIAL_INTERRUPT UART0_IRQ

enum chardev_id {
BCM2xxx_UART0,

NUM_CHARDEV,

/* Aliases */
PS_SERIAL0 = BCM2xxx_UART0,

/* Defaults */
PS_SERIAL_DEFAULT = BCM2xxx_UART0
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright 2025, UNSW
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once

#include <utils/util.h>

/*
* The Device Tree by default for BCM2712 will contain the timer IRQs
* for each channel. Channels 0 and 2 are used by the VideoCore, so
* we use 1 instead.
*/
#define BCM_SYSTEM_TIMER_CHANNEL (1)
#define BCM_SYSTEM_TIMER_FREQ (MHZ)
#define BCM_SYSTEM_TIMER_FDT_PATH "/soc@107c000000/timer@7c003000"
#define BCM_SYSTEM_TIMER_REG_CHOICE (0)
#define BCM_SYSTEM_TIMER_IRQ_CHOICE (1)
31 changes: 31 additions & 0 deletions libplatsupport/src/fdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,20 @@ int ps_fdt_walk_registers(ps_io_fdt_t *io_fdt, ps_fdt_cookie_t *cookie, reg_walk
}
int total_cells = prop_len / sizeof(uint32_t);

int parent_ranges_prop_len = 0;
const uint32_t *parent_ranges_prop = fdt_getprop(dtb_blob, parent_offset, "ranges", &parent_ranges_prop_len);
bool parent_has_ranges = parent_ranges_prop != NULL;

int num_parent_bus_address_cells = 0;
if (parent_has_ranges) {
int parent_bus_node_offset = fdt_parent_offset(dtb_blob, parent_offset);
/* If the parent has the ranges field, it should have its own parent node. */
if (parent_bus_node_offset < 0) {
return parent_bus_node_offset;
}
num_parent_bus_address_cells = fdt_address_cells(dtb_blob, parent_bus_node_offset);
}

/* sanity check */
assert(total_cells % (num_address_cells + num_size_cells) == 0);

Expand All @@ -128,6 +142,23 @@ int ps_fdt_walk_registers(ps_io_fdt_t *io_fdt, ps_fdt_cookie_t *cookie, reg_walk
curr_pmem.type = PMEM_TYPE_DEVICE;
curr_pmem.base_addr = READ_CELL(num_address_cells, curr, 0);
curr_pmem.length = READ_CELL(num_size_cells, curr, num_address_cells);

if (parent_has_ranges) {
assert(num_parent_bus_address_cells != 0);
int parent_ranges_cells = parent_ranges_prop_len / sizeof(uint32_t);
int num_ranges = parent_ranges_cells / (num_parent_bus_address_cells + num_address_cells + num_size_cells);
for (int j = 0; j < num_ranges; j++) {
const void *curr_range = (const void *)(&parent_ranges_prop[j]);
uint64_t child_bus_addr = READ_CELL(num_address_cells, curr_range, 0);
uint64_t parent_bus_addr = READ_CELL(num_parent_bus_address_cells, curr_range, num_address_cells);
uint64_t range_length = READ_CELL(num_size_cells, curr_range, num_address_cells + num_parent_bus_address_cells);
if (child_bus_addr <= curr_pmem.base_addr && child_bus_addr + range_length > curr_pmem.base_addr) {
uint64_t offset = curr_pmem.base_addr - child_bus_addr;
curr_pmem.base_addr = parent_bus_addr + offset;
}
}
}

int error = callback(curr_pmem, i, num_regs, token);
if (error) {
return error;
Expand Down
7 changes: 7 additions & 0 deletions libplatsupport/src/mach/bcm/bcm_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,16 @@ int bcm_uart_init(const struct dev_defn *defn, const ps_io_ops_t *ops, ps_charde
uint32_t addr_offset = 0;

switch (defn->id) {
#if defined(CONFIG_PLAT_BCM2711) || defined(CONFIG_PLAT_BCM2837)
case 1:
addr_offset = UART1_OFFSET;
break;
#elif defined (CONFIG_PLAT_BCM2712)
/* BCM UART is not supported on BCM2712 as it is on the PCIe bus rather
* than the SoC itself. */
#else
#error "bcm_uart_init: unknown platform"
#endif
default:
ZF_LOGE("Mini-UART with ID %d does not exist!", defn->id);
return -1;
Expand Down
8 changes: 8 additions & 0 deletions libplatsupport/src/mach/bcm/chardev.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ static const struct dev_defn dev_defn[] = {
UART_DEFN(5)
};

#elif defined(CONFIG_PLAT_BCM2712)

static const int uart_irqs_0[] = { UART0_IRQ, -1 };

static const struct dev_defn dev_defn[] = {
UART_DEFN(0),
};

#elif defined(CONFIG_PLAT_BCM2837)

static const int uart_irqs_0[] = { UART0_IRQ, -1 };
Expand Down
11 changes: 11 additions & 0 deletions libplatsupport/src/mach/bcm/pl011_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,17 @@ int pl011_uart_init(const struct dev_defn *defn, const ps_io_ops_t *ops, ps_char
return -1;
}

#elif defined(CONFIG_PLAT_BCM2712)

switch (defn->id) {
case BCM2xxx_UART0:
addr_offset = UART0_OFFSET;
break;
default:
ZF_LOGE("PL011 UART with ID %d does not exist!", defn->id);
return -1;
}

#elif defined(CONFIG_PLAT_BCM2837)

switch (defn->id) {
Expand Down
14 changes: 14 additions & 0 deletions libplatsupport/src/mach/bcm/serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ static const uart_gpio_defn_t gpio_defs[NUM_CHARDEV] = {
UART_GPIO_DEFN(BCM2xxx_UART5, 12, 13, BCM2711_GPIO_FSEL_ALT4) // UART 5 uses GPIO pins 12-13
};

#elif defined(CONFIG_PLAT_BCM2712)

/* GPIO is not supported on BCM2712. */

#elif defined(CONFIG_PLAT_BCM2837)

static const uart_gpio_defn_t gpio_defs[NUM_CHARDEV] = {
Expand Down Expand Up @@ -96,6 +100,7 @@ int uart_gpio_configure(enum chardev_id id, const ps_io_ops_t *o)
// control (CTS/RTS pins) for now.
uart_gpio_defn_t pindef = { -1, -1, -1, -1 };

#ifndef CONFIG_PLAT_BCM2712
for (int i = 0; i < NUM_CHARDEV; i++) {
if (id == gpio_defs[i].uart_id) {
pindef = gpio_defs[i];
Expand Down Expand Up @@ -137,6 +142,8 @@ int uart_gpio_configure(enum chardev_id id, const ps_io_ops_t *o)

#else
#error "Unknown BCM2xxx platform!"
#endif

#endif

return 0;
Expand All @@ -163,6 +170,13 @@ int uart_init(const struct dev_defn *defn, const ps_io_ops_t *ops, ps_chardevice
uart_funcs.uart_putchar = &pl011_uart_putchar;
break;

#elif defined(CONFIG_PLAT_BCM2712)
case BCM2xxx_UART0:
uart_funcs.uart_init = &pl011_uart_init;
uart_funcs.uart_getchar = &pl011_uart_getchar;
uart_funcs.uart_putchar = &pl011_uart_putchar;
break;

#elif defined(CONFIG_PLAT_BCM2837)

case 0:
Expand Down
Loading