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