On Tue, May 1, 2012 at 4:06 PM, Blue Swirl <blauwir...@gmail.com> wrote: > On Tue, May 1, 2012 at 13:54, Artyom Tarasenko <atar4q...@gmail.com> wrote: >> On Tue, May 1, 2012 at 11:25 AM, Blue Swirl <blauwir...@gmail.com> wrote: >>> On Mon, Apr 30, 2012 at 17:38, Artyom Tarasenko <atar4q...@gmail.com> wrote: >>>> On Mon, Apr 30, 2012 at 7:15 PM, Andreas Färber <afaer...@suse.de> wrote: >>>>> Am 30.04.2012 18:39, schrieb Artyom Tarasenko: >>>>>> Tried to boot QEMU Niagara machine with the firmware from the >>>>>> OpenSPARC T1 emulator ( www.opensparc.net/opensparc-t1/download.html ) >>>>>> , and it dies very early. >>>>>> The reason: in translate.c >>>>>> >>>>>> #define hypervisor(dc) (dc->mem_idx == MMU_HYPV_IDX) >>>>>> #define supervisor(dc) (dc->mem_idx >= MMU_KERNEL_IDX) >>>>>> >>>>>> and the dc->mem_idx is initialized like this: >>>>>> >>>>>> if (env1->tl > 0) { >>>>>> return MMU_NUCLEUS_IDX; >>>>>> } else if (cpu_hypervisor_mode(env1)) { >>>>>> return MMU_HYPV_IDX; >>>>>> } else if (cpu_supervisor_mode(env1)) { >>>>>> return MMU_KERNEL_IDX; >>>>>> } else { >>>>>> return MMU_USER_IDX; >>>>>> } >>>>>> >>>>>> Which seems to be conceptually incorrect. After reset tl == MAXTL, but >>>>>> still super- and hyper-visor bits are set, so both supervisor(dc) and >>>>>> hypervisor(dc) must return 1 which is impossible in the current >>>>>> implementation. >>>>>> >>>>>> What would be the proper way to fix it? Make mem_idx bitmap, add two >>>>>> more variables to DisasContext, or ...? >>>>>> >>>>>> Some other findings/questions: >>>>>> >>>>>> /* Sun4v generic Niagara machine */ >>>>>> { >>>>>> .default_cpu_model = "Sun UltraSparc T1", >>>>>> .console_serial_base = 0xfff0c2c000ULL, >>>>>> >>>>>> Where is this address coming from? The OpenSPARC Niagara machine has a >>>>>> "dumb serial" at 0x1f10000000ULL. >>>>>> >>>>>> And the biggest issue: UA2005 (as well as UA2007) describe a totally >>>>>> different format for a MMU TTE entry than the one sun4u CPU are using. >>>>>> I think the best way to handle it would be splitting off Niagara >>>>>> machine, and #defining MMU bits differently for sun4u and sun4v >>>>>> machines. >>>>>> >>>>>> Do we the cases in qemu where more than two (qemu-system-xxx and >>>>>> qemu-system-xxx64) binaries are produced? >>>>>> Would the name qemu-system-sun4v fit the naming convention? >>>>> >>>>> We have such a case for ppc (ppcemb) and it is kind of a maintenance >>>>> nightmare - I'm working towards getting rid of it with my QOM CPU work. >>>>> Better avoid it for sparc in the first place. >>>>> >>>>> Instead, you should add a callback function pointer to SPARCCPUClass >>>>> that you initialize based on CPU model so that is behaves differently at >>>>> runtime rather than at compile time. >>>>> Or if it's just about the class_init then after the Hard Freeze I can >>>>> start polishing my subclasses for sparc so that you can add a special >>>>> class_init for Niagara. >>>> >>>> But this would mean that the defines from >>>> #define TTE_NFO_BIT (1ULL << 60) >>>> to >>>> #define TTE_PGSIZE(tte) (((tte) >> 61) & 3ULL) >>>> >>>> inclusive would need to be replaced with functions and variables? >>>> Sounds like a further performance regression for sun4u? >>> >>> There could be parallel definitions for sun4u (actually UltraSparc-III >>> onwards the MMU is again different) and sun4v. >>> >>> At tlb_fill(), different implementations can be selected based on MMU >>> model. For ASI accesses, we can add conditional code but for higher >>> performance, some checks can be moved to translation time. >> >> Can be done, but what is the gain of having it runtime configurable? > > I was thinking of code like this in: > > switch (env->mmu_model) { > case MMU_US2: > return tlb_fill_us2(..); > case MMU_US3: > return tlb_fill_us3(..); > case MMU_US4: > return tlb_fill_us4(..); > case MMU_T1: > return tlb_fill_t1(..); > case MMU_T2: > return tlb_fill_t2(..); > } > > The perfomance cost shouldn't be too high. Alternatively a function > pointer could be set up.
Actually I was more worried about get_physical_address_* than filling, there we would have to use variables instead of constants and functions instead of macros. > Yes, we can always provide the register bank, older models just access > some of those. > >> cpu_change_pstate should probably have another parameter (new_GL) >> which is only valid for sun4v. >> And, depending on a trap type, env->htba has to be taken instead of >> env->tbr. To me it looks like at the end do_interrupt will have less >> common parts between sun4u and sun4v than specific ones. > > Same as tlb_fill(), switch() or function pointer. The functions are different. > > This is unavoidable (unless maybe in the future the TLB handling can > be pushed partially higher so mmu_idx parameters can be eliminated) > and the performance cost is not great. So, altogether you'd still prefer run-time checks over having qemu-system-sun4v (or -sparc64v) ? -- Regards, Artyom Tarasenko solaris/sparc under qemu blog: http://tyom.blogspot.com/search/label/qemu