Date: Sat, 2 Mar 2013 21:18:31 -0700 From: Warner Losh <imp@bsdimp.com> To: Ian Lepore <ian@FreeBSD.org> Cc: Tim Kientzle <tim@kientzle.com>, freebsd-arm@FreeBSD.org Subject: Re: PHYSADDR Message-ID: <042A3136-C7E6-4824-B153-8C8778376106@bsdimp.com> In-Reply-To: <1362273533.1195.199.camel@revolution.hippie.lan> References: <E886046B-1612-425B-902B-72D4B0E93618@freebsd.org> <1362068453.1195.40.camel@revolution.hippie.lan> <674A08B3-6600-4B77-8511-9EF54E4B9B1F@FreeBSD.org> <8FEA3237-8ABF-4564-B672-4B4C0C6EF291@kientzle.com> <1362155632.1195.120.camel@revolution.hippie.lan> <5B622D1B-4EAE-4184-A194-DD14083A48B6@kientzle.com> <1362246634.1195.178.camel@revolution.hippie.lan> <AC642AAD-8D8C-429E-AE3B-A34241DA2517@kientzle.com> <1362273533.1195.199.camel@revolution.hippie.lan>
next in thread | previous in thread | raw e-mail | index | archive | help
I didn't review this in great detail, but I agree: this isn't quite = ready to commit. Just had one comment inline... On Mar 2, 2013, at 6:18 PM, Ian Lepore wrote: > On Sat, 2013-03-02 at 10:10 -0800, Tim Kientzle wrote: >> On Mar 2, 2013, at 9:50 AM, Ian Lepore wrote: >>=20 >>> [...] >>=20 >>> I'm not sure its safe to assume that (entry-pc & 0xfffff000) is the >>> beginning of the kernel; it's true now but need not be so. But = that's >>> no big deal, we can tweak the linker script to give us the offset of = the >>> _start symbol so it'll work no matter what. >>=20 >> Patches? ;-) >=20 > This turned out to be a bit trickier than I first thought it would be, > but it worked out. >=20 > This gets rids of any reference to PHYSADDR and similar constants in = the > main path through the code. I didn't address the "running from flash" > case or anything under #ifdef SMP, yet. The only constant left is > KERNBASE which is 0xC0000000 for all arm systems. >=20 > For now I've got #undef PHYSADDR at the top of the code; this is just > for testing without having to remove it yet from anywhere else. >=20 > There are two ldscript changes: define a new ENTRY_OFFSET symbol which > is the offset between the start of the load image and the _start = symbol, > and also it puts the physical addresses in the headers, by calculating = a > physical value for ENTRY(), and using an AT(expr) for the text = segment, > which very conviently just flows to the following segments without > needing to re-specify it on every new segment. >=20 > This isn't ready to commit, but it's ready to play with, and to get > comments from folks who know some of the history of this code (Olivier > has been helping me on irc all day answering such questions). >=20 > -- Ian >=20 > Index: sys/arm/arm/locore.S > =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 > --- sys/arm/arm/locore.S (revision 247421) > +++ sys/arm/arm/locore.S (working copy) > @@ -41,6 +41,8 @@ >=20 > __FBSDID("$FreeBSD$"); >=20 > +#undef PHYSADDR > + > /* What size should this really be ? It is only used by initarm() */ > #define INIT_ARM_STACK_SIZE (2048 * 4) >=20 > @@ -52,16 +54,8 @@ __FBSDID("$FreeBSD$"); > mov tmp, tmp /* wait for it to complete */ = ;\ > CPWAIT_BRANCH /* branch to next insn */ >=20 > -/* > - * This is for kvm_mkdb, and should be the address of the beginning > - * of the kernel text segment (not necessarily the same as kernbase). > - */ > .text > .align 0 > -.globl kernbase > -.set kernbase,KERNBASE > -.globl physaddr > -.set physaddr,PHYSADDR >=20 > /* > * On entry for FreeBSD boot ABI: > @@ -87,7 +81,7 @@ ASENTRY_NP(_start) > orr r7, r7, #(I32_bit|F32_bit) > msr cpsr_c, r7 >=20 > -#if defined (FLASHADDR) && defined(LOADERRAMADDR) > +#if defined(PHYSADDR) && defined(FLASHADDR) && defined(LOADERRAMADDR) > /* Check if we're running from flash. */ > ldr r7, =3DFLASHADDR > /* > @@ -123,11 +117,23 @@ Lram_offset: .word from_ram-_C_LABEL(_start) > from_ram: > nop > #endif > + > + /* > + * The MMU could be disabled (we're on physical addressing), > + * or it could be enabled with VA=3DPA, or it could be enabled > + * with some mystery mapping. In the latter case, there's no > + * easy way to recover the current physical address from the PC. > + * We could maybe do a manual tlb walk, but for now we'll just > + * require that the physical address be provided at compile = time. > + * This is all legacy stuff to support redboot long ago. > + */ Linux requires that the kernel be booted without the MMU enabled to = simplify this case. Is there any reason we can't do the same? > adr r7, Lunmapped > +#ifdef PHYSADDR > bic r7, r7, #0xf0000000 > orr r7, r7, #PHYSADDR > +#endif >=20 > - > disable_mmu: > /* Disable MMU for a while */ > mrc p15, 0, r2, c1, c0, 0 > @@ -142,12 +148,39 @@ disable_mmu: > nop > mov pc, r7 > Lunmapped: > + > +#ifdef PHYSADDR > + ldr r6, =3DPHYSADDR /* If PHYSADDR is provided, use = it. */ > +#else > + adr r0, entry_offset /* Load the linker-provided = offset */ > + ldr r0, [r0] /* between _start and the start = of */ > + adr r6, _start /* the image. Subtract the = offset */ > + sub r6, r6, r0 /* to get the physical load = addr. */ > +#endif > + adr r0, kern_physaddr /* Save it (for debugging = mostly). */ > + str r6, [r0] /* We'll use the addr to build = L1 */ > + mov r0, #0xff000000 /* section PDEs that map 1MB = each; */ > + orr r0, #0x00f00000 /* mask the load address to = round */ > + and r6, r6, r0 /* to previous 1MB boundary. */ > + > #ifdef STARTUP_PAGETABLE_ADDR > + > /* build page table from scratch */ > - ldr r0, Lstartup_pagetable > adr r4, mmu_init_table > - b 3f >=20 > +#define fix_mmu_init(offset) \ > + ldr r0, [r4, offset] ; \ > + orr r0, r0, r6 ; \ > + str r0, [r4, offset] > + > + fix_mmu_init(#4) /* Adjust the va and pa values = in */ > + fix_mmu_init(#8) /* the first two mmu init table = */ > + fix_mmu_init(#16) /* entries to the actual = physical */ > + fix_mmu_init(#20) /* load address calculated = above. */ > + > + ldr r0, Lstartup_pagetable > + b 3f /* Go start building the table. = */ > + > 2: > str r3, [r0, r2] > add r2, r2, #4 > @@ -156,11 +189,9 @@ Lunmapped: > bhi 2b > 3: > ldmia r4!, {r1,r2,r3} /* # of sections, VA, PA|attr */ > + mov r2, r2, LSR #(L1_S_SHIFT-2) > cmp r1, #0 > - adrne r5, 2b > - bicne r5, r5, #0xf0000000 > - orrne r5, r5, #PHYSADDR > - movne pc, r5 > + bne 2b >=20 > #if defined(SMP) > orr r0, r0, #2 /* Set TTB shared memory flag */ > @@ -222,15 +253,7 @@ virt_done: > b _C_LABEL(panic) > /* NOTREACHED */ > #ifdef STARTUP_PAGETABLE_ADDR > -#define MMU_INIT(va,pa,n_sec,attr) \ > - .word n_sec ; \ > - .word 4*((va)>>L1_S_SHIFT) ; \ > - .word (pa)|(attr) ; >=20 > -Lvirtaddr: > - .word KERNVIRTADDR > -Lphysaddr: > - .word KERNPHYSADDR > Lreal_start: > .word _start > Lend:=09 > @@ -241,21 +264,47 @@ Lstartup_pagetable: > Lstartup_pagetable_secondary: > .word temp_pagetable > #endif > -mmu_init_table: > - /* fill all table VA=3D=3DPA */ > - /* map SDRAM VA=3D=3DPA, WT cacheable */ > + > +/*=20 > + * mmu_init_table: data used to construct the initial page tables. > + *=20 > + * Note that the first two table entries are magical. They establish = va=3Dpa and > + * kernva=3Dpa mappings for the first 64 mb starting at the kernel's = physical load > + * address. The virtual and physical addresses of just the first two = entries > + * are re-written by the code that builds the L1 table, to add in the = offset at > + * which the kernel is physically loaded/running. Any entries after = the first > + * two are mapped without modification. This is especially useful = for things > + * like temporarily adding mappings for serial console hardware for = debugging. > + */ > #if !defined(SMP) > - MMU_INIT(PHYSADDR, PHYSADDR , 64, = L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW)) > - /* map VA 0xc0000000..0xc3ffffff to PA */ > - MMU_INIT(KERNBASE, PHYSADDR, 64, = L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW)) > +#define VM_ATTR_DEV (L1_TYPE_S|L1_S_AP(AP_KRW)) > +#define VM_ATTR_RAM (L1_TYPE_S|L1_S_AP(AP_KRW)|L1_S_C) > #else > - MMU_INIT(PHYSADDR, PHYSADDR , 64, = L1_TYPE_S|L1_SHARED|L1_S_C|L1_S_AP(AP_KRW)) > - /* map VA 0xc0000000..0xc3ffffff to PA */ > - MMU_INIT(KERNBASE, PHYSADDR, 64, = L1_TYPE_S|L1_SHARED|L1_S_C|L1_S_AP(AP_KRW)) > - MMU_INIT(0x48000000, 0x48000000, 1, = L1_TYPE_S|L1_SHARED|L1_S_C|L1_S_AP(AP_KRW)) > +#define VM_ATTR_DEV (L1_TYPE_S|L1_S_AP(AP_KRW)|L1_SHARED) > +#define VM_ATTR_RAM (L1_TYPE_S|L1_S_AP(AP_KRW)|L1_SHARED|L1_S_C) > #endif > + > +#define MMU_INIT(va,pa,n_sec,attr) \ > + .word (n_sec) ; \ > + .word (va) ; \ > + .word (pa)|(attr) ; > + > +mmu_init_table: > + MMU_INIT(0, 0, 256, VM_ATTR_RAM) > + MMU_INIT(KERNBASE, 0, 256, VM_ATTR_RAM) > +/* MMU_INIT(0xFFF00000, 0xFFF00000, 1, VM_ATTR_DEV) example hw = entry */ > .word 0 /* end of table */ > -#endif > + > +#endif /* STARTUP_PAGETABLE_ADDR */ > + > + .extern ENTRY_OFFSET /* Import this symbol generated = by */ > +entry_offset: /* ldscript.arm. It is = the offset */ > + .word ENTRY_OFFSET /* of _start in the loaded = image. */ > + > + .globl kern_physaddr /* Export calculated addr, = mostly */ > +kern_physaddr: /* for debugging. There = may be */ > + .word 0 /* no reason to keep this. */ > + > .Lstart: > .word _edata > .word _end > Index: sys/conf/ldscript.arm > =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 > --- sys/conf/ldscript.arm (revision 247421) > +++ sys/conf/ldscript.arm (working copy) > @@ -1,13 +1,17 @@ > /* $FreeBSD$ */ > OUTPUT_ARCH(arm) > -ENTRY(_start) >=20 > -SEARCH_DIR(/usr/lib); > +PHYSOFFS =3D KERNVIRTADDR - KERNPHYSADDR; > +PHYSENTRY =3D _start - PHYSOFFS; > + > +ENTRY(PHYSENTRY) > + > SECTIONS > { > /* Read-only sections, merged into text segment: */ > . =3D KERNVIRTADDR + SIZEOF_HEADERS; > - .text : > + ENTRY_OFFSET =3D _start - KERNVIRTADDR; > + .text : AT(ADDR(.text) - PHYSOFFS) =20 > { > *(.text) > *(.stub) > _______________________________________________ > freebsd-arm@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-arm > To unsubscribe, send any mail to "freebsd-arm-unsubscribe@freebsd.org"
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?042A3136-C7E6-4824-B153-8C8778376106>