Date: Thu, 28 Feb 2013 08:56:54 -0800 From: Tim Kientzle <kientzle@freebsd.org> To: Warner Losh <imp@bsdimp.com> Cc: freebsd-arm@freebsd.org Subject: Re: PHYSADDR Message-ID: <1F9B0ED4-7FAF-43D8-BECD-1D42792E81DF@freebsd.org> In-Reply-To: <1A428660-39FB-45EB-979B-103F7E83BC4A@bsdimp.com> References: <E886046B-1612-425B-902B-72D4B0E93618@freebsd.org> <1A428660-39FB-45EB-979B-103F7E83BC4A@bsdimp.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Feb 27, 2013, at 10:41 PM, Warner Losh wrote: >=20 > On Feb 27, 2013, at 11:27 PM, Tim Kientzle wrote: >=20 >> Starting to look at what is needed for a Generic ARM kernel. >> There's a lot here; I sincerely hope I'm not the only one=85 ;-) >>=20 >> First up: Can we get rid of PHYSADDR? >=20 > There's lots of places in the tree that use it, but not so many that a = whack-a-mole approach wouldn't work. It's mostly only used in locore.S and machdep.c (and, of course, the many copies of machdep.c). >> I think we can always compute it at runtime from PC. >>=20 >> For example, I think this works in several places: >> and r0, pc, #0xF0000000 >=20 > This only works early in boot before we've turned on the MMU, right? I'm still pretty new to this section of the code, so might have missed something, but I don't think we need PHYSADDR after the kernel has relocated itself. Do we? >=20 >> And I've found at least one reference that I think can be simply >> eliminated: >>=20 >> Index: arm/elf_trampoline.c >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> --- arm/elf_trampoline.c (revision 247250) >> +++ arm/elf_trampoline.c (working copy) >> @@ -169,7 +169,7 @@ >> void >> _startC(void) >> { >> - int physaddr =3D KERNPHYSADDR; >> + unsigned int physaddr =3D (unsigned int)&_start & 0xfffff000; >=20 > How'd you come up with this? Perhaps we should just define = KERNPHYSADDR as this gross expression :) >=20 > But isn't _start a virtual address, not a physical address? Honestly, I'm still trying to figure that part out. ;-) Disassembling the compiler output, taking the address of the current function always uses a PC-relative address. So &_startC here would give the current address of the function as it's executing. >=20 >> int tmp1; >> unsigned int sp =3D ((unsigned int)&_end & ~3) + 4; >> #if defined(FLASHADDR) && defined(LOADERRAMADDR) >> @@ -189,10 +189,9 @@ >> */ >> unsigned int target_addr; >> unsigned int tmp_sp; >> - uint32_t src_addr =3D (uint32_t)&_start - PHYSADDR + = FLASHADDR >> - + (pc - FLASHADDR - ((uint32_t)&_startC - PHYSADDR)) = & 0xfffff000; >> + uint32_t src_addr =3D (uint32_t)&_start; >=20 > I'm not sure how this works=85 Here's my reasoning: FLASHADDR and PHYSADDR are always multiples of 4k, so you can pull those out of the parentheses to get: _start - PHYSADDR + FLASHADDR - FLASHADD + PHYSADDR + (pc - _startC) = & 0xffffff000 And since pc was sampled early in _startC, the last expression should always be zero. I was a little surprised by this myself, so I might have missed something. >> - target_addr =3D (unsigned int)&_start - PHYSADDR + = LOADERRAMADDR; >> + target_addr =3D (unsigned int)&_start - (pc & = 0xf0000000) + LOADERRAMADDR; >=20 > This might work, but I'd suggest a PC_TO_PHYSADDR(pc) macro or = something similar=85 I'll try that later on. I suspect some of these PHYSADDRs will simply go away, since I think what we really want in the early bootstrap stage is just "what address is the kernel currently executing at". I still need to piece together some more things before I understand that. As with the above, at least some of the expressions using PHYSADDR seem more complex than necessary. >> tmp_sp =3D target_addr + 0x100000 + >> (unsigned int)&_end - (unsigned int)&_start; >> memcpy((char *)target_addr, (char *)src_addr, >>=20 >>=20 >> Tim >>=20 >=20
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1F9B0ED4-7FAF-43D8-BECD-1D42792E81DF>