mb/arm/rdn2: Add support for Arm Neoverse N2
Add support for Arm Neoverse N2 Reference design. Based on Arm Neoverse N2 reference design Revision: Release D TEST=Build Arm Neoverse N2 & make sure there is no error. Change-Id: I17908d3ce773d4a88924bafb1d0e9e2a043c7fbc Signed-off-by: Naresh Solanki <naresh.solanki@9elements.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/79103 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Maximilian Brune <maximilian.brune@9elements.com> Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
parent
f6ecfbc12b
commit
6d1dbe12d2
20 changed files with 1179 additions and 0 deletions
18
src/mainboard/arm/Kconfig
Normal file
18
src/mainboard/arm/Kconfig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
## SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
if VENDOR_ARM
|
||||
|
||||
choice
|
||||
prompt "Mainboard model"
|
||||
default BOARD_ARM_RDN2
|
||||
|
||||
source "src/mainboard/arm/*/Kconfig.name"
|
||||
|
||||
endchoice
|
||||
|
||||
source "src/mainboard/arm/*/Kconfig"
|
||||
|
||||
config MAINBOARD_VENDOR
|
||||
default "Arm"
|
||||
|
||||
endif # VENDOR_ARM
|
||||
4
src/mainboard/arm/Kconfig.name
Normal file
4
src/mainboard/arm/Kconfig.name
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
## SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
config VENDOR_ARM
|
||||
bool "Arm"
|
||||
64
src/mainboard/arm/rdn2/Kconfig
Normal file
64
src/mainboard/arm/rdn2/Kconfig
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
if BOARD_ARM_RDN2
|
||||
|
||||
config BOARD_SPECIFIC_OPTIONS
|
||||
def_bool y
|
||||
select ARCH_BOOTBLOCK_ARMV8_64
|
||||
select ARCH_VERSTAGE_ARMV8_64
|
||||
select ARCH_ROMSTAGE_ARMV8_64
|
||||
select ARCH_RAMSTAGE_ARMV8_64
|
||||
select ARM64_USE_ARCH_TIMER
|
||||
select BOARD_ROMSIZE_KB_65536
|
||||
select BOOTBLOCK_CUSTOM
|
||||
select DRIVERS_UART_PL011
|
||||
select HAVE_ACPI_TABLES
|
||||
select ACPI_GTDT
|
||||
select ACPI_COMMON_MADT_GICC_V3
|
||||
select MISSING_BOARD_RESET
|
||||
select PCI
|
||||
select PROBE_RAM
|
||||
select ACPI_IORT
|
||||
select ACPI_GTDT
|
||||
select ACPI_COMMON_MADT_GICC_V3
|
||||
select ACPI_PPTT
|
||||
select GENERATE_SMBIOS_TABLES
|
||||
|
||||
config ARM64_CURRENT_EL
|
||||
default 2
|
||||
|
||||
config ECAM_MMCONF_BASE_ADDRESS
|
||||
default 0x1010000000
|
||||
|
||||
config ECAM_MMCONF_BUS_NUMBER
|
||||
default 256
|
||||
|
||||
config MEMLAYOUT_LD_FILE
|
||||
string
|
||||
default "src/mainboard/arm/rdn2/memlayout.ld"
|
||||
|
||||
config FATAL_ASSERTS
|
||||
default y
|
||||
|
||||
config FMDFILE
|
||||
default "src/mainboard/arm/rdn2/flash.fmd"
|
||||
|
||||
config MAINBOARD_DIR
|
||||
default "arm/rdn2"
|
||||
|
||||
config MAINBOARD_PART_NUMBER
|
||||
default "Neoverse N2"
|
||||
|
||||
config MAX_CPUS
|
||||
int
|
||||
default 128
|
||||
|
||||
config MAINBOARD_VENDOR
|
||||
string
|
||||
default "Arm"
|
||||
|
||||
config DRAM_SIZE_MB
|
||||
int
|
||||
default 2048
|
||||
|
||||
endif # BOARD_ARM_RDN2
|
||||
8
src/mainboard/arm/rdn2/Kconfig.name
Normal file
8
src/mainboard/arm/rdn2/Kconfig.name
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
config BOARD_ARM_RDN2
|
||||
bool "Neoverse N2"
|
||||
help
|
||||
To execute, do:
|
||||
FVP_RD_N2\models\Win64_VC2019\FVP_RD_N2 -C board.flashloader0.fname=coreboot.rom \
|
||||
-C css.trustedBootROMloader.fname=bl1.bin
|
||||
19
src/mainboard/arm/rdn2/Makefile.mk
Normal file
19
src/mainboard/arm/rdn2/Makefile.mk
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
bootblock-y += bootblock.c
|
||||
|
||||
romstage-y += cbmem.c
|
||||
|
||||
bootblock-y += media.c
|
||||
romstage-y += media.c
|
||||
ramstage-y += media.c
|
||||
|
||||
bootblock-y += uart.c
|
||||
romstage-y += uart.c
|
||||
ramstage-y += uart.c
|
||||
ramstage-y += acpi.c
|
||||
ramstage-$(CONFIG_ACPI_PPTT) += pptt.c
|
||||
|
||||
bootblock-y += bootblock_custom.S
|
||||
|
||||
CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include
|
||||
207
src/mainboard/arm/rdn2/acpi.c
Normal file
207
src/mainboard/arm/rdn2/acpi.c
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <acpi/acpi.h>
|
||||
#include <acpi/acpi_iort.h>
|
||||
#include <console/console.h>
|
||||
#include <mainboard/addressmap.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void acpi_fill_fadt(acpi_fadt_t *fadt)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned long acpi_fill_madt(unsigned long current)
|
||||
{
|
||||
return current;
|
||||
}
|
||||
|
||||
uintptr_t platform_get_gicd_base(void)
|
||||
{
|
||||
return RDN2_GIC_DIST;
|
||||
}
|
||||
|
||||
uintptr_t platform_get_gicr_base(void)
|
||||
{
|
||||
return RDN2_GIC_REDIST;
|
||||
}
|
||||
|
||||
void platform_fill_gicc(acpi_madt_gicc_t *gicc)
|
||||
{
|
||||
gicc->physical_base_address = platform_get_gicd_base();
|
||||
gicc->gicv = RDN2_VGIC_BASE;
|
||||
gicc->gich = RDN2_HGIC_BASE;
|
||||
|
||||
if (gicc->mpidr >> 16 == 0xf)
|
||||
gicc->trbe_interrupt = 0x180c;
|
||||
else
|
||||
gicc->trbe_interrupt = 0x500b;
|
||||
}
|
||||
|
||||
static uintptr_t gic_its[] = {
|
||||
RDN2_GIC_ITS(0),
|
||||
RDN2_GIC_ITS(1),
|
||||
RDN2_GIC_ITS(2),
|
||||
RDN2_GIC_ITS(3),
|
||||
RDN2_GIC_ITS(4),
|
||||
RDN2_GIC_ITS(5)
|
||||
};
|
||||
|
||||
int platform_get_gic_its(uintptr_t **base)
|
||||
{
|
||||
*base = gic_its;
|
||||
return ARRAY_SIZE(gic_its);
|
||||
}
|
||||
|
||||
void mainboard_fill_fadt(acpi_fadt_t *fadt)
|
||||
{
|
||||
fadt->preferred_pm_profile = PM_DESKTOP;
|
||||
fadt->ARM_boot_arch = 1;
|
||||
}
|
||||
|
||||
void acpi_soc_fill_gtdt(acpi_gtdt_t *gtdt)
|
||||
{
|
||||
/* his value is optional if the system implements EL3 (Security
|
||||
Extensions). If not provided, this field must be 0xFFFFFFFFFFFFFFFF. */
|
||||
gtdt->counter_block_address = UINT64_MAX;
|
||||
gtdt->secure_el1_interrupt = SEC_EL1_TIMER_GISV;
|
||||
gtdt->secure_el1_flags = RDN2_TIMER_FLAGS;
|
||||
gtdt->non_secure_el1_interrupt = NONSEC_EL1_TIMER_GSIV;
|
||||
gtdt->non_secure_el1_flags = RDN2_TIMER_FLAGS;
|
||||
gtdt->virtual_timer_interrupt = VIRTUAL_TIMER_GSIV;
|
||||
gtdt->virtual_timer_flags = RDN2_TIMER_FLAGS;
|
||||
gtdt->non_secure_el2_interrupt = NONSEC_EL2_TIMER_GSIV;
|
||||
gtdt->non_secure_el2_flags = RDN2_TIMER_FLAGS;
|
||||
/* his value is optional if the system implements EL3
|
||||
(Security Extensions). If not provided, this field must be
|
||||
0xFFFFFFFFFFFFFFF. */
|
||||
gtdt->counter_read_block_address = UINT64_MAX;
|
||||
}
|
||||
|
||||
unsigned long acpi_soc_gtdt_add_timers(uint32_t *count, unsigned long current)
|
||||
{
|
||||
struct acpi_gtdt_timer_entry timers[2];
|
||||
|
||||
memset(timers, 0, sizeof(timers));
|
||||
(*count)++;
|
||||
timers[0].frame_number = 0;
|
||||
timers[0].base_address = RDN2_GT_FRAME1_CTL_BASE;
|
||||
timers[0].el0_base_address = UINT64_MAX;
|
||||
timers[0].timer_interrupt = RDN2_GT_FRAME1_GSIV;
|
||||
timers[0].timer_flags = 0;
|
||||
timers[0].virtual_timer_interrupt = 0;
|
||||
timers[0].virtual_timer_flags = 0;
|
||||
timers[0].common_flags = ACPI_GTDT_GT_ALWAYS_ON;
|
||||
|
||||
|
||||
(*count)++;
|
||||
timers[1].frame_number = 1;
|
||||
timers[1].base_address = RDN2_GT_FRAME0_CTL_BASE;
|
||||
timers[1].el0_base_address = UINT64_MAX;
|
||||
timers[1].timer_interrupt = RDN2_GT_FRAME0_GSIV;
|
||||
timers[1].timer_flags = 0;
|
||||
timers[1].virtual_timer_interrupt = 0;
|
||||
timers[1].virtual_timer_flags = 0;
|
||||
timers[1].common_flags = ACPI_GTDT_GT_ALWAYS_ON | ACPI_GTDT_GT_IS_SECURE_TIMER;
|
||||
|
||||
current = acpi_gtdt_add_timer_block(current, RDN2_GT_CTL_BASE, timers, 2);
|
||||
|
||||
(*count)++;
|
||||
current = acpi_gtdt_add_watchdog(current, RDN2_GWDT_REFRESH, RDN2_GWDT_CONTROL,
|
||||
RDN2_GWDT_WS0_GSIV, 0);
|
||||
/* Secure */
|
||||
current = acpi_gtdt_add_watchdog(current, RDN2_GWDT_REFRESH, RDN2_GWDT_CONTROL,
|
||||
RDN2_GWDT_WS1_GSIV, ACPI_GTDT_WATCHDOG_SECURE);
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
static unsigned long acpi_soc_fill_iort_tcu4(acpi_iort_t *iort, unsigned long current)
|
||||
{
|
||||
acpi_iort_node_t *its, *smmu_v3, *named_comp;
|
||||
u32 identifiers[] = {4};
|
||||
u32 its_reference, smmuv3_reference;
|
||||
|
||||
current = acpi_iort_its_entry(current, iort, &its, 1, identifiers);
|
||||
its_reference = (unsigned long)its - (unsigned long)iort;
|
||||
|
||||
current = acpi_iort_smmuv3_entry(current, iort, &smmu_v3, RDN2_SMMU_V3(4), ACPI_IORT_SMMU_V3_FLAGS);
|
||||
smmuv3_reference = (unsigned long)smmu_v3 - (unsigned long)iort;
|
||||
|
||||
/* Individual maps here */
|
||||
current = acpi_iort_id_map_entry(current, smmu_v3, 0, 1, 0x80000, its_reference,
|
||||
ACPI_IORT_ID_SINGLE_MAPPING);
|
||||
|
||||
current = acpi_iort_id_map_entry(current, smmu_v3, 0x10000, 10, 0x10000, its_reference, 0);
|
||||
|
||||
current = acpi_iort_id_map_entry(current, smmu_v3, 0x30000, 10, 0x30000, its_reference, 0);
|
||||
|
||||
/* SMMUV3 entry length includes mapping */
|
||||
|
||||
for (int n = 0 ; n < 2 ; n++) {
|
||||
/* DMA */
|
||||
char dma[32];
|
||||
snprintf(dma, sizeof(dma), "\\_SB_.DMA%d", n);
|
||||
|
||||
current = acpi_iort_nc_entry(current, iort, &named_comp, 0, 0, 0x30, dma);
|
||||
|
||||
for (int i = 0 ; i < 9 ; i++) {
|
||||
/* ID */
|
||||
current = acpi_iort_id_map_entry(current, named_comp, i, 1, 0x10000 + n * 0x20000 + i,
|
||||
smmuv3_reference, ACPI_IORT_ID_SINGLE_MAPPING);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
static unsigned long acpi_soc_fill_iort_tcu(u32 i, u16 id_count, u32 *smmu_offset,
|
||||
acpi_iort_t *iort, unsigned long current)
|
||||
{
|
||||
|
||||
acpi_iort_node_t *its, *smmu_v3;
|
||||
static u32 id_base = 0x30000;
|
||||
u32 its_reference;
|
||||
|
||||
current = acpi_iort_its_entry(current, iort, &its, 1, &i);
|
||||
its_reference = (unsigned long)its - (unsigned long)iort;
|
||||
|
||||
current = acpi_iort_smmuv3_entry(current, iort, &smmu_v3, RDN2_SMMU_V3(i), ACPI_IORT_SMMU_V3_FLAGS);
|
||||
|
||||
*smmu_offset = (unsigned long)smmu_v3 - (unsigned long)iort;
|
||||
|
||||
/* Individual maps here */
|
||||
current = acpi_iort_id_map_entry(current, smmu_v3, 0, 1, 0x80000, its_reference,
|
||||
ACPI_IORT_ID_SINGLE_MAPPING);
|
||||
|
||||
current = acpi_iort_id_map_entry(current, smmu_v3, id_base, id_count, id_base, its_reference, 0);
|
||||
id_base += id_count;
|
||||
|
||||
/* SMMUV3 entry length includes mapping */
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
unsigned long acpi_soc_fill_iort(acpi_iort_t *iort, unsigned long current)
|
||||
{
|
||||
acpi_iort_node_t *root_comp;
|
||||
u32 smmu_offset[4];
|
||||
uint32_t id_count[] = {768, 256, 256, 256};
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
current = acpi_soc_fill_iort_tcu(i, id_count[i], &smmu_offset[i], iort, current);
|
||||
|
||||
current = acpi_soc_fill_iort_tcu4(iort, current);
|
||||
|
||||
current = acpi_iort_rc_entry(current, iort, &root_comp, 0, ACPI_IORT_ATS_SUPPORTED, 0,
|
||||
0x30, 0);
|
||||
|
||||
u32 base = 0;
|
||||
for (int i = 0 ; i < 4 ; i++) {
|
||||
current = acpi_iort_id_map_entry(current, root_comp, base, id_count[i], 0x30000 + base,
|
||||
smmu_offset[i], 0);
|
||||
base += id_count[i];
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
3
src/mainboard/arm/rdn2/board_info.txt
Normal file
3
src/mainboard/arm/rdn2/board_info.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
Board name: Neoverse N2
|
||||
Category: emulation
|
||||
Board URL: https://developer.arm.com/documentation/102337/latest/
|
||||
37
src/mainboard/arm/rdn2/bootblock.c
Normal file
37
src/mainboard/arm/rdn2/bootblock.c
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <arch/mmu.h>
|
||||
#include <bootblock_common.h>
|
||||
#include <console/console.h>
|
||||
#include <mainboard/addressmap.h>
|
||||
#include <symbols.h>
|
||||
|
||||
DECLARE_REGION(dev_mem)
|
||||
|
||||
void bootblock_mainboard_init(void)
|
||||
{
|
||||
mmu_init();
|
||||
|
||||
/* NOR Flash 0 */
|
||||
mmu_config_range((void *)RDN2_FLASH_BASE, (uintptr_t)RDN2_FLASH_SIZE,
|
||||
MA_MEM | MA_RO | MA_MEM_NC);
|
||||
|
||||
/* device memory */
|
||||
mmu_config_range(_dev_mem, _dram - _dev_mem, MA_DEV | MA_RW);
|
||||
|
||||
/* Set a dummy value for DRAM. ramstage should update the mapping. */
|
||||
mmu_config_range(_dram, ((size_t) 2 * GiB) - 16*MiB, MA_MEM | MA_RW);
|
||||
|
||||
mmu_config_range((void *)RDN2_DRAM2_BASE, RDN2_DRAM2_SIZE, MA_MEM | MA_RW);
|
||||
|
||||
mmu_config_range(_ttb, REGION_SIZE(ttb), MA_MEM | MA_S | MA_RW);
|
||||
|
||||
mmu_config_range(_stack, REGION_SIZE(stack), MA_MEM | MA_S | MA_RW);
|
||||
mmu_config_range(_cbfs_mcache, REGION_SIZE(cbfs_mcache), MA_MEM | MA_S | MA_RW);
|
||||
mmu_config_range(_fmap_cache, REGION_SIZE(fmap_cache), MA_MEM | MA_S | MA_RW);
|
||||
mmu_config_range(_timestamp, REGION_SIZE(timestamp), MA_MEM | MA_S | MA_RW);
|
||||
|
||||
mmu_config_range((void *)CONFIG_ECAM_MMCONF_BASE_ADDRESS, CONFIG_ECAM_MMCONF_LENGTH,
|
||||
MA_DEV | MA_RW);
|
||||
mmu_enable();
|
||||
}
|
||||
31
src/mainboard/arm/rdn2/bootblock_custom.S
Normal file
31
src/mainboard/arm/rdn2/bootblock_custom.S
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <arch/asm.h>
|
||||
|
||||
/*
|
||||
* Note: This board uses boot flow: TFA -> coreboot.
|
||||
*/
|
||||
ENTRY(_start)
|
||||
|
||||
/* TF-A arg which contains a pointer to fdt */
|
||||
ldr x1, =_fdt_pointer
|
||||
str x0, [x1]
|
||||
|
||||
msr SPSel, #0 /* use SP_EL0 */
|
||||
|
||||
/* ==== stack init from arm64_init_cpu ==== */
|
||||
ldr x2, =0xdeadbeefdeadbeef
|
||||
ldr x0, =_stack
|
||||
ldr x1, =_estack
|
||||
1:
|
||||
stp x2, x2, [x0], #16
|
||||
cmp x0, x1
|
||||
bne 1b
|
||||
|
||||
sub sp, x0, #16
|
||||
|
||||
/* ==== END ==== */
|
||||
|
||||
/* Jump to main() in DRAM. */
|
||||
bl main
|
||||
ENDPROC(_start)
|
||||
11
src/mainboard/arm/rdn2/cbmem.c
Normal file
11
src/mainboard/arm/rdn2/cbmem.c
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <cbmem.h>
|
||||
#include <console/console.h>
|
||||
#include <ramdetect.h>
|
||||
#include <symbols.h>
|
||||
|
||||
uintptr_t cbmem_top_chipset(void)
|
||||
{
|
||||
return (uintptr_t)_dram + (probe_ramsize((uintptr_t)_dram, CONFIG_DRAM_SIZE_MB) * MiB);
|
||||
}
|
||||
11
src/mainboard/arm/rdn2/chip.h
Normal file
11
src/mainboard/arm/rdn2/chip.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifndef MAINBOARD_ARM_RDN2_CHIP_H
|
||||
#define MAINBOARD_ARM_RDN2_CHIP_H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
struct mainboard_arm_rdn2_config {
|
||||
};
|
||||
|
||||
#endif
|
||||
10
src/mainboard/arm/rdn2/devicetree.cb
Normal file
10
src/mainboard/arm/rdn2/devicetree.cb
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
chip mainboard/arm/rdn2
|
||||
|
||||
device cpu_cluster 0 on ops rdn2_aarch64_cpu_ops end
|
||||
|
||||
device domain 0 on ops rdn2_aarch64_pci_domain_ops
|
||||
device pci 00.0 on end
|
||||
end
|
||||
end
|
||||
227
src/mainboard/arm/rdn2/dsdt.asl
Normal file
227
src/mainboard/arm/rdn2/dsdt.asl
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <acpi/acpi.h>
|
||||
#include <mainboard/addressmap.h>
|
||||
DefinitionBlock(
|
||||
"dsdt.aml",
|
||||
"DSDT",
|
||||
ACPI_DSDT_REV_2,
|
||||
OEM_ID,
|
||||
ACPI_TABLE_CREATOR,
|
||||
0x20230621 // OEM revision
|
||||
)
|
||||
{
|
||||
#include <acpi/dsdt_top.asl>
|
||||
|
||||
Device (COM0)
|
||||
{
|
||||
Name (_HID, "ARMH0011") // _HID: Hardware ID
|
||||
Name (_UID, Zero) // _UID: Unique ID
|
||||
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
|
||||
{
|
||||
Memory32Fixed (ReadWrite,
|
||||
RDN2_UART_NS_BASE, // Address Base
|
||||
0x00001000, // Address Length
|
||||
)
|
||||
Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
|
||||
{
|
||||
RDN2_UART_NS_GSIV,
|
||||
}
|
||||
})
|
||||
Method (_STA, 0, NotSerialized) // _STA: Status
|
||||
{
|
||||
Return (0xf)
|
||||
}
|
||||
}
|
||||
|
||||
Device (VR00)
|
||||
{
|
||||
Name (_HID, "LNRO0005") // _HID: Hardware ID
|
||||
Name (_UID, Zero) // _UID: Unique ID
|
||||
Name (_CCA, One) // _CCA: Cache Coherency Attribute
|
||||
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
|
||||
{
|
||||
Memory32Fixed (ReadWrite,
|
||||
0x0C130000, // Address Base
|
||||
0x00010000, // Address Length
|
||||
)
|
||||
Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
|
||||
{
|
||||
0x000001CA,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Device (VR01)
|
||||
{
|
||||
Name (_HID, "LNRO0005") // _HID: Hardware ID
|
||||
Name (_UID, One) // _UID: Unique ID
|
||||
Name (_CCA, One) // _CCA: Cache Coherency Attribute
|
||||
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
|
||||
{
|
||||
Memory32Fixed (ReadWrite,
|
||||
0x0C150000, // Address Base
|
||||
0x00010000, // Address Length
|
||||
)
|
||||
Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
|
||||
{
|
||||
0x000001CC,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Device (\_SB.DMA0)
|
||||
{
|
||||
Name (_HID, "ARMH0330") // _HID: Hardware ID
|
||||
Name (_UID, Zero) // _UID: Unique ID
|
||||
Name (_CCA, One) // _CCA: Cache Coherency Attribute
|
||||
Name (_STA, 0x0F) // _STA: Status
|
||||
Method (_CRS, 0, Serialized) // _CRS: Current Resource Settings
|
||||
{
|
||||
Name (RBUF, ResourceTemplate ()
|
||||
{
|
||||
QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
|
||||
0x0000000000000000, // Granularity
|
||||
0x0000000000000000, // Range Minimum
|
||||
0x0000000000000001, // Range Maximum
|
||||
0x0000000000000000, // Translation Offset
|
||||
0x0000000000000002, // Length
|
||||
,, _Y02, AddressRangeMemory, TypeStatic)
|
||||
Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
|
||||
{
|
||||
0x000001ED,
|
||||
0x000001EE,
|
||||
0x000001EF,
|
||||
0x000001F0,
|
||||
0x000001F1,
|
||||
0x000001F2,
|
||||
0x000001F3,
|
||||
0x000001F4,
|
||||
0x000001F5,
|
||||
}
|
||||
})
|
||||
CreateQWordField (RBUF, \_SB.DMA0._CRS._Y02._MIN, MIN2) // _MIN: Minimum Base Address
|
||||
CreateQWordField (RBUF, \_SB.DMA0._CRS._Y02._MAX, MAX2) // _MAX: Maximum Base Address
|
||||
CreateQWordField (RBUF, \_SB.DMA0._CRS._Y02._LEN, LEN2) // _LEN: Length
|
||||
MIN2 = RDN2_DMA0_BASE
|
||||
MAX2 = (MIN2 + 0xFFFF)
|
||||
LEN2 = 0x00010000
|
||||
Return (RBUF) /* \_SB_.DMA0._CRS.RBUF */
|
||||
}
|
||||
}
|
||||
|
||||
Device (\_SB.DMA1)
|
||||
{
|
||||
Name (_HID, "ARMH0330") // _HID: Hardware ID
|
||||
Name (_UID, One) // _UID: Unique ID
|
||||
Name (_CCA, One) // _CCA: Cache Coherency Attribute
|
||||
Name (_STA, 0x0F) // _STA: Status
|
||||
Method (_CRS, 0, Serialized) // _CRS: Current Resource Settings
|
||||
{
|
||||
Name (RBUF, ResourceTemplate ()
|
||||
{
|
||||
QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
|
||||
0x0000000000000000, // Granularity
|
||||
0x0000000000000000, // Range Minimum
|
||||
0x0000000000000001, // Range Maximum
|
||||
0x0000000000000000, // Translation Offset
|
||||
0x0000000000000002, // Length
|
||||
,, _Y03, AddressRangeMemory, TypeStatic)
|
||||
Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
|
||||
{
|
||||
0x000001F7,
|
||||
0x000001F8,
|
||||
0x000001F9,
|
||||
0x000001FA,
|
||||
0x000001FB,
|
||||
0x000001FC,
|
||||
0x000001FD,
|
||||
0x000001FE,
|
||||
0x000001FF,
|
||||
}
|
||||
})
|
||||
CreateQWordField (RBUF, \_SB.DMA1._CRS._Y03._MIN, MIN2) // _MIN: Minimum Base Address
|
||||
CreateQWordField (RBUF, \_SB.DMA1._CRS._Y03._MAX, MAX2) // _MAX: Maximum Base Address
|
||||
CreateQWordField (RBUF, \_SB.DMA1._CRS._Y03._LEN, LEN2) // _LEN: Length
|
||||
MIN2 = RDN2_DMA1_BASE
|
||||
MAX2 = (MIN2 + 0xFFFF)
|
||||
LEN2 = 0x00010000
|
||||
Return (RBUF) /* \_SB_.DMA1._CRS.RBUF */
|
||||
}
|
||||
}
|
||||
Device (PCI0)
|
||||
{
|
||||
Name (_HID, EisaId ("PNP0A08")) // PCI Express Bus _HID: Hardware ID
|
||||
Name (_CID, EisaId ("PNP0A03")) // PCI Bus _CID: Compatible ID
|
||||
Name (_SEG, Zero) // _SEG: PCI Segment
|
||||
Name (_BBN, Zero) // _BBN: BIOS Bus Number
|
||||
Name (_UID, "PCI0") // _UID: Unique ID
|
||||
Name (_CCA, One) // _CCA: Cache Coherency Attribute
|
||||
|
||||
Method (_STA, 0, NotSerialized) // _STA: Status
|
||||
{
|
||||
Return (0xf)
|
||||
}
|
||||
|
||||
Method (_CBA, 0, NotSerialized) // _CBA: Configuration Base Address
|
||||
{
|
||||
Return (RDN2_PCIE_ECAM_BASE)
|
||||
}
|
||||
|
||||
Method (_CRS, 0, Serialized) // _CRS: Current Resource Settings
|
||||
{
|
||||
Name (RBUF, ResourceTemplate ()
|
||||
{
|
||||
WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
|
||||
0x0000, // Granularity
|
||||
0x0000, // Range Minimum
|
||||
0x00FF, // Range Maximum
|
||||
0x0000, // Translation Offset
|
||||
0x0100, // Length
|
||||
,, )
|
||||
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
|
||||
0x00000000, // Granularity
|
||||
RDN2_PCIE_MMIO_BASE, // Range Minimum
|
||||
RDN2_PCIE_MMIO_LIMIT, // Range Maximum
|
||||
0x00000000, // Translation Offset
|
||||
RDN2_PCIE_MMIO_SIZE, // Length
|
||||
,, , AddressRangeMemory, TypeStatic)
|
||||
QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
|
||||
0x0000000000000000, // Granularity
|
||||
RDN2_PCIE_MMIO_HIGH_BASE, // Range Minimum
|
||||
RDN2_PCIE_MMIO_HIGH_LIMIT, // Range Maximum
|
||||
0x0000000000000000, // Translation Offset
|
||||
RDN2_PCIE_MMIO_HIGH_SIZE, // Length
|
||||
,, , AddressRangeMemory, TypeStatic)
|
||||
DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
|
||||
0x00000000, // Granularity
|
||||
0x00000000, // Range Minimum
|
||||
0x007FFFFF, // Range Maximum
|
||||
0x77800000, // Translation Offset
|
||||
0x00800000, // Length
|
||||
,, , TypeTranslation, DenseTranslation)
|
||||
})
|
||||
Return (RBUF) /* \PCI0._CRS.RBUF */
|
||||
}
|
||||
|
||||
Device (RES0)
|
||||
{
|
||||
Name (_HID, "PNP0C02" /* PNP Motherboard Resources */) // _HID: Hardware ID
|
||||
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
|
||||
{
|
||||
QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
|
||||
0x0000000000000000, // Granularity
|
||||
RDN2_PCIE_ECAM_BASE, // Range Minimum
|
||||
RDN2_PCIE_ECAM_LIMIT, // Range Maximum
|
||||
0x0000000000000000, // Translation Offset
|
||||
RDN2_PCIE_ECAM_SIZE, // Length
|
||||
,, , AddressRangeMemory, TypeStatic)
|
||||
})
|
||||
Method (_STA, 0, NotSerialized) // _STA: Status
|
||||
{
|
||||
Return (0xf)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
9
src/mainboard/arm/rdn2/flash.fmd
Normal file
9
src/mainboard/arm/rdn2/flash.fmd
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
FLASH@0x08000000 CONFIG_ROM_SIZE {
|
||||
|
||||
BIOS@0x0 CONFIG_ROM_SIZE {
|
||||
|
||||
BOOTBLOCK 128K
|
||||
FMAP@0x20000 0x200
|
||||
COREBOOT(CBFS)
|
||||
}
|
||||
}
|
||||
97
src/mainboard/arm/rdn2/include/mainboard/addressmap.h
Normal file
97
src/mainboard/arm/rdn2/include/mainboard/addressmap.h
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/*
|
||||
* Memory map for Neoverse N2
|
||||
* See Technical Reference: Table 5-2: FVP board peripherals
|
||||
*/
|
||||
|
||||
#define RDN2_FLASH_BASE 0x08000000
|
||||
#define RDN2_FLASH_SIZE (64 * MiB)
|
||||
|
||||
/* Actual DRAM size should be probed */
|
||||
#define RDN2_DRAM_BASE 0x80000000
|
||||
#define RDN2_DRAM_SIZE (2 * GiB)
|
||||
|
||||
#define RDN2_SECMEM_BASE 0xff000000
|
||||
#define RDN2_SECMEM_SIZE (16 * MiB)
|
||||
|
||||
#define RDN2_DRAM2_BASE 0x8080000000
|
||||
#define RDN2_DRAM2_SIZE (6UL * GiB)
|
||||
|
||||
#define RDN2_GIC_DIST 0x30000000
|
||||
#define RDN2_GIC_REDIST 0x301C0000
|
||||
#define RDN2_VGIC_BASE 0x2c020000
|
||||
#define RDN2_HGIC_BASE 0x2c010000
|
||||
|
||||
#define RDN2_GIC_ITS_BASE 0x30040000
|
||||
#define RDN2_GIC_ITS_SIZE 0x40000
|
||||
#define RDN2_GIC_ITS(i) (RDN2_GIC_ITS_BASE + i * RDN2_GIC_ITS_SIZE)
|
||||
|
||||
#define SEC_EL1_TIMER_GISV 29
|
||||
#define NONSEC_EL1_TIMER_GSIV 30
|
||||
#define VIRTUAL_TIMER_GSIV 27
|
||||
#define NONSEC_EL2_TIMER_GSIV 26
|
||||
|
||||
#define RDN2_TIMER_FLAGS (ACPI_GTDT_INTERRUPT_POLARITY)
|
||||
#define RDN2_GT_CTL_BASE 0x2A810000
|
||||
#define RDN2_GT_FRAME0_CTL_BASE 0x2A820000
|
||||
#define RDN2_GT_FRAME0_EL0_BASE -1
|
||||
#define RDN2_GT_FRAME0_GSIV 0x6c
|
||||
|
||||
#define RDN2_GT_FRAME1_CTL_BASE 0x2A830000
|
||||
#define RDN2_GT_FRAME1_EL0_BASE -1
|
||||
#define RDN2_GT_FRAME1_GSIV 0x6d
|
||||
|
||||
#define RDN2_GWDT_REFRESH 0x2a450000
|
||||
#define RDN2_GWDT_CONTROL 0x2a440000
|
||||
#define RDN2_GWDT_WS0_GSIV 0x6e
|
||||
#define RDN2_GWDT_WS1_GSIV 0x6f
|
||||
|
||||
#define RDN2_UART_CLK_HZ 7372800
|
||||
#define RDN2_UART_NS_BASE 0x2a400000
|
||||
#define RDN2_UART_NS_GSIV 112
|
||||
#define RDN2_SECURE_UART_BASE 0x2a410000
|
||||
#define RDN2_SECURE_UART_GSIV 81
|
||||
|
||||
#define RDN2_RTC_BASE 0x0C170000
|
||||
#define RDN2_RTC1_BASE 0x0C180000
|
||||
#define RDN2_GPIO_BASE 0x0c1d0000
|
||||
#define RDN2_GPIO1_BASE 0x0c1e0000
|
||||
|
||||
#define RDN2_SMMU_BASE 0x40000000
|
||||
#define RDN2_SMMU_SIZE 0x2000000
|
||||
|
||||
|
||||
|
||||
|
||||
#define RDN2_SMMU_V3(i) (RDN2_SMMU_BASE + i * RDN2_SMMU_SIZE)
|
||||
#define ACPI_IORT_SMMU_V3_FLAGS (ACPI_IORT_SMMU_V3_COHACC_OVERRIDE | ACPI_IORT_SMMU_V3_DEVICEID_VALID)
|
||||
|
||||
#define RDN2_DMA0_BASE 0x1090000000
|
||||
#define RDN2_DMA1_BASE 0x10B0000000
|
||||
/* Virtio block device */
|
||||
#define RDN2_AHCI_BASE 0x0C130000
|
||||
#define RDN2_AHCI_INT 458
|
||||
|
||||
/* Virtio net */
|
||||
#define RDN2_VNET_BASE 0x0C150000
|
||||
#define RDN2_VNET_INT 460
|
||||
|
||||
/* Arm Dual-Timer Module */
|
||||
#define RDN2_DUAL_TIMER 0x0C110000
|
||||
#define RDN2_DUAL_TIMER_INT 486
|
||||
|
||||
#define RDN2_GPIO0 0x0C1D0000
|
||||
#define RDN2_GPIO0_INT 392
|
||||
|
||||
#define RDN2_EHCI_BASE 0x60110000
|
||||
|
||||
#define RDN2_PCIE_MMIO_BASE 0x60000000
|
||||
#define RDN2_PCIE_MMIO_LIMIT 0x7fffffff
|
||||
#define RDN2_PCIE_MMIO_SIZE 0x20000000
|
||||
#define RDN2_PCIE_ECAM_BASE 0x1010000000
|
||||
#define RDN2_PCIE_ECAM_LIMIT 0x101FFFFFFF
|
||||
#define RDN2_PCIE_ECAM_SIZE 0x10000000
|
||||
#define RDN2_PCIE_MMIO_HIGH_BASE 0x4000000000
|
||||
#define RDN2_PCIE_MMIO_HIGH_LIMIT 0x807fffffff
|
||||
#define RDN2_PCIE_MMIO_HIGH_SIZE 0x4080000000
|
||||
156
src/mainboard/arm/rdn2/mainboard.c
Normal file
156
src/mainboard/arm/rdn2/mainboard.c
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "chip.h"
|
||||
#include <acpi/acpigen.h>
|
||||
#include <arch/mmu.h>
|
||||
#include <bootmem.h>
|
||||
#include <cbfs.h>
|
||||
#include <device/device.h>
|
||||
#include <mainboard/addressmap.h>
|
||||
#include <ramdetect.h>
|
||||
#include <stdint.h>
|
||||
#include <symbols.h>
|
||||
|
||||
static size_t ram_size(void)
|
||||
{
|
||||
return (size_t)cbmem_top() - (uintptr_t)_dram;
|
||||
}
|
||||
|
||||
static size_t ram2_size(void)
|
||||
{
|
||||
return (size_t)probe_ramsize((uintptr_t)RDN2_DRAM2_BASE, RDN2_DRAM2_SIZE) * MiB;
|
||||
}
|
||||
|
||||
static void mainboard_init(void *chip_info)
|
||||
{
|
||||
mmu_config_range(_dram, ram_size(), MA_MEM | MA_RW);
|
||||
mmu_config_range((void *)RDN2_DRAM2_BASE, ram2_size(), MA_MEM | MA_RW);
|
||||
}
|
||||
|
||||
DECLARE_REGION(fdt_pointer)
|
||||
|
||||
void smbios_cpu_get_core_counts(u16 *core_count, u16 *thread_count)
|
||||
{
|
||||
*core_count = 0;
|
||||
struct device *dev = NULL;
|
||||
while ((dev = dev_find_path(dev, DEVICE_PATH_GICC_V3)))
|
||||
*core_count += 1;
|
||||
|
||||
*thread_count = 1;
|
||||
}
|
||||
|
||||
|
||||
static void rdn2_aarch64_init(struct device *dev)
|
||||
{
|
||||
struct memory_info *mem_info;
|
||||
|
||||
mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
|
||||
if (mem_info == NULL)
|
||||
return;
|
||||
|
||||
memset(mem_info, 0, sizeof(*mem_info));
|
||||
|
||||
mem_info->ecc_type = MEMORY_ARRAY_ECC_UNKNOWN;
|
||||
mem_info->max_capacity_mib = 0x800000;
|
||||
mem_info->number_of_devices = mem_info->dimm_cnt = 1;
|
||||
|
||||
mem_info->dimm[0].dimm_size = (ram_size() + ram2_size()) / MiB;
|
||||
mem_info->dimm[0].ddr_type = MEMORY_TYPE_DRAM;
|
||||
mem_info->dimm[0].ddr_frequency = 0;
|
||||
mem_info->dimm[0].channel_num = mem_info->dimm[0].dimm_num = 0;
|
||||
mem_info->dimm[0].bank_locator = 0;
|
||||
|
||||
mem_info->dimm[0].bus_width = 0x03; // 64-bit, no parity
|
||||
mem_info->dimm[0].vdd_voltage = 0;
|
||||
mem_info->dimm[0].max_speed_mts = mem_info->dimm[0].configured_speed_mts = 0;
|
||||
}
|
||||
|
||||
static unsigned long mb_write_acpi_tables(const struct device *dev, unsigned long current,
|
||||
acpi_rsdp_t *rsdp)
|
||||
{
|
||||
printk(BIOS_DEBUG, "ACPI: * DBG2\n");
|
||||
return acpi_pl011_write_dbg2_uart(rsdp, current, RDN2_UART_NS_BASE, "\\_SB.COM0");
|
||||
}
|
||||
|
||||
|
||||
static void mainboard_enable(struct device *dev)
|
||||
{
|
||||
dev->ops->init = rdn2_aarch64_init;
|
||||
dev->ops->write_acpi_tables = mb_write_acpi_tables;
|
||||
}
|
||||
|
||||
|
||||
struct chip_operations mainboard_ops = {
|
||||
.init = mainboard_init,
|
||||
.enable_dev = mainboard_enable,
|
||||
};
|
||||
|
||||
struct chip_operations mainboard_arm_rdn2_ops = { };
|
||||
|
||||
static void rdn2_aarch64_domain_read_resources(struct device *dev)
|
||||
{
|
||||
struct resource *res;
|
||||
int index = 0;
|
||||
|
||||
/* Initialize the system-wide I/O space constraints. */
|
||||
res = new_resource(dev, index++);
|
||||
res->limit = 0xffffUL;
|
||||
res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED;
|
||||
|
||||
/* Initialize the system-wide memory resources constraints. */
|
||||
res = new_resource(dev, index++);
|
||||
res->base = RDN2_PCIE_MMIO_BASE;
|
||||
res->limit = RDN2_PCIE_MMIO_LIMIT;
|
||||
res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED;
|
||||
|
||||
res = new_resource(dev, index++);
|
||||
res->base = RDN2_PCIE_MMIO_HIGH_BASE;
|
||||
res->limit = RDN2_PCIE_MMIO_HIGH_LIMIT;
|
||||
res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED;
|
||||
|
||||
ram_range(dev, index++, (uintptr_t)_dram, ram_size());
|
||||
reserved_ram_range(dev, index++, (uintptr_t)RDN2_SECMEM_BASE, RDN2_SECMEM_SIZE);
|
||||
|
||||
ram_range(dev, index++, (uintptr_t)RDN2_DRAM2_BASE, ram2_size());
|
||||
|
||||
mmio_range(dev, index++, RDN2_FLASH_BASE, RDN2_FLASH_SIZE);
|
||||
}
|
||||
|
||||
struct device_operations rdn2_aarch64_pci_domain_ops = {
|
||||
.read_resources = rdn2_aarch64_domain_read_resources,
|
||||
.set_resources = pci_domain_set_resources,
|
||||
.scan_bus = pci_host_bridge_scan_bus,
|
||||
};
|
||||
|
||||
static void rdn2_fill_cpu_ssdt(const struct device *dev)
|
||||
{
|
||||
acpigen_write_processor_device(dev->path.gicc_v3.mpidr);
|
||||
acpigen_write_processor_device_end();
|
||||
}
|
||||
|
||||
struct device_operations rdn2_cpu_ops = {
|
||||
.acpi_fill_ssdt = rdn2_fill_cpu_ssdt,
|
||||
};
|
||||
|
||||
static void rdn2_aarch64_scan_bus(struct device *dev)
|
||||
{
|
||||
u16 i = 0;
|
||||
struct bus *bus = alloc_bus(dev);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
printk(BIOS_DEBUG, "Allocating CPU %d\n", i);
|
||||
struct device_path devpath = { .type = DEVICE_PATH_GICC_V3,
|
||||
.gicc_v3 = { .mpidr = i << 16,
|
||||
.vgic_mi = 0x19,
|
||||
.pi_gsiv = 0x17, },
|
||||
};
|
||||
struct device *cpu = alloc_dev(bus, &devpath);
|
||||
assert(cpu);
|
||||
cpu->ops = &rdn2_cpu_ops;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct device_operations rdn2_aarch64_cpu_ops = {
|
||||
.scan_bus = rdn2_aarch64_scan_bus,
|
||||
};
|
||||
13
src/mainboard/arm/rdn2/media.c
Normal file
13
src/mainboard/arm/rdn2/media.c
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <boot_device.h>
|
||||
#include <mainboard/addressmap.h>
|
||||
|
||||
/* Maps directly to NOR flash up to ROM size. */
|
||||
static const struct mem_region_device boot_dev =
|
||||
MEM_REGION_DEV_RO_INIT((void *)RDN2_FLASH_BASE, RDN2_FLASH_SIZE);
|
||||
|
||||
const struct region_device *boot_device_ro(void)
|
||||
{
|
||||
return &boot_dev.rdev;
|
||||
}
|
||||
27
src/mainboard/arm/rdn2/memlayout.ld
Normal file
27
src/mainboard/arm/rdn2/memlayout.ld
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <memlayout.h>
|
||||
#include <arch/header.ld>
|
||||
|
||||
/*
|
||||
* Memory map for Neoverse N2
|
||||
* See Technical Reference: Table 5-2: FVP board peripherals
|
||||
*/
|
||||
SECTIONS
|
||||
{
|
||||
REGION(flash, 0x8000000, CONFIG_ROM_SIZE, 8)
|
||||
|
||||
REGION(dev_mem, 0x0c010000, 2M, 8)
|
||||
DRAM_START(0x80000000)
|
||||
BOOTBLOCK(0xe0000000, 64K)
|
||||
STACK(0xe0010000, 64K)
|
||||
CBFS_MCACHE(0xe0020000, 8K)
|
||||
FMAP_CACHE(0xe0022000 , 4K)
|
||||
TIMESTAMP(0xe0023000, 4K)
|
||||
ROMSTAGE(0xe0024000, 128K)
|
||||
TTB(0xe0060000, 128K)
|
||||
RAMSTAGE(0xe00a0000, 16M)
|
||||
REGION(fdt_pointer, 0xe10a0000, ARCH_POINTER_ALIGN_SIZE, ARCH_POINTER_ALIGN_SIZE)
|
||||
|
||||
POSTRAM_CBFS_CACHE(0xe11f0000, 1M)
|
||||
}
|
||||
218
src/mainboard/arm/rdn2/pptt.c
Normal file
218
src/mainboard/arm/rdn2/pptt.c
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <cpu/cpu.h>
|
||||
#include <arch/cache.h>
|
||||
#include <acpi/acpi.h>
|
||||
#include <console/console.h>
|
||||
|
||||
#define CACHE_NODE_FLAGS 0xd7 // everything valid except, write-policy and allocation type
|
||||
#define CLUSTER_FLAGS 0x11 // physical package, ID invalid, no thread, no leaf, identical impl.
|
||||
#define CORE_FLAGS 0x0a // no physical package, ID valid, no thread, leaf.
|
||||
#define CORE_FLAGS_1 0x12 // no physical package, ID valid, no thread, identical i.
|
||||
|
||||
/*
|
||||
* L2 cache (LLC)
|
||||
*/
|
||||
struct pptt_cache l2 = {
|
||||
|
||||
.next_level = NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* L1D cache
|
||||
*/
|
||||
struct pptt_cache l1d = {
|
||||
.next_level = &l2
|
||||
};
|
||||
|
||||
/*
|
||||
* L1I cache
|
||||
*/
|
||||
struct pptt_cache l1i = {
|
||||
//.sibling = &l1d,
|
||||
.next_level = &l2
|
||||
};
|
||||
|
||||
/*
|
||||
* private resources of a cpu core. Same for
|
||||
* each core, thus we can reuse this struture
|
||||
* instead of creating it dynamically.
|
||||
*/
|
||||
struct pptt_cpu_resources core_resources = {
|
||||
.cache = &l1i,
|
||||
};
|
||||
|
||||
struct pptt_topology root_topology = {
|
||||
|
||||
.flags.raw = CLUSTER_FLAGS,
|
||||
.resources = NULL,
|
||||
.sibling = NULL,
|
||||
|
||||
.child = &(struct pptt_topology) {
|
||||
|
||||
.processor_id = 0,
|
||||
.flags.raw = CORE_FLAGS_1,
|
||||
|
||||
.resources = NULL,
|
||||
|
||||
.child = &(struct pptt_topology) {
|
||||
.processor_id = 0,
|
||||
.flags.raw = CORE_FLAGS,
|
||||
|
||||
.resources = &(struct pptt_cpu_resources) {
|
||||
|
||||
.cache = &l1i,
|
||||
|
||||
},
|
||||
|
||||
.sibling = NULL,
|
||||
.child = NULL,
|
||||
},
|
||||
.sibling = NULL, // updated in runtime
|
||||
}
|
||||
};
|
||||
|
||||
/* --- Helpers --- */
|
||||
|
||||
static u8 cache_attributes(const enum cache_type type)
|
||||
{
|
||||
/*
|
||||
* 'write-policy' and 'allocation type' currently
|
||||
* unsupported. cache flags set accordingly.
|
||||
*
|
||||
* maybe a todo for the future.
|
||||
*/
|
||||
|
||||
u8 attr = 0x0;
|
||||
|
||||
if (type == CACHE_INSTRUCTION)
|
||||
attr |= (0x1 << 2);
|
||||
else if (type == CACHE_UNIFIED)
|
||||
attr |= (0x1 << 3);
|
||||
|
||||
return attr;
|
||||
}
|
||||
|
||||
/* --- ACPI hook --- */
|
||||
|
||||
struct pptt_topology *acpi_get_pptt_topology(void)
|
||||
{
|
||||
struct cache_info info;
|
||||
|
||||
/* Dump Cache info */
|
||||
for (int cache_level = CACHE_L1; cache_level <= CACHE_L7; cache_level++) {
|
||||
int cache_type = cpu_get_cache_type(cache_level);
|
||||
if (cache_type == NO_CACHE)
|
||||
continue;
|
||||
|
||||
if (cache_type == CACHE_SEPARATE) {
|
||||
printk(BIOS_DEBUG, "Fetching cache info for: level:%d, type:%d\n",
|
||||
cache_level, cache_type);
|
||||
cpu_get_cache_info(cache_level, cache_type, &info);
|
||||
printk(BIOS_DEBUG, "Size: %lld, associativity: %lld\n", info.size,
|
||||
info.associativity);
|
||||
|
||||
cache_type = CACHE_INSTRUCTION;
|
||||
|
||||
printk(BIOS_DEBUG, "Fetching cache info for: level:%d, type:%d\n",
|
||||
cache_level, cache_type);
|
||||
cpu_get_cache_info(cache_level, cache_type, &info);
|
||||
printk(BIOS_DEBUG, "Size: %lld, associativity: %lld\n", info.size,
|
||||
info.associativity);
|
||||
|
||||
cache_type = CACHE_DATA;
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "Fetching cache info for: level:%d, type:%d\n", cache_level,
|
||||
cache_type);
|
||||
cpu_get_cache_info(cache_level, cache_type, &info);
|
||||
printk(BIOS_DEBUG, "Size: %lld, associativity: %lld\n", info.size,
|
||||
info.associativity);
|
||||
}
|
||||
|
||||
/* update cache information (L1I) */
|
||||
|
||||
cpu_get_cache_info(CACHE_L1, CACHE_INSTRUCTION, &info);
|
||||
|
||||
l1i.size = info.size;
|
||||
l1i.associativity = info.associativity;
|
||||
l1i.numsets = info.numsets;
|
||||
l1i.line_size = info.line_bytes;
|
||||
l1i.attributes = cache_attributes(CACHE_INSTRUCTION);
|
||||
l1i.flags.raw = CACHE_NODE_FLAGS | 0xff;
|
||||
|
||||
/* update cache information (L1D) */
|
||||
|
||||
cpu_get_cache_info(CACHE_L1, CACHE_DATA, &info);
|
||||
|
||||
l1d.size = info.size;
|
||||
l1d.associativity = info.associativity;
|
||||
l1d.numsets = info.numsets;
|
||||
l1d.line_size = info.line_bytes;
|
||||
l1d.attributes = cache_attributes(CACHE_DATA) | (0x2);
|
||||
l1d.flags.raw = CACHE_NODE_FLAGS | 0xff;
|
||||
|
||||
/* update cache information (L2) */
|
||||
|
||||
cpu_get_cache_info(CACHE_L2, CACHE_UNIFIED, &info);
|
||||
|
||||
l2.size = info.size;
|
||||
l2.associativity = info.associativity;
|
||||
l2.numsets = info.numsets;
|
||||
l2.line_size = info.line_bytes;
|
||||
l2.attributes = cache_attributes(CACHE_UNIFIED) | (0x2);
|
||||
l2.flags.raw = CACHE_NODE_FLAGS | 0xff;
|
||||
|
||||
/* add secondary CPUs */
|
||||
|
||||
u32 cpu_id = 0;
|
||||
|
||||
struct device *dev = NULL;
|
||||
struct pptt_topology **it = &root_topology.child->sibling;
|
||||
struct pptt_topology **sibling;
|
||||
|
||||
while ((dev = dev_find_path(dev, DEVICE_PATH_GICC_V3))) {
|
||||
if (cpu_id == 0) {
|
||||
|
||||
cpu_id += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((*it = malloc(sizeof(struct pptt_topology))) == NULL) {
|
||||
|
||||
printk(BIOS_ERR, "Could not allocate pptt structure!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
memset(*it, 0, sizeof(struct pptt_topology));
|
||||
|
||||
(*it)->processor_id = cpu_id;
|
||||
(*it)->flags.raw = CORE_FLAGS_1;
|
||||
(*it)->resources = NULL;
|
||||
|
||||
//sibling = (*it)->sibling;
|
||||
sibling = &(*it)->sibling;
|
||||
|
||||
it = &(*it)->child;
|
||||
|
||||
if ((*it = malloc(sizeof(struct pptt_topology))) == NULL) {
|
||||
|
||||
printk(BIOS_ERR, "Could not allocate pptt structure!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
memset(*it, 0, sizeof(struct pptt_topology));
|
||||
|
||||
(*it)->processor_id = cpu_id;
|
||||
(*it)->flags.raw = CORE_FLAGS;
|
||||
(*it)->resources = &core_resources;
|
||||
|
||||
//it = &(*it)->sibling;
|
||||
it = sibling;
|
||||
|
||||
cpu_id += 1;
|
||||
}
|
||||
|
||||
return &root_topology;
|
||||
}
|
||||
9
src/mainboard/arm/rdn2/uart.c
Normal file
9
src/mainboard/arm/rdn2/uart.c
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <console/uart.h>
|
||||
#include <mainboard/addressmap.h>
|
||||
|
||||
uintptr_t uart_platform_base(unsigned int idx)
|
||||
{
|
||||
return RDN2_UART_NS_BASE;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue