On Fri, Jan 10, 2025 at 3:33 PM Sam Price <thesampr...@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 <alistai...@gmail.com> wrote:
> >
> > On Wed, Jan 8, 2025 at 12:28 PM Sam Price <thesampr...@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

Reply via email to