diff mbox series

[v3,03/13] hw/arm/raspi: Extract the version from the board revision

Message ID 20200208165645.15657-4-f4bug@amsat.org
State New
Headers show
Series hw/arm/raspi: Dynamically create machines based on the board revision | expand

Commit Message

Philippe Mathieu-Daudé Feb. 8, 2020, 4:56 p.m. UTC
The board revision encode the board version. Add a helper
to extract the version, and use it.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/arm/raspi.c | 31 +++++++++++++++++++++++++++----
 1 file changed, 27 insertions(+), 4 deletions(-)

Comments

Peter Maydell Feb. 13, 2020, 1:40 p.m. UTC | #1
On Sat, 8 Feb 2020 at 16:57, Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
>
> The board revision encode the board version. Add a helper
> to extract the version, and use it.
>
> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>  hw/arm/raspi.c | 31 +++++++++++++++++++++++++++----
>  1 file changed, 27 insertions(+), 4 deletions(-)
>
> diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
> index 818146fdbb..f285e2988f 100644
> --- a/hw/arm/raspi.c
> +++ b/hw/arm/raspi.c
> @@ -16,6 +16,7 @@
>  #include "qapi/error.h"
>  #include "cpu.h"
>  #include "hw/arm/bcm2836.h"
> +#include "hw/registerfields.h"
>  #include "qemu/error-report.h"
>  #include "hw/boards.h"
>  #include "hw/loader.h"
> @@ -37,6 +38,28 @@ typedef struct RasPiState {
>      MemoryRegion ram;
>  } RasPiState;
>
> +/*
> + * Board revision codes:
> + * www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/
> + */
> +FIELD(REV_CODE, REVISION,           0, 4);
> +FIELD(REV_CODE, TYPE,               4, 8);
> +FIELD(REV_CODE, PROCESSOR,         12, 4);
> +FIELD(REV_CODE, MANUFACTURER,      16, 4);
> +FIELD(REV_CODE, MEMORY_SIZE,       20, 3);
> +FIELD(REV_CODE, STYLE,             23, 1);
> +
> +static int board_processor_id(uint32_t board_rev)
> +{
> +    assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */
> +    return FIELD_EX32(board_rev, REV_CODE, PROCESSOR);
> +}
> +
> +static int board_version(uint32_t board_rev)
> +{
> +    return board_processor_id(board_rev) + 1;

This uses the 'processor' field, which basically means the SoC
(0 for BCM2835, 1 for BCM2836, 2 for BCMM2837, 3 for BCM2711).
We use 'version' for a wider range of things in our code here:
 * do we need SMP setup?
 * which address does the firmware image go?
 * do we need to set up SMC vectors so no-op SMC works?
 * as well as "which SoC do we instantiate"?

We think of 'version' as basically "raspi 2 or 3?", but
according to the table in your url you can get a version of
the raspi 2b with a BCM2837 SoC, which confuses this idea.

Anyway, since what we have in this patch works OK for the set
of board models we support, I'm happy to leave the patch as-is,
but maybe worth checking and considering what in our code we
should really be making conditional on "actually the SoC type"
and what on something else...

thanks
-- PMM
Philippe Mathieu-Daudé Feb. 13, 2020, 1:53 p.m. UTC | #2
On 2/13/20 2:40 PM, Peter Maydell wrote:
> On Sat, 8 Feb 2020 at 16:57, Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
>>
>> The board revision encode the board version. Add a helper
>> to extract the version, and use it.
>>
>> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
>> ---
>>   hw/arm/raspi.c | 31 +++++++++++++++++++++++++++----
>>   1 file changed, 27 insertions(+), 4 deletions(-)
>>
>> diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
>> index 818146fdbb..f285e2988f 100644
>> --- a/hw/arm/raspi.c
>> +++ b/hw/arm/raspi.c
>> @@ -16,6 +16,7 @@
>>   #include "qapi/error.h"
>>   #include "cpu.h"
>>   #include "hw/arm/bcm2836.h"
>> +#include "hw/registerfields.h"
>>   #include "qemu/error-report.h"
>>   #include "hw/boards.h"
>>   #include "hw/loader.h"
>> @@ -37,6 +38,28 @@ typedef struct RasPiState {
>>       MemoryRegion ram;
>>   } RasPiState;
>>
>> +/*
>> + * Board revision codes:
>> + * www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/
>> + */
>> +FIELD(REV_CODE, REVISION,           0, 4);
>> +FIELD(REV_CODE, TYPE,               4, 8);
>> +FIELD(REV_CODE, PROCESSOR,         12, 4);
>> +FIELD(REV_CODE, MANUFACTURER,      16, 4);
>> +FIELD(REV_CODE, MEMORY_SIZE,       20, 3);
>> +FIELD(REV_CODE, STYLE,             23, 1);
>> +
>> +static int board_processor_id(uint32_t board_rev)
>> +{
>> +    assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */
>> +    return FIELD_EX32(board_rev, REV_CODE, PROCESSOR);
>> +}
>> +
>> +static int board_version(uint32_t board_rev)
>> +{
>> +    return board_processor_id(board_rev) + 1;
> 
> This uses the 'processor' field, which basically means the SoC
> (0 for BCM2835, 1 for BCM2836, 2 for BCMM2837, 3 for BCM2711).
> We use 'version' for a wider range of things in our code here:
>   * do we need SMP setup?
>   * which address does the firmware image go?
>   * do we need to set up SMC vectors so no-op SMC works?
>   * as well as "which SoC do we instantiate"?
> 
> We think of 'version' as basically "raspi 2 or 3?", but
> according to the table in your url you can get a version of
> the raspi 2b with a BCM2837 SoC, which confuses this idea.
> 
> Anyway, since what we have in this patch works OK for the set
> of board models we support, I'm happy to leave the patch as-is,
> but maybe worth checking and considering what in our code we
> should really be making conditional on "actually the SoC type"
> and what on something else...

Yes you are right, version = (2, 3) was too simple, I replaced the 
'version' check by 'processor_id' in the series introducing the raspi4 
(with other cleanups).
Eventually this file will only use the board_rev fields directly.
diff mbox series

Patch

diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index 818146fdbb..f285e2988f 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -16,6 +16,7 @@ 
 #include "qapi/error.h"
 #include "cpu.h"
 #include "hw/arm/bcm2836.h"
+#include "hw/registerfields.h"
 #include "qemu/error-report.h"
 #include "hw/boards.h"
 #include "hw/loader.h"
@@ -37,6 +38,28 @@  typedef struct RasPiState {
     MemoryRegion ram;
 } RasPiState;
 
+/*
+ * Board revision codes:
+ * www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/
+ */
+FIELD(REV_CODE, REVISION,           0, 4);
+FIELD(REV_CODE, TYPE,               4, 8);
+FIELD(REV_CODE, PROCESSOR,         12, 4);
+FIELD(REV_CODE, MANUFACTURER,      16, 4);
+FIELD(REV_CODE, MEMORY_SIZE,       20, 3);
+FIELD(REV_CODE, STYLE,             23, 1);
+
+static int board_processor_id(uint32_t board_rev)
+{
+    assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */
+    return FIELD_EX32(board_rev, REV_CODE, PROCESSOR);
+}
+
+static int board_version(uint32_t board_rev)
+{
+    return board_processor_id(board_rev) + 1;
+}
+
 static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
 {
     static const uint32_t smpboot[] = {
@@ -164,9 +187,10 @@  static void setup_boot(MachineState *machine, int version, size_t ram_size)
     arm_load_kernel(ARM_CPU(first_cpu), machine, &binfo);
 }
 
-static void raspi_init(MachineState *machine, int version)
+static void raspi_init(MachineState *machine, uint32_t board_rev)
 {
     RasPiState *s = g_new0(RasPiState, 1);
+    int version = board_version(board_rev);
     uint32_t vcram_size;
     DriveInfo *di;
     BlockBackend *blk;
@@ -192,7 +216,6 @@  static void raspi_init(MachineState *machine, int version)
     /* Setup the SOC */
     object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram),
                                    &error_abort);
-    int board_rev = version == 3 ? 0xa02082 : 0xa21041;
     object_property_set_int(OBJECT(&s->soc), board_rev, "board-rev",
                             &error_abort);
     object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_abort);
@@ -216,7 +239,7 @@  static void raspi_init(MachineState *machine, int version)
 
 static void raspi2_init(MachineState *machine)
 {
-    raspi_init(machine, 2);
+    raspi_init(machine, 0xa21041);
 }
 
 static void raspi2_machine_init(MachineClass *mc)
@@ -238,7 +261,7 @@  DEFINE_MACHINE("raspi2", raspi2_machine_init)
 #ifdef TARGET_AARCH64
 static void raspi3_init(MachineState *machine)
 {
-    raspi_init(machine, 3);
+    raspi_init(machine, 0xa02082);
 }
 
 static void raspi3_machine_init(MachineClass *mc)