Home | History | Annotate | Line # | Download | only in ldd
      1  1.1  kiyohara /*	$NetBSD: e32boot.cpp,v 1.1 2013/04/28 12:11:27 kiyohara Exp $	*/
      2  1.1  kiyohara /*
      3  1.1  kiyohara  * Copyright (c) 2012, 2013 KIYOHARA Takashi
      4  1.1  kiyohara  * All rights reserved.
      5  1.1  kiyohara  *
      6  1.1  kiyohara  * Redistribution and use in source and binary forms, with or without
      7  1.1  kiyohara  * modification, are permitted provided that the following conditions
      8  1.1  kiyohara  * are met:
      9  1.1  kiyohara  * 1. Redistributions of source code must retain the above copyright
     10  1.1  kiyohara  *    notice, this list of conditions and the following disclaimer.
     11  1.1  kiyohara  * 2. Redistributions in binary form must reproduce the above copyright
     12  1.1  kiyohara  *    notice, this list of conditions and the following disclaimer in the
     13  1.1  kiyohara  *    documentation and/or other materials provided with the distribution.
     14  1.1  kiyohara  *
     15  1.1  kiyohara  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  1.1  kiyohara  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17  1.1  kiyohara  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18  1.1  kiyohara  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     19  1.1  kiyohara  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     20  1.1  kiyohara  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     21  1.1  kiyohara  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22  1.1  kiyohara  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     23  1.1  kiyohara  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     24  1.1  kiyohara  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25  1.1  kiyohara  * POSSIBILITY OF SUCH DAMAGE.
     26  1.1  kiyohara  */
     27  1.1  kiyohara 
     28  1.1  kiyohara #include <e32base.h>
     29  1.1  kiyohara #include <e32def.h>
     30  1.1  kiyohara #include <e32std.h>
     31  1.1  kiyohara 
     32  1.1  kiyohara #include "cpu.h"
     33  1.1  kiyohara #include "e32boot.h"
     34  1.1  kiyohara #include "ekern.h"
     35  1.1  kiyohara #include "epoc32.h"
     36  1.1  kiyohara #include "netbsd.h"
     37  1.1  kiyohara 
     38  1.1  kiyohara 
     39  1.1  kiyohara class E32BootLDD : public DLogicalDevice {
     40  1.1  kiyohara public:
     41  1.1  kiyohara 	E32BootLDD(void);
     42  1.1  kiyohara 	virtual TInt Install(void);
     43  1.1  kiyohara 	virtual void GetCaps(TDes8 &) const;
     44  1.1  kiyohara 	virtual DLogicalChannel *CreateL(void);
     45  1.1  kiyohara };
     46  1.1  kiyohara 
     47  1.1  kiyohara class E32BootChannel : public DLogicalChannel {
     48  1.1  kiyohara public:
     49  1.1  kiyohara 	E32BootChannel(DLogicalDevice *);
     50  1.1  kiyohara 
     51  1.1  kiyohara protected:
     52  1.1  kiyohara 	virtual void DoCancel(TInt);
     53  1.1  kiyohara 	virtual void DoRequest(TInt, TAny *, TAny *);
     54  1.1  kiyohara 	virtual TInt DoControl(TInt, TAny *, TAny *);
     55  1.1  kiyohara 
     56  1.1  kiyohara private:
     57  1.1  kiyohara 	EPOC32 *epoc32;
     58  1.1  kiyohara 	TAny *safeAddress;
     59  1.1  kiyohara 
     60  1.1  kiyohara 	TInt BootNetBSD(NetBSD *, struct btinfo_common *);
     61  1.1  kiyohara };
     62  1.1  kiyohara 
     63  1.1  kiyohara 
     64  1.1  kiyohara /* E32Dll() function is required by all DLLs. */
     65  1.1  kiyohara GLDEF_C TInt
     66  1.1  kiyohara E32Dll(TDllReason)
     67  1.1  kiyohara {
     68  1.1  kiyohara 
     69  1.1  kiyohara 	return KErrNone;
     70  1.1  kiyohara }
     71  1.1  kiyohara 
     72  1.1  kiyohara EXPORT_C DLogicalDevice *
     73  1.1  kiyohara CreateLogicalDevice(void)
     74  1.1  kiyohara {
     75  1.1  kiyohara 
     76  1.1  kiyohara 	return new E32BootLDD;
     77  1.1  kiyohara }
     78  1.1  kiyohara 
     79  1.1  kiyohara E32BootLDD::E32BootLDD(void)
     80  1.1  kiyohara {
     81  1.1  kiyohara 	/* Nothing */
     82  1.1  kiyohara }
     83  1.1  kiyohara 
     84  1.1  kiyohara TInt
     85  1.1  kiyohara E32BootLDD::Install(void)
     86  1.1  kiyohara {
     87  1.1  kiyohara 
     88  1.1  kiyohara 	return SetName(&E32BootName);
     89  1.1  kiyohara }
     90  1.1  kiyohara 
     91  1.1  kiyohara void
     92  1.1  kiyohara E32BootLDD::GetCaps(TDes8 &aDes) const
     93  1.1  kiyohara {
     94  1.1  kiyohara 	TVersion version(0, 0, 0);	/* XXXXX: What is it? Don't check? */
     95  1.1  kiyohara 
     96  1.1  kiyohara 	aDes.FillZ(aDes.MaxLength());
     97  1.1  kiyohara 	aDes.Copy((TUint8 *)&version, Min(aDes.MaxLength(), sizeof(version)));
     98  1.1  kiyohara }
     99  1.1  kiyohara 
    100  1.1  kiyohara DLogicalChannel *
    101  1.1  kiyohara E32BootLDD::CreateL(void)
    102  1.1  kiyohara {
    103  1.1  kiyohara 
    104  1.1  kiyohara 	return new (ELeave) E32BootChannel(this);
    105  1.1  kiyohara }
    106  1.1  kiyohara 
    107  1.1  kiyohara 
    108  1.1  kiyohara E32BootChannel::E32BootChannel(DLogicalDevice *aDevice)
    109  1.1  kiyohara     : DLogicalChannel(aDevice)
    110  1.1  kiyohara {
    111  1.1  kiyohara 
    112  1.1  kiyohara 	epoc32 = new EPOC32;
    113  1.1  kiyohara 	safeAddress = NULL;
    114  1.1  kiyohara }
    115  1.1  kiyohara 
    116  1.1  kiyohara void
    117  1.1  kiyohara E32BootChannel::DoCancel(TInt aReqNo)
    118  1.1  kiyohara {
    119  1.1  kiyohara 	/* Nothing */
    120  1.1  kiyohara }
    121  1.1  kiyohara 
    122  1.1  kiyohara void
    123  1.1  kiyohara E32BootChannel::DoRequest(TInt aReqNo, TAny *a1, TAny *a2)
    124  1.1  kiyohara {
    125  1.1  kiyohara 	/* Nothing */
    126  1.1  kiyohara }
    127  1.1  kiyohara 
    128  1.1  kiyohara TInt
    129  1.1  kiyohara E32BootChannel::DoControl(TInt aFunction, TAny *a1, TAny *a2)
    130  1.1  kiyohara {
    131  1.1  kiyohara 
    132  1.1  kiyohara 	switch (aFunction) {
    133  1.1  kiyohara 	case KE32BootGetProcessorID:
    134  1.1  kiyohara 	{
    135  1.1  kiyohara 		TInt id;
    136  1.1  kiyohara 
    137  1.1  kiyohara 		__asm("mrc	p15, 0, %0, c0, c0" : "=r"(id));
    138  1.1  kiyohara 		*(TUint *)a1 = id;
    139  1.1  kiyohara 		break;
    140  1.1  kiyohara 	}
    141  1.1  kiyohara 
    142  1.1  kiyohara 	case KE32BootSetSafeAddress:
    143  1.1  kiyohara 	{
    144  1.1  kiyohara 		safeAddress = (TAny *)PAGE_ALIGN(a1);
    145  1.1  kiyohara 		break;
    146  1.1  kiyohara 	}
    147  1.1  kiyohara 
    148  1.1  kiyohara 	case KE32BootBootNetBSD:
    149  1.1  kiyohara 	{
    150  1.1  kiyohara 		NetBSD *netbsd = (NetBSD *)a1;
    151  1.1  kiyohara 		struct btinfo_common *bootinfo = (struct btinfo_common *)a2;
    152  1.1  kiyohara 
    153  1.1  kiyohara 		BootNetBSD(netbsd, bootinfo);
    154  1.1  kiyohara 
    155  1.1  kiyohara 		/* NOTREACHED */
    156  1.1  kiyohara 
    157  1.1  kiyohara 		break;
    158  1.1  kiyohara 	}
    159  1.1  kiyohara 
    160  1.1  kiyohara 	default:
    161  1.1  kiyohara 		break;
    162  1.1  kiyohara 	}
    163  1.1  kiyohara 	return KErrNone;
    164  1.1  kiyohara }
    165  1.1  kiyohara 
    166  1.1  kiyohara TInt
    167  1.1  kiyohara E32BootChannel::BootNetBSD(NetBSD *netbsd, struct btinfo_common *bootinfo)
    168  1.1  kiyohara {
    169  1.1  kiyohara 	TAny *mmu_disabled, *ttb;
    170  1.1  kiyohara 
    171  1.1  kiyohara 	__asm("adr %0, mmu_disabled" : "=r"(mmu_disabled));
    172  1.1  kiyohara 	mmu_disabled = epoc32->GetPhysicalAddress(mmu_disabled);
    173  1.1  kiyohara 	/*
    174  1.1  kiyohara 	 * ARMv3 can't read TTB from CP15 C1.
    175  1.1  kiyohara 	 * Also can't read Control Register.
    176  1.1  kiyohara 	 */
    177  1.1  kiyohara 	ttb = epoc32->GetPhysicalAddress(epoc32->GetTTB());
    178  1.1  kiyohara 
    179  1.1  kiyohara 	__asm __volatile("				\
    180  1.1  kiyohara 	mrs	r12, cpsr;				\
    181  1.1  kiyohara 	/* Clear PSR_MODE and Interrupts */		\
    182  1.1  kiyohara 	bic	r12, r12, #0xdf;			\
    183  1.1  kiyohara 	/* Disable Interrupts(IRQ/FIQ) */		\
    184  1.1  kiyohara 	orr	r12, r12, #(3 << 6);			\
    185  1.1  kiyohara 	/* Set SVC32 MODE */				\
    186  1.1  kiyohara 	orr	r12, r12, #0x13;			\
    187  1.1  kiyohara 	msr	cpsr_c, r12;				\
    188  1.1  kiyohara 							\
    189  1.1  kiyohara 	ldr	r10, [%0, #0x0];			\
    190  1.1  kiyohara 	ldr	sp, [%0, #0x4];				\
    191  1.1  kiyohara 	ldr	lr, [%0, #0x8];				\
    192  1.1  kiyohara 	mov	r12, %1;				\
    193  1.1  kiyohara 	" :: "r"(netbsd), "r"(bootinfo));
    194  1.1  kiyohara 
    195  1.1  kiyohara 	__asm __volatile("				\
    196  1.1  kiyohara 	mov	r7, %2;					\
    197  1.1  kiyohara 	mov	r8, %1;					\
    198  1.1  kiyohara 	mov	r9, %0;					\
    199  1.1  kiyohara 							\
    200  1.1  kiyohara 	/* Set all domains to 15 */			\
    201  1.1  kiyohara 	mov	r0, #0xffffffff;			\
    202  1.1  kiyohara 	mcr	p15, 0, r0, c3, c0;			\
    203  1.1  kiyohara 							\
    204  1.1  kiyohara 	/* Disable MMU */				\
    205  1.1  kiyohara 	mov	r0, #0x38; /* WBUF | 32BP | 32BD */	\
    206  1.1  kiyohara 	mcr	p15, 0, r0, c1, c0, 0;			\
    207  1.1  kiyohara 							\
    208  1.1  kiyohara 	mov	pc, r7;					\
    209  1.1  kiyohara 							\
    210  1.1  kiyohara mmu_disabled:						\
    211  1.1  kiyohara 	/*						\
    212  1.1  kiyohara 	 * r8	safe address(maybe frame-buffer address)\
    213  1.1  kiyohara 	 * r9	ttb					\
    214  1.1  kiyohara 	 * r10	buffer (netbsd)				\
    215  1.1  kiyohara 	 * r11	memory descriptor			\
    216  1.1  kiyohara 	 * r12	bootinfo				\
    217  1.1  kiyohara 	 * sp	load descriptor				\
    218  1.1  kiyohara 	 * lr	entry point				\
    219  1.1  kiyohara 	 */						\
    220  1.1  kiyohara 	/* save lr to r7 before call functions. */	\
    221  1.1  kiyohara 	mov	r7, lr;					\
    222  1.1  kiyohara 							\
    223  1.1  kiyohara 	mov	r0, r8;					\
    224  1.1  kiyohara 	mov	r1, r9;					\
    225  1.1  kiyohara 	bl	vtop;					\
    226  1.1  kiyohara 	mov	r8, r0;					\
    227  1.1  kiyohara 							\
    228  1.1  kiyohara 	/*						\
    229  1.1  kiyohara 	 * Copy bootinfo to safe address.		\
    230  1.1  kiyohara 	 * That addr used to framebuffer by EPOC32.	\
    231  1.1  kiyohara 	 */						\
    232  1.1  kiyohara 	mov	r0, r12;				\
    233  1.1  kiyohara 	mov	r1, r9;					\
    234  1.1  kiyohara 	bl	vtop;					\
    235  1.1  kiyohara 	mov	r1, r0;					\
    236  1.1  kiyohara 	mov	r12, r8;				\
    237  1.1  kiyohara 	mov	r0, r8;					\
    238  1.1  kiyohara 	mov	r2, #0x400;				\
    239  1.1  kiyohara 	bl	copy;					\
    240  1.1  kiyohara 							\
    241  1.1  kiyohara 	/* save lr(r7) to r8. it is no need. */		\
    242  1.1  kiyohara 	mov	r8, r7;					\
    243  1.1  kiyohara 							\
    244  1.1  kiyohara 	/* Copy loader to safe address + 0x400. */	\
    245  1.1  kiyohara 	add	r0, r12, #0x400;			\
    246  1.1  kiyohara 	adr	r1, miniloader_start;			\
    247  1.1  kiyohara 	adr	r2, miniloader_end;			\
    248  1.1  kiyohara 	sub	r2, r2, r1;				\
    249  1.1  kiyohara 	bl	copy;					\
    250  1.1  kiyohara 							\
    251  1.1  kiyohara 	/* Make load-descriptor to safe addr + 0x800. */\
    252  1.1  kiyohara 	mov	r0, sp;					\
    253  1.1  kiyohara 	mov	r1, r9;					\
    254  1.1  kiyohara 	bl	vtop;					\
    255  1.1  kiyohara 	mov	sp, r0;					\
    256  1.1  kiyohara 	add	r4, r12, #0x800;			\
    257  1.1  kiyohara 							\
    258  1.1  kiyohara next_section:						\
    259  1.1  kiyohara 	ldmia	sp!, {r5 - r7};				\
    260  1.1  kiyohara 							\
    261  1.1  kiyohara next_page:						\
    262  1.1  kiyohara 	add	r0, r10, r6;				\
    263  1.1  kiyohara 	mov	r1, r9;					\
    264  1.1  kiyohara 	bl	vtop;					\
    265  1.1  kiyohara 	/* vtop returns set mask to r2 */		\
    266  1.1  kiyohara 	orr	r2, r0, r2;				\
    267  1.1  kiyohara 	add	r2, r2, #1;				\
    268  1.1  kiyohara 	sub	r2, r2,	r0;				\
    269  1.1  kiyohara 	cmp	r2, r7;					\
    270  1.1  kiyohara 	movgt	r2, r7;					\
    271  1.1  kiyohara 	mov	r1, r0;					\
    272  1.1  kiyohara 	mov	r0, r5;					\
    273  1.1  kiyohara 	stmia	r4!, {r0 - r2};				\
    274  1.1  kiyohara 	add	r5, r5, r2;				\
    275  1.1  kiyohara 	add	r6, r6, r2;				\
    276  1.1  kiyohara 	subs	r7, r7, r2;				\
    277  1.1  kiyohara 	bgt	next_page;				\
    278  1.1  kiyohara 							\
    279  1.1  kiyohara 	ldr	r0, [sp];				\
    280  1.1  kiyohara 	cmp	r0, #0xffffffff;			\
    281  1.1  kiyohara 	beq	fin;					\
    282  1.1  kiyohara 	/* Pad to section align. */			\
    283  1.1  kiyohara 	str	r5, [r4], #4;				\
    284  1.1  kiyohara 	mov	r6, #0xffffffff;			\
    285  1.1  kiyohara 	str	r6, [r4], #4;				\
    286  1.1  kiyohara 	sub	r2, r0, r5;				\
    287  1.1  kiyohara 	str	r2, [r4], #4;				\
    288  1.1  kiyohara 	b	next_section;				\
    289  1.1  kiyohara 							\
    290  1.1  kiyohara fin:							\
    291  1.1  kiyohara 	stmia	r4, {r5 - r7};				\
    292  1.1  kiyohara 	add	sp, r12, #0x800;			\
    293  1.1  kiyohara 							\
    294  1.1  kiyohara 	/* save lr(r8) to r11. r11 is no need. */	\
    295  1.1  kiyohara 	mov	r11, r8;				\
    296  1.1  kiyohara 							\
    297  1.1  kiyohara 	/* Fixup load-descriptor by BTINFO_MEMORY. */	\
    298  1.1  kiyohara 	mov	r10, r12;				\
    299  1.1  kiyohara 	mov	r9, sp;					\
    300  1.1  kiyohara 	add	r8, sp, #12;				\
    301  1.1  kiyohara next_bootinfo:						\
    302  1.1  kiyohara 	ldmia	r10, {r0, r1};				\
    303  1.1  kiyohara 	cmp	r1, #0;		/* BTINFO_NONE */	\
    304  1.1  kiyohara 	beq	btinfo_none;				\
    305  1.1  kiyohara 							\
    306  1.1  kiyohara 	cmp	r1, #2;		/* BTINFO_MEMORY */	\
    307  1.1  kiyohara 	beq	btinfo_memory;				\
    308  1.1  kiyohara 	add	r10, r10, r0;				\
    309  1.1  kiyohara 	b	next_bootinfo;				\
    310  1.1  kiyohara 							\
    311  1.1  kiyohara btinfo_none:						\
    312  1.1  kiyohara 	/* ENOMEM */					\
    313  1.1  kiyohara 	add	r2, r12, #0x800;			\
    314  1.1  kiyohara 	mov	r1, #640;				\
    315  1.1  kiyohara 	mov	r0, #0x00ff0000;			\
    316  1.1  kiyohara 	orr	r0, r0, #0x00ff;			\
    317  1.1  kiyohara 98:							\
    318  1.1  kiyohara 	str	r0, [r2], #4;				\
    319  1.1  kiyohara 	subs	r1, r1, #4;				\
    320  1.1  kiyohara 	bgt	98b;					\
    321  1.1  kiyohara 	mov	r1, #640;				\
    322  1.1  kiyohara 	mov	r0, #0xff000000;			\
    323  1.1  kiyohara 	orr	r0, r0, #0xff00;			\
    324  1.1  kiyohara 99:							\
    325  1.1  kiyohara 	str	r0, [r2], #4;				\
    326  1.1  kiyohara 	subs	r1, r1, #4;				\
    327  1.1  kiyohara 	bgt	99b;					\
    328  1.1  kiyohara 100:							\
    329  1.1  kiyohara 	b	100b;					\
    330  1.1  kiyohara 							\
    331  1.1  kiyohara btinfo_memory:						\
    332  1.1  kiyohara 	ldmia	r10!, {r4 - r7};			\
    333  1.1  kiyohara 	ldr	r4, [r9, #0];				\
    334  1.1  kiyohara 	subs	r4, r4, r6;				\
    335  1.1  kiyohara 	addgt	r6, r6, r4;				\
    336  1.1  kiyohara 	subgt	r7, r7, r4;				\
    337  1.1  kiyohara next_desc:						\
    338  1.1  kiyohara 	ldmia	r9, {r3 - r5};				\
    339  1.1  kiyohara 	ldmia	r8!, {r0 - r2};				\
    340  1.1  kiyohara 	add	r3, r3, r5;				\
    341  1.1  kiyohara 	add	r4, r4, r5;				\
    342  1.1  kiyohara 	cmp	r3, r0;					\
    343  1.1  kiyohara 	cmpeq	r4, r1;					\
    344  1.1  kiyohara 	beq	join_desc;				\
    345  1.1  kiyohara 							\
    346  1.1  kiyohara 	ldr	r3, [r9, #0];				\
    347  1.1  kiyohara 	cmp	r3, r6;					\
    348  1.1  kiyohara 	strlt	r6, [r9, #0];	/* Fixup */		\
    349  1.1  kiyohara 	cmp	r5, r7;					\
    350  1.1  kiyohara 	bgt	split_desc;				\
    351  1.1  kiyohara 	add	r6, r6, r5;				\
    352  1.1  kiyohara 	sub	r7, r7, r5;				\
    353  1.1  kiyohara 	add	r9, r9, #12;				\
    354  1.1  kiyohara 	stmia	r9, {r0 - r2};				\
    355  1.1  kiyohara 	cmp	r0, #0xffffffff;			\
    356  1.1  kiyohara 	beq	fixuped;				\
    357  1.1  kiyohara 	b	next_desc;				\
    358  1.1  kiyohara 							\
    359  1.1  kiyohara join_desc:	/* Join r8 descriptor to r9. */		\
    360  1.1  kiyohara 	add	r5, r5, r2;				\
    361  1.1  kiyohara 	str	r5, [r9, #8];				\
    362  1.1  kiyohara 	b	next_desc;				\
    363  1.1  kiyohara 							\
    364  1.1  kiyohara split_desc:	/* Split r9 descriptor. */		\
    365  1.1  kiyohara 	ldr	r3, [r9, #0];				\
    366  1.1  kiyohara 	ldr	r4, [r9, #4];				\
    367  1.1  kiyohara 	str	r7, [r9, #8];				\
    368  1.1  kiyohara 							\
    369  1.1  kiyohara 	sub	r6, r5, r7;				\
    370  1.1  kiyohara 	add	r5, r4, r7;				\
    371  1.1  kiyohara 	add	r4, r3, r7;				\
    372  1.1  kiyohara 	sub	r8, r8, #12;	/* Back to prev desc */	\
    373  1.1  kiyohara 	add	r9, r9, #12;/* Point to splited desc */ \
    374  1.1  kiyohara 							\
    375  1.1  kiyohara 	cmp	r8, r9;					\
    376  1.1  kiyohara 	bne	2f;					\
    377  1.1  kiyohara 	add	r0, r8, #12;				\
    378  1.1  kiyohara 	mov	r1, r8;					\
    379  1.1  kiyohara 	mov	r2, #0;					\
    380  1.1  kiyohara 1:							\
    381  1.1  kiyohara 	ldr	r3, [r8, r2];				\
    382  1.1  kiyohara 	add	r2, r2, #12;				\
    383  1.1  kiyohara 	cmp	r3, #0xffffffff;			\
    384  1.1  kiyohara 	bne	1b;					\
    385  1.1  kiyohara 	bl	copy;					\
    386  1.1  kiyohara 	add	r8, r8, #12; /* Point to moved desc */	\
    387  1.1  kiyohara 2:							\
    388  1.1  kiyohara 	stmia	r9, {r4 - r6};				\
    389  1.1  kiyohara 	b	next_bootinfo;				\
    390  1.1  kiyohara 							\
    391  1.1  kiyohara fixuped:						\
    392  1.1  kiyohara 	/* Jump to miniloader. Our LR is entry-point! */\
    393  1.1  kiyohara 	add	pc, r12, #0x400;			\
    394  1.1  kiyohara 							\
    395  1.1  kiyohara vtop:							\
    396  1.1  kiyohara 	/*						\
    397  1.1  kiyohara 	 * paddr vtop(vaddr, ttb)			\
    398  1.1  kiyohara 	 */						\
    399  1.1  kiyohara 	bic	r2, r0, #0x000f0000; /* L1_ADDR_BITS */	\
    400  1.1  kiyohara 	bic	r2, r2, #0x0000ff00; /* L1_ADDR_BITS */	\
    401  1.1  kiyohara 	bic	r2, r2, #0x000000ff; /* L1_ADDR_BITS */	\
    402  1.1  kiyohara 	mov	r2, r2, lsr #(20 - 2);			\
    403  1.1  kiyohara 	ldr	r1, [r1, r2];				\
    404  1.1  kiyohara 	and	r3, r1, #0x3;	/* L1_TYPE_MASK */	\
    405  1.1  kiyohara 	cmp	r3, #0;					\
    406  1.1  kiyohara 	bne	valid;					\
    407  1.1  kiyohara 							\
    408  1.1  kiyohara invalid:						\
    409  1.1  kiyohara 	mov	r0, #-1;				\
    410  1.1  kiyohara 	mov	pc, lr;					\
    411  1.1  kiyohara 							\
    412  1.1  kiyohara valid:							\
    413  1.1  kiyohara 	cmp	r3, #0x2;				\
    414  1.1  kiyohara 	bgt	3f;					\
    415  1.1  kiyohara 	beq	2f;					\
    416  1.1  kiyohara 							\
    417  1.1  kiyohara 1:	/* Coarse L2 */					\
    418  1.1  kiyohara 	mov	r2, #10;				\
    419  1.1  kiyohara 	b	l2;					\
    420  1.1  kiyohara 							\
    421  1.1  kiyohara 2:	/* Section */					\
    422  1.1  kiyohara 	mov	r2, #0xff000000;    /* L1_S_ADDR_MASK */\
    423  1.1  kiyohara 	add	r2, r2, #0x00f00000;/* L1_S_ADDR_MASK */\
    424  1.1  kiyohara 	mvn	r2, r2;					\
    425  1.1  kiyohara 	bic	r3, r1, r2;				\
    426  1.1  kiyohara 	and	r0, r0, r2;				\
    427  1.1  kiyohara 	orr	r0, r3, r0;				\
    428  1.1  kiyohara 	mov	pc, lr;					\
    429  1.1  kiyohara 							\
    430  1.1  kiyohara 3:	/* Fine L2 */					\
    431  1.1  kiyohara 	mov	r2, #12;				\
    432  1.1  kiyohara l2:							\
    433  1.1  kiyohara 	mov	r3, #1;					\
    434  1.1  kiyohara 	mov	r3, r3, lsl r2;				\
    435  1.1  kiyohara 	sub	r3, r3, #1;				\
    436  1.1  kiyohara 	bic	r1, r1, r3;	/* L2 table */		\
    437  1.1  kiyohara 	mov	r3, r0, lsl #12;			\
    438  1.1  kiyohara 	mov	r3, r3, lsr #12;			\
    439  1.1  kiyohara 	sub	r2, r2, #22;				\
    440  1.1  kiyohara 	rsb	r2, r2, #0;				\
    441  1.1  kiyohara 	mov	r3, r3, lsr r2;	/* index for L2 */	\
    442  1.1  kiyohara 	ldr	r1, [r1, r3, lsl #2];			\
    443  1.1  kiyohara 	and	r3, r1, #0x3;	/* L2_TYPE_MASK */	\
    444  1.1  kiyohara 	cmp	r3, #0;					\
    445  1.1  kiyohara 	beq	invalid;				\
    446  1.1  kiyohara 	cmp	r3, #2;					\
    447  1.1  kiyohara 	movlt	r2, #16;	/* L2_L_SHIFT */	\
    448  1.1  kiyohara 	moveq	r2, #12;	/* L2_S_SHIFT */	\
    449  1.1  kiyohara 	movgt	r2, #10;	/* L2_T_SHIFT */	\
    450  1.1  kiyohara 	mov	r3, #1;					\
    451  1.1  kiyohara 	mov	r2, r3, lsl r2;				\
    452  1.1  kiyohara 	sub	r2, r2, #1;				\
    453  1.1  kiyohara 	bic	r3, r1, r2;				\
    454  1.1  kiyohara 	and	r0, r0, r2;				\
    455  1.1  kiyohara 	orr	r0, r3, r0;				\
    456  1.1  kiyohara 	mov	pc, lr;					\
    457  1.1  kiyohara 							\
    458  1.1  kiyohara miniloader_start:					\
    459  1.1  kiyohara 	b	miniloader;				\
    460  1.1  kiyohara 							\
    461  1.1  kiyohara copy:							\
    462  1.1  kiyohara 	/*						\
    463  1.1  kiyohara 	 * void copy(dest, src, len)			\
    464  1.1  kiyohara 	 */						\
    465  1.1  kiyohara 	cmp	r0, r1;					\
    466  1.1  kiyohara 	bgt	rcopy;					\
    467  1.1  kiyohara lcopy:							\
    468  1.1  kiyohara 	ldr	r3, [r1], #4;				\
    469  1.1  kiyohara 	str	r3, [r0], #4;				\
    470  1.1  kiyohara 	subs	r2, r2, #4;				\
    471  1.1  kiyohara 	bgt	lcopy;					\
    472  1.1  kiyohara 	mov	pc, lr;					\
    473  1.1  kiyohara rcopy:							\
    474  1.1  kiyohara 	subs	r2, r2, #4;				\
    475  1.1  kiyohara 	ldr	r3, [r1, r2];				\
    476  1.1  kiyohara 	str	r3, [r0, r2];				\
    477  1.1  kiyohara 	bgt	rcopy;					\
    478  1.1  kiyohara 	mov	pc, lr;					\
    479  1.1  kiyohara 							\
    480  1.1  kiyohara 							\
    481  1.1  kiyohara miniloader:						\
    482  1.1  kiyohara 	/*						\
    483  1.1  kiyohara 	 * r11	entry-point				\
    484  1.1  kiyohara 	 * r12	bootinfo				\
    485  1.1  kiyohara 	 * sp	load-descriptor				\
    486  1.1  kiyohara 	 */						\
    487  1.1  kiyohara load:							\
    488  1.1  kiyohara 	ldmia	sp!, {r0 - r2};				\
    489  1.1  kiyohara 	cmp	r0, #0xffffffff;			\
    490  1.1  kiyohara 	beq	end;					\
    491  1.1  kiyohara 	cmp	r1, #0xffffffff;/* Skip section align */\
    492  1.1  kiyohara 	blne	copy;		 /* or copy */		\
    493  1.1  kiyohara 	b	load;					\
    494  1.1  kiyohara 							\
    495  1.1  kiyohara end:							\
    496  1.1  kiyohara 	mov	r0, r12;				\
    497  1.1  kiyohara 	mov	pc, r11;				\
    498  1.1  kiyohara 	nop;						\
    499  1.1  kiyohara 	nop;						\
    500  1.1  kiyohara miniloader_end:						\
    501  1.1  kiyohara 							\
    502  1.1  kiyohara 	"
    503  1.1  kiyohara 	::"r"(ttb),
    504  1.1  kiyohara 	  "r"(safeAddress),
    505  1.1  kiyohara 	  "r"(mmu_disabled)
    506  1.1  kiyohara 	);
    507  1.1  kiyohara 
    508  1.1  kiyohara 	/* NOTREACHED */
    509  1.1  kiyohara 
    510  1.1  kiyohara 	return -1;
    511  1.1  kiyohara }
    512