[03/23] sim/erc32: Perform pseudo-init of system if binary starts from non-zero address.
Commit Message
Binaries produced by most erc32 tool-chains do not include
system initialization. sis will detect this and initialize
necessary registers for memory and timer control.
* erc32.c (mec_read) allow simulator memory size to be read
by application. (boot_init) initialize memory and timers if
start address is not 0.
* erc32,c (exe_cmd) call boot_init if start address not 0
* interf.c (run_sim) Likewise
---
sim/erc32/erc32.c | 24 ++++++++++++++++++++++++
sim/erc32/func.c | 1 +
sim/erc32/interf.c | 1 +
3 files changed, 26 insertions(+)
Comments
On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> +extern struct pstate sregs;
> +
> +void
> +boot_init ()
in C, you need to do (void) to avoid ugliness.
also looks like this is missing an update to a header to add the prototype ?
> +{
> + mec_write(MEC_WCR, 0); /* zero waitstates */
> + mec_write(MEC_TRAPD, 0); /* turn off watch-dog */
> + mec_write(MEC_RTC_SCALER, sregs.freq-1); /* generate 1 MHz RTC tick */
> + mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */
> + sregs.wim = 2;
> + sregs.psr = 0x110010e0;
> + sregs.r[30] = RAM_END;
> + sregs.r[14] = sregs.r[30] - 96*4;
> + mec_mcr |= 1; /* power-down enabled */
> +}
why isn't sregs passed in as an arg ? looks like both callers have a pointer to
it already.
> --- a/sim/erc32/func.c
> +++ b/sim/erc32/func.c
> @@ -468,6 +468,7 @@ exec_cmd(sregs, cmd)
> }
> sregs->pc = len & ~3;
> sregs->npc = sregs->pc + 4;
> + if ((sregs->pc != 0) && (ebase.simtime == 0)) boot_init();
i know the code base doesn't follow GNU style already, but lets at least start
moving in that direction. i.e. uncuddle this:
if (...)
boot_init();
> --- a/sim/erc32/interf.c
> +++ b/sim/erc32/interf.c
> @@ -78,6 +78,7 @@ run_sim(sregs, icount, dis)
> init_stdio();
> sregs->starttime = time(NULL);
> irq = 0;
> + if ((sregs->pc != 0) && (ebase.simtime == 0)) boot_init();
same here
-mike
On 02/17/2015 09:59 AM, Mike Frysinger wrote:
> On 17 Feb 2015 08:44, Jiri Gaisler wrote:
>> +extern struct pstate sregs;
>> +
>> +void
>> +boot_init ()
>
> in C, you need to do (void) to avoid ugliness.
Will fix.
>
> also looks like this is missing an update to a header to add the prototype ?
This is done in patch (17/23).
>
>> +{
>> + mec_write(MEC_WCR, 0); /* zero waitstates */
>> + mec_write(MEC_TRAPD, 0); /* turn off watch-dog */
>> + mec_write(MEC_RTC_SCALER, sregs.freq-1); /* generate 1 MHz RTC tick */
>> + mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */
>> + sregs.wim = 2;
>> + sregs.psr = 0x110010e0;
>> + sregs.r[30] = RAM_END;
>> + sregs.r[14] = sregs.r[30] - 96*4;
>> + mec_mcr |= 1; /* power-down enabled */
>> +}
>
> why isn't sregs passed in as an arg ? looks like both callers have a pointer to
> it already.
I am saving this for next major update - SMP support. All globals will then
be removed and the full cpu state will be in a struct that is passed to the
simulation engine. In this way I can simulate multiple cpu's.
Jiri.
On 18 Feb 2015 15:40, Jiri Gaisler wrote:
> On 02/17/2015 09:59 AM, Mike Frysinger wrote:
> > On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> >> +extern struct pstate sregs;
> >> +
> >> +void
> >> +boot_init ()
> >
> > also looks like this is missing an update to a header to add the prototype ?
>
> This is done in patch (17/23).
ok, but patches things really should be standalone. although your series is
pretty good already in terms of splitting things apart.
> >> +{
> >> + mec_write(MEC_WCR, 0); /* zero waitstates */
> >> + mec_write(MEC_TRAPD, 0); /* turn off watch-dog */
> >> + mec_write(MEC_RTC_SCALER, sregs.freq-1); /* generate 1 MHz RTC tick */
> >> + mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */
> >> + sregs.wim = 2;
> >> + sregs.psr = 0x110010e0;
> >> + sregs.r[30] = RAM_END;
> >> + sregs.r[14] = sregs.r[30] - 96*4;
> >> + mec_mcr |= 1; /* power-down enabled */
> >> +}
> >
> > why isn't sregs passed in as an arg ? looks like both callers have a pointer to
> > it already.
>
> I am saving this for next major update - SMP support. All globals will then
> be removed and the full cpu state will be in a struct that is passed to the
> simulation engine. In this way I can simulate multiple cpu's.
can't this particular bit be done already ? or is the global pointer diff from
the local one ?
-mike
On 02/18/2015 05:53 PM, Mike Frysinger wrote:
> On 18 Feb 2015 15:40, Jiri Gaisler wrote:
>> On 02/17/2015 09:59 AM, Mike Frysinger wrote:
>>> On 17 Feb 2015 08:44, Jiri Gaisler wrote:
>>>> +extern struct pstate sregs;
>>>> +
>>>> +void
>>>> +boot_init ()
>>>
>>> also looks like this is missing an update to a header to add the prototype ?
>>
>> This is done in patch (17/23).
>
> ok, but patches things really should be standalone. although your series is
> pretty good already in terms of splitting things apart.
>
>>>> +{
>>>> + mec_write(MEC_WCR, 0); /* zero waitstates */
>>>> + mec_write(MEC_TRAPD, 0); /* turn off watch-dog */
>>>> + mec_write(MEC_RTC_SCALER, sregs.freq-1); /* generate 1 MHz RTC tick */
>>>> + mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */
>>>> + sregs.wim = 2;
>>>> + sregs.psr = 0x110010e0;
>>>> + sregs.r[30] = RAM_END;
>>>> + sregs.r[14] = sregs.r[30] - 96*4;
>>>> + mec_mcr |= 1; /* power-down enabled */
>>>> +}
>>>
>>> why isn't sregs passed in as an arg ? looks like both callers have a pointer to
>>> it already.
>>
>> I am saving this for next major update - SMP support. All globals will then
>> be removed and the full cpu state will be in a struct that is passed to the
>> simulation engine. In this way I can simulate multiple cpu's.
>
> can't this particular bit be done already ? or is the global pointer diff from
> the local one ?
The global pointer is not different from the local, but since the global is
used in so many places it does not seem logical to switch to a local copy just
here. That is why I would like to keep this as is and remove all globals in
a later patch.
Jiri.
> -mike
>
On 19 Feb 2015 17:11, Jiri Gaisler wrote:
> On 02/18/2015 05:53 PM, Mike Frysinger wrote:
> > On 18 Feb 2015 15:40, Jiri Gaisler wrote:
> >> On 02/17/2015 09:59 AM, Mike Frysinger wrote:
> >>> On 17 Feb 2015 08:44, Jiri Gaisler wrote:
> >>>> +{
> >>>> + mec_write(MEC_WCR, 0); /* zero waitstates */
> >>>> + mec_write(MEC_TRAPD, 0); /* turn off watch-dog */
> >>>> + mec_write(MEC_RTC_SCALER, sregs.freq-1); /* generate 1 MHz RTC tick */
> >>>> + mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */
> >>>> + sregs.wim = 2;
> >>>> + sregs.psr = 0x110010e0;
> >>>> + sregs.r[30] = RAM_END;
> >>>> + sregs.r[14] = sregs.r[30] - 96*4;
> >>>> + mec_mcr |= 1; /* power-down enabled */
> >>>> +}
> >>>
> >>> why isn't sregs passed in as an arg ? looks like both callers have a pointer to
> >>> it already.
> >>
> >> I am saving this for next major update - SMP support. All globals will then
> >> be removed and the full cpu state will be in a struct that is passed to the
> >> simulation engine. In this way I can simulate multiple cpu's.
> >
> > can't this particular bit be done already ? or is the global pointer diff from
> > the local one ?
>
> The global pointer is not different from the local, but since the global is
> used in so many places it does not seem logical to switch to a local copy just
> here. That is why I would like to keep this as is and remove all globals in
> a later patch.
there's already funcs that accept it as a pointer and operate on it in this
code base. since you're creating this function for the first time, it seems
natural to include the right change from the start to reduce code shuffling
later on.
if you're really set on this route though, i won't belabor the point (even if i
think i'm right ;]).
-mike
@@ -743,6 +743,14 @@ mec_read(addr, asi, data)
*data = read_uart(addr);
break;
+ case 0xF4: /* simulator RAM size in bytes */
+ *data = 4096*1024;
+ break;
+
+ case 0xF8: /* simulator ROM size in bytes */
+ *data = 1024*1024;
+ break;
+
default:
set_sfsr(MEC_ACC, addr, asi, 1);
return (1);
@@ -1887,3 +1895,19 @@ sis_memory_read(addr, data, length)
memcpy(data, mem, length);
return (length);
}
+
+extern struct pstate sregs;
+
+void
+boot_init ()
+{
+ mec_write(MEC_WCR, 0); /* zero waitstates */
+ mec_write(MEC_TRAPD, 0); /* turn off watch-dog */
+ mec_write(MEC_RTC_SCALER, sregs.freq-1); /* generate 1 MHz RTC tick */
+ mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */
+ sregs.wim = 2;
+ sregs.psr = 0x110010e0;
+ sregs.r[30] = RAM_END;
+ sregs.r[14] = sregs.r[30] - 96*4;
+ mec_mcr |= 1; /* power-down enabled */
+}
@@ -468,6 +468,7 @@ exec_cmd(sregs, cmd)
}
sregs->pc = len & ~3;
sregs->npc = sregs->pc + 4;
+ if ((sregs->pc != 0) && (ebase.simtime == 0)) boot_init();
printf("resuming at 0x%08x\n",sregs->pc);
if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {
stat = run_sim(sregs, VAL(cmd2), 0);
@@ -78,6 +78,7 @@ run_sim(sregs, icount, dis)
init_stdio();
sregs->starttime = time(NULL);
irq = 0;
+ if ((sregs->pc != 0) && (ebase.simtime == 0)) boot_init();
while (!sregs->err_mode & (icount > 0)) {
sregs->fhold = 0;