blob: c4f2bd0a59f24db0432798f8b71bbfa8e84f9336 [file] [log] [blame]
/*
* Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or any later version.
*
* 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 Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
* You can also choose to distribute this program under the terms of
* the Unmodified Binary Distribution Licence (as given in the file
* COPYING.UBDL), provided that you have satisfied its requirements.
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** @file
*
* Hardware threads (harts)
*
*/
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <ipxe/fdt.h>
#include <ipxe/hart.h>
/** Boot hart ID */
unsigned long boot_hart;
/** Colour for debug messages */
#define colour &boot_hart
/**
* Find boot hart node
*
* @v offset Boot hart node offset
* @ret rc Return status code
*/
static int hart_node ( unsigned int *offset ) {
char path[27 /* "/cpus/cpu@XXXXXXXXXXXXXXXX" + NUL */ ];
int rc;
/* Construct node path */
snprintf ( path, sizeof ( path ), "/cpus/cpu@%lx", boot_hart );
/* Find node */
if ( ( rc = fdt_path ( path, offset ) ) != 0 ) {
DBGC ( colour, "HART could not find %s: %s\n",
path, strerror ( rc ) );
return rc;
}
return 0;
}
/**
* Check for supported extension
*
* @v ext Extension name (including leading underscore)
* @ret rc Return status code
*/
int hart_supported ( const char *ext ) {
unsigned int offset;
const char *isa;
const char *tmp;
int rc;
/* Find boot hart node */
if ( ( rc = hart_node ( &offset ) ) != 0 )
return rc;
/* Get ISA description */
isa = fdt_string ( offset, "riscv,isa" );
if ( ! isa ) {
DBGC ( colour, "HART could not identify ISA\n" );
return -ENOENT;
}
DBGC ( colour, "HART supports %s\n", isa );
/* Check for presence of extension */
tmp = isa;
while ( ( tmp = strstr ( tmp, ext ) ) != NULL ) {
tmp += strlen ( ext );
if ( ( *tmp == '\0' ) || ( *tmp == '_' ) )
return 0;
}
return -ENOTSUP;
}