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. > >>> And would it be possible to have a different register set for an >>> inherited SPARCCPUClass ? >>> Also trap handling and related cpu registers behavior has to be quite >>> different. >> >> Not really, we already handle some (but not all cases). > > You mean by not handling AG? The UA2005 doesn't have IG and MG either, > but that's the easy part. Instead it has a few register banks > switchable with the GL register pointer. 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. > >>>> Helpers such as cpu_hypervisor_mode() will need to be changed to take a >>>> SPARCCPU *cpu rather than CPUSPARCState *env argument; as an interim >>>> solution sparc_env_get_cpu() can be used. (examples on the list for sh4) >>>> >>>> Andreas >>>> >>>> -- >>>> SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany >>>> GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg >>> > > -- > Regards, > Artyom Tarasenko > > solaris/sparc under qemu blog: http://tyom.blogspot.com/search/label/qemu