1 /* This file contains code for initialization of protected mode, to initialize
2 * code and data segment descriptors, and to initialize global descriptors
3 * for local descriptors in the process table.
9 #include <machine/multiboot.h>
11 #include "kernel/kernel.h"
13 #include "archconst.h"
14 #include "arch_proto.h"
19 struct tss_s tss
[CONFIG_MAX_CPUS
];
20 extern int exc_vector_table
;
22 int prot_init_done
= 0;
24 phys_bytes
vir2phys(void *vir
)
26 /* defined in kernel.lds */
27 extern char _kern_vir_base
, _kern_phys_base
;
28 u32_t offset
= (vir_bytes
) &_kern_vir_base
-
29 (vir_bytes
) &_kern_phys_base
;
30 return (phys_bytes
)vir
- offset
;
33 int tss_init(unsigned cpu
, void * kernel_stack
)
36 struct tss_s
* t
= &tss
[cpu
];
39 * make space for process pointer and cpu id and point to the first
42 t
->sp0
= ((unsigned) kernel_stack
) - ARM_STACK_TOP_RESERVED
;
44 * set the cpu id at the top of the stack so we know on which cpu is
45 * this stack in use when we trap to kernel
47 *((reg_t
*)(t
->sp0
+ 1 * sizeof(reg_t
))) = cpu
;
52 multiboot_module_t
*bootmod(int pnr
)
58 /* Search for desired process in boot process
59 * list. The first NR_TASKS ones do not correspond
60 * to a module, however, so we don't search those.
62 for(i
= NR_TASKS
; i
< NR_BOOT_PROCS
; i
++) {
65 if(image
[i
].proc_nr
== pnr
) {
66 assert(p
< MULTIBOOT_MAX_MODS
);
67 assert(p
< kinfo
.mbi
.mi_mods_count
);
68 return &kinfo
.module_list
[p
];
72 panic("boot module %d not found", pnr
);
79 /* tell the HW where we stored our vector table */
80 write_vbar((reg_t
)&exc_vector_table
);
82 /* Set up a new post-relocate bootstrap pagetable so that
83 * we can map in VM, and we no longer rely on pre-relocated
88 pg_identity(&kinfo
); /* Still need 1:1 for device memory . */
95 static int alloc_for_vm
= 0;
97 void arch_post_init(void)
99 /* Let memory mapping code know what's going on at bootstrap time */
101 vm
= proc_addr(VM_PROC_NR
);
102 get_cpulocal_var(ptproc
) = vm
;
103 pg_info(&vm
->p_seg
.p_ttbr
, &vm
->p_seg
.p_ttbr_v
);
106 static int libexec_pg_alloc(struct exec_info
*execi
, vir_bytes vaddr
, size_t len
)
108 pg_map(PG_ALLOCATEME
, vaddr
, vaddr
+len
, &kinfo
);
110 memset((char *) vaddr
, 0, len
);
115 void arch_boot_proc(struct boot_image
*ip
, struct proc
*rp
)
117 multiboot_module_t
*mod
;
118 struct ps_strings
*psp
;
121 if(rp
->p_nr
< 0) return;
123 mod
= bootmod(rp
->p_nr
);
125 /* Important special case: we put VM in the bootstrap pagetable
129 if(rp
->p_nr
== VM_PROC_NR
) {
130 struct exec_info execi
;
132 memset(&execi
, 0, sizeof(execi
));
134 /* exec parameters */
135 execi
.stack_high
= kinfo
.user_sp
;
136 execi
.stack_size
= 64 * 1024; /* not too crazy as it must be preallocated */
137 execi
.proc_e
= ip
->endpoint
;
138 execi
.hdr
= (char *) mod
->mod_start
; /* phys mem direct */
139 execi
.filesize
= execi
.hdr_len
= mod
->mod_end
- mod
->mod_start
;
140 strlcpy(execi
.progname
, ip
->proc_name
, sizeof(execi
.progname
));
143 /* callbacks for use in the kernel */
144 execi
.copymem
= libexec_copy_memcpy
;
145 execi
.clearmem
= libexec_clear_memset
;
146 execi
.allocmem_prealloc_junk
= libexec_pg_alloc
;
147 execi
.allocmem_prealloc_cleared
= libexec_pg_alloc
;
148 execi
.allocmem_ondemand
= libexec_pg_alloc
;
149 execi
.clearproc
= NULL
;
151 /* parse VM ELF binary and alloc/map it into bootstrap pagetable */
152 if(libexec_load_elf(&execi
) != OK
)
153 panic("VM loading failed");
155 /* Setup a ps_strings struct on the stack, pointing to the
156 * following argv, envp. */
157 sp
= (char *)execi
.stack_high
;
158 sp
-= sizeof(struct ps_strings
);
159 psp
= (struct ps_strings
*) sp
;
161 /* Take the stack pointer down three words to give startup code
162 * something to use as "argc", "argv" and "envp".
164 sp
-= (sizeof(void *) + sizeof(void *) + sizeof(int));
166 // linear address space, so it is available.
167 psp
->ps_argvstr
= (char **)(sp
+ sizeof(int));
168 psp
->ps_nargvstr
= 0;
169 psp
->ps_envstr
= psp
->ps_argvstr
+ sizeof(void *);
172 arch_proc_init(rp
, execi
.pc
, (vir_bytes
)sp
,
173 execi
.stack_high
- sizeof(struct ps_strings
),
176 /* Free VM blob that was just copied into existence. */
177 add_memmap(&kinfo
, mod
->mod_start
, mod
->mod_end
-mod
->mod_start
);
178 mod
->mod_end
= mod
->mod_start
= 0;
181 kinfo
.vm_allocated_bytes
= alloc_for_vm
;