1 #include <lunaix/boot_generic.h>
3 #include <asm/aa64_spsr.h>
4 #include <hal/devtree.h>
13 EE=0, E0E=0 // all little endian
14 WXN=1 // write implie exec never
15 SA0=1, SA=1 // alignment check on SP
16 A=1 // alignment check on memref
17 NMI=1 // mask interrupt
21 unsigned long sctrl = 0;
24 sctrl |= SCTRL_WXN | SCTRL_nAA;
25 sctrl |= SCTRL_SA | SCTRL_SA0;
26 sctrl |= SCTRL_A | SCTRL_M;
28 set_sysreg(TCR_EL1, sctrl);
32 extern void aa64_vbase();
37 set_sysreg(VBAR_EL1, __ptr(aa64_vbase));
46 SH0=3 // Inner sharable
47 ORGN0=0 // Normal memory, Outer Non-cacheable.
48 IRGN0=1 // Normal memory, Inner Write-Back Read-Allocate Write-Allocate Cacheable.
49 A1=0 // TTBR0 define ASID
53 T0SZ=16 // disable TTBR1, Use TTBR0 for all translation
54 TG0=0 // VA48, 256T, 4K Granule
56 TBI0=0 // Ignore top bits
59 HD=1 // Hardware managed dirty and access
62 We may use the follow practice later
63 TTBR0: Translation for user-land (lowmem)
64 TTBR1: Translation for kernel-land (highmem)
67 unsigned long tcr = 0;
70 tcr |= TCR_T1SZ(0) | TCR_T0SZ(16);
71 tcr |= TCR_TG0(TCR_G4K);
72 tcr |= TCR_AS | TCR_HA | TCR_HD;
77 set_sysreg(TTBR0_EL1, ttb);
78 set_sysreg(TCR_EL1, tcr);
81 #define MMAP_ENTS_CHUNK_SIZE 16
84 extract_dtb_bootinfo(ptr_t dtb, struct boot_handoff* handoff)
87 struct fdt_memscan mscan;
88 struct dt_memory_node mnode;
90 int mmap_len = 0, mmap_max_len = 16;
92 struct boot_mmapent* mmap;
94 mmap = bootmem_alloc(sizeof(*mmap) * MMAP_ENTS_CHUNK_SIZE);
95 handoff->kexec.dtb_pa = dtb;
97 // TODO extract /memory, /reserved-memories from dtb
100 fdt_memscan_begin(&mscan, &fdt);
102 struct boot_mmapent* mmap_ent;
104 while(fdt_memscan_nextnode(&mscan, &fdt))
106 while (fdt_memscan_nextrange(&mscan, &mnode))
108 mmap_ent = &mmap[mmap_len++];
109 *mmap_ent = (struct boot_mmapent) {
114 if (mnode.type == FDT_MEM_FREE) {
115 mmap_ent->type = BOOT_MMAP_FREE;
116 pmem_size += mnode.size;
119 mmap_ent->type = BOOT_MMAP_RSVD;
123 if (mmap_len < mmap_max_len) {
127 mmap_max_len += MMAP_ENTS_CHUNK_SIZE;
129 // another allocation is just expanding the previous allocation.
130 bootmem_alloc(sizeof(*mmap) * MMAP_ENTS_CHUNK_SIZE);
134 handoff->mem.mmap = mmap;
135 handoff->mem.mmap_len = mmap_len;
136 handoff->mem.size = pmem_size;
146 pfr = read_sysreg(ID_AA64PFR0_EL1);
147 el = read_sysreg(CurrentEL) >> 2;
149 // Arm A-Profile: D19.2.69, check for GIC sysreg avaliability
151 if (!BITS_GET(pfr, BITFIELD(27, 24))) {
155 has_el2 = !!BITS_GET(pfr, BITFIELD(11, 8));
157 // GIC spec (v3,v4): 12.1.7, table 12-2
158 // GIC spec (v3,v4): ICC_SRE_ELx accessing
159 // Arm A-Profile: R_PCDTX, PSTATE.EL reset value
162 sysreg_flagging(ICC_SRE_EL3, ICC_SRE_SRE, 0);
167 sysreg_flagging(ICC_SRE_EL2, ICC_SRE_SRE, 0);
170 sysreg_flagging(ICC_SRE_EL1, ICC_SRE_SRE, 0);
174 aarch64_pre_el1_init()
180 aarch64_prepare_el1_transfer()
185 el = read_sysreg(CurrentEL) >> 2;
188 // no transfer required
192 spsr = SPSR_EL1_preset;
193 spsr |= SPSR_AllInt | SPSR_I | SPSR_F | SPSR_A;
196 set_sysreg(SPSR_EL2, spsr);
199 set_sysreg(SPSR_EL3, spsr);
205 struct boot_handoff* boot_text
206 aarch64_init(ptr_t dtb)
212 struct boot_handoff* handoff;
214 handoff = bootmem_alloc(sizeof(*handoff));
216 extract_dtb_bootinfo(dtb, handoff);