From: "Philippe Mathieu-Daudé" <philmd@linaro.org>
To: "Sam Price" <thesamprice@gmail.com>,
"Alex Bennée" <alex.bennee@linaro.org>
Cc: qemu-devel@nongnu.org, Alistair Francis <alistair23@gmail.com>,
alistair@alistair23.me,
Pierrick Bouvier <pierrick.bouvier@linaro.org>
Subject: Re: Subject: [PATCH] loader: Add register setting support via cli
Date: Tue, 4 Feb 2025 22:42:08 +0100 [thread overview]
Message-ID: <d6888fe3-740d-4d8a-a27b-cd5968722b81@linaro.org> (raw)
In-Reply-To: <CAKmqyKMwojdOo7cQdjd5A+EqGv1YGqRQUUY_WXOYO_9m76WH2g@mail.gmail.com>
Cc'ing Alex/Pierrick
On 31/1/25 01:27, Alistair Francis wrote:
> On Fri, Jan 10, 2025 at 3:33 PM Sam Price <thesamprice@gmail.com> wrote:
>>
>> Yes that is true a boot loader will do more than just set registers.
>> Ill rework the text a bit on the next update.
>> In my case i need to set the r5 register that specifies the memory
>> location to the device tree.
>
> Should that be done in the machine instead? It seems tricky to expect
> users to set this register
>
>> I also use the device loader to load in a elf file to ram, and the
>> device-loader to load in the device tree to the location specified by
>> the r5 register
>>
>> I could add a gdb call that would return an array of string mappings
>> to integers.
>> If the machine doesn't implement the function/ leaves it as null
>> pointer then you wouldn't get the cli support.
>> Not sure where you would document all the machine register names /
>> numbers at though.
>> This might be too much though?
>
> We probably don't need to document the register names
>
> Alistair
>
>> I left the door somewhat open on this via the NAME_NUMBER format.
>>
>> There was some checking logic where if data is supplied then it forces
>> a check for data-len.
>> I could relax that check if you supply the reg.name field.
>>
>> I am unsure how to determine the machine register size.
>> I assumed the max register size on any machine would be 8 bytes, this
>> might be wrong.
>> the gdb call seems to just pass in the full 8 bytes, but I didn't dig
>> into it for all machines.
>>
>> Ill look at this a bit more and try to configure the git email.
>> I also need to set up a docker container to build /test latest.
>> I have been building / testing on an old ubuntu machine.
>> (To test this I need to run it on qemu-xilinx).
>> My workplace has us on ubuntu 20.
>>
>> So it might be a while before I have another version up.
>>
>> Thanks,
>> Sam
>>
>> On Thu, Jan 9, 2025 at 7:34 PM Alistair Francis <alistair23@gmail.com> wrote:
>>>
>>> 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
>>
>>
>>
>> --
>> Sincerely,
>>
>> Sam Price
>
next prev parent reply other threads:[~2025-02-04 21:42 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
2025-01-10 5:33 ` Sam Price
2025-01-31 0:27 ` Alistair Francis
2025-02-04 21:42 ` Philippe Mathieu-Daudé [this message]
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=d6888fe3-740d-4d8a-a27b-cd5968722b81@linaro.org \
--to=philmd@linaro.org \
--cc=alex.bennee@linaro.org \
--cc=alistair23@gmail.com \
--cc=alistair@alistair23.me \
--cc=pierrick.bouvier@linaro.org \
--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).