qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Alistair Francis <alistair23@gmail.com>
To: Sam Price <thesamprice@gmail.com>
Cc: qemu-devel@nongnu.org, alistair@alistair23.me
Subject: Re: Subject: [PATCH] loader: Add register setting support via cli
Date: Fri, 10 Jan 2025 10:33:36 +1000	[thread overview]
Message-ID: <CAKmqyKPa2OnCvDPd8WqvyFWN3f9bsngSpF2io4ObJPoCTsx+dQ@mail.gmail.com> (raw)
In-Reply-To: <CAEekfLYFsdzgRiscqJ4NsvpMsOaLrj_6QbjH-0f42mdggXbyDQ@mail.gmail.com>

On Wed, Jan 8, 2025 at 12:28 PM Sam Price <thesamprice@gmail.com> wrote:
>
> I made the changes, and added documentation.
> https://gitlab.com/thesamprice/qemu/-/compare/master...loader?from_project_id=11167699
>
> I left it as [PREFIX]<RegNumber>
>
> I can switch this to just RegNumber if desired.
>
> I am still struggling with the email format sorry.
> ---
> docs/system/generic-loader.rst | 98 ++++++++++++++++++++++++++++++++
> hw/core/generic-loader.c | 46 +++++++++++----
> include/hw/core/generic-loader.h | 7 +++
> 3 files changed, 139 insertions(+), 12 deletions(-)
>
> diff --git a/docs/system/generic-loader.rst b/docs/system/generic-loader.rst
> index 4f9fb005f1..71d4aaa097 100644
> --- a/docs/system/generic-loader.rst
> +++ b/docs/system/generic-loader.rst
> @@ -117,4 +117,102 @@ future the internal state 'set_pc' (which exists
> in the generic loader
> now) should be exposed to the user so that they can choose if the PC
> is set or not.
> +Loading Data into Registers
> +^^^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +The `loader` device allows the initialization of CPU registers from the command
> +line. This feature is particularly useful for setting up the processor state
> +before starting an executable. By configuring registers prior to execution, the
> +`loader` can mimic the state that a bootloader would leave the processor in
> +before transferring control to an ELF file or another executable.

This isn't really true though. A bootloader generally will set more
than the GP registers. A boot loader will configure devices and
perhaps initalise memory.

> +
> +The syntax for loading data into registers is as follows::
> +
> + -device loader,reg=<reg>,data=<data>,data-len=<data-len>
> +
> +**Parameters:**
> +
> +``<reg>``
> + The target register to set. Format must pass the following regex
> + ``[a-zA-Z]+[0-9]+``. The numeric part corresponds to the processor's GDB \
> + register index. For general-purpose registers, this is typically the
> + number in the register's name (e.g., ``r5`` translates to ``5``).
> + Special-purpose registers have specific IDs defined in their processor's
> + `gdbstub.c` file. Note that these IDs vary between processors.
> +
> +``<data>``
> + The value to load into the specified register. The data must not exceed 8
> + bytes in size.

Why 8 bytes?

> +
> +``<data-len>``
> + The length of the data in bytes. This parameter is mandatory when using
> + the ``data`` argument.

Do we need data-len? Why not just use the register size

> +
> +**Examples:**
> +
> +Set a general-purpose register
> +""""""""""""""""""""""""""""""
> +
> +To set register ``r5`` to ``0xc0001000`` (4 bytes) on CPU 0::
> +
> + -device loader,reg=r5,data=0xc0001000,data-len=4
> +
> +Set a special register
> +""""""""""""""""""""""
> +
> +To set the Program Counter (PC, register ``32``) to ``0x80000000`` on CPU 0::
> +
> + -device loader,reg=pc32,data=0x80000000,data-len=4
> +
> +You must look in your processor's `gdbstub.c` file to special register to index
> +mappings.

That isn't really helpful for users, but I don't have a better idea

> +
> +**Special Registers:**
> +
> +Special registers are defined in the processor's ``gdbstub.c`` file
> with numeric IDs.
> +Examples from the MicroBlaze processor at one point looked like. include::
> +
> + enum {
> + GDB_PC = 32 + 0,
> + GDB_MSR = 32 + 1,
> + GDB_EAR = 32 + 2,
> + GDB_ESR = 32 + 3,
> + GDB_FSR = 32 + 4,
> + GDB_BTR = 32 + 5,
> + GDB_PVR0 = 32 + 6,
> + GDB_PVR11 = 32 + 17,
> + GDB_EDR = 32 + 18,
> + GDB_SLR = 32 + 25,
> + GDB_SHR = 32 + 26,
> + };
> +
> +For example, to set the Machine State Register (``GDB_MSR``) on a MicroBlaze
> +processor::
> +
> + -device loader,reg=MSR33,data=0x00000001,data-len=4
> +
> +**Register Loading Notes:**
> +
> +1. **Processor-Specific IDs**:
> + The numeric IDs for registers vary between processors. Always refer to the
> + `gdbstub.c` file for the target processor to identify the correct register
> + mappings.
> +
> +2. **Pre-Execution State**:
> + This capability is ideal for initializing a simulated environment to match
> + the state expected by an ELF file. For example, you can configure stack
> + pointers, machine state registers, and program counters to prepare the
> + processor to run a bootstrapped application.
> +
> +3. **Validation**:
> + Register numbers are validated by the `gdb_write_register` function. Ensure
> + the specified register is supported by the target architecture.
> +
> +4. **Endianess**:
> + The `data` value is written using the processor's native endian format.
> +
> +By using the `loader` device to initialize registers, you can simulate
> +realistic execution environments, enabling detailed testing and debugging
> +of embedded software, including bootloaders interactions and operating
> +system kernels.
> diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c
> index ea8628b892..9408ecd150 100644
> --- a/hw/core/generic-loader.c
> +++ b/hw/core/generic-loader.c
> @@ -55,6 +55,14 @@ static void generic_loader_reset(void *opaque)
> }
> }
> + if(s->reg.name) {
> + CPUClass *cc = CPU_GET_CLASS(s->cpu);
> + int bytes_written = cc->gdb_write_register(s->cpu, (uint8_t*)
> &s->reg.value, s->reg.num);
> + if(bytes_written != s->reg.data_len) {
> + printf("Error setting register %d to value %lX expected to write %d,
> but wrote %d\n", s->reg.num, s->reg.value, s->reg.data_len,
> bytes_written);

The line wrapping is muddled up here. Can you please send it with git
send-email. Do some sends against yourself to make sure it works.

You mentioned gmail in an earlier thread I think, did you follow the
instructions: https://git-scm.com/docs/git-send-email#_use_gmail_as_the_smtp_server

Alistair


  reply	other threads:[~2025-01-10  0:35 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-06  3:29 Subject: [PATCH] loader: Add register setting support via cli Sam Price
2024-12-19 23:11 ` Sam Price
2025-01-06  1:43   ` Sam Price
2025-01-06  4:41 ` Alistair Francis
2025-01-06  4:59   ` Sam Price
2025-01-06  5:13     ` Alistair Francis
2025-01-08  2:28       ` Sam Price
2025-01-10  0:33         ` Alistair Francis [this message]
2025-01-10  5:33           ` Sam Price
2025-01-31  0:27             ` Alistair Francis
2025-02-04 21:42               ` Philippe Mathieu-Daudé
2025-01-10  9:53         ` Philippe Mathieu-Daudé

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAKmqyKPa2OnCvDPd8WqvyFWN3f9bsngSpF2io4ObJPoCTsx+dQ@mail.gmail.com \
    --to=alistair23@gmail.com \
    --cc=alistair@alistair23.me \
    --cc=qemu-devel@nongnu.org \
    --cc=thesamprice@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).