summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2008-02-04 02:21:33 +0000
committermarcel <marcel@FreeBSD.org>2008-02-04 02:21:33 +0000
commitc1a1c62b2afb3f2602fa7d2c438ce32eacc9f72b (patch)
treeb4eb04d38b3f9012de64a868c443f8563f747654 /sys/ia64
parent72d185548f88b6924d5a926aa9b6877ebe113169 (diff)
downloadFreeBSD-src-c1a1c62b2afb3f2602fa7d2c438ce32eacc9f72b.zip
FreeBSD-src-c1a1c62b2afb3f2602fa7d2c438ce32eacc9f72b.tar.gz
Allocate a stack for thread0 and switch to it before calling
mi_startup(). This frees up kstack for static PAL/SAL calls and double-fault handling.
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/ia64/locore.S22
-rw-r--r--sys/ia64/ia64/machdep.c26
-rw-r--r--sys/ia64/include/md_var.h7
3 files changed, 34 insertions, 21 deletions
diff --git a/sys/ia64/ia64/locore.S b/sys/ia64/ia64/locore.S
index e52c76a..6b1d8f1 100644
--- a/sys/ia64/ia64/locore.S
+++ b/sys/ia64/ia64/locore.S
@@ -110,6 +110,28 @@ ENTRY_NOPROFILE(__start, 1)
br.call.sptk.many rp=ia64_init
;;
}
+ // We have the new bspstore in r8 and the new sp in r9.
+ // Switch onto the new stack and call mi_startup().
+{
+ mov ar.rsc = 0
+ ;;
+ mov ar.bspstore = r8
+ mov sp = r9
+ ;;
+}
+{
+ loadrs
+ ;;
+ mov ar.rsc = 3
+ nop 0
+ ;;
+}
+{
+ nop 0
+ nop 0
+ br.call.sptk.many rp=mi_startup
+ ;;
+}
/* NOTREACHED */
1: br.cond.sptk.few 1b
END(__start)
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index e6e5d7f..0c28f2b 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -109,8 +109,6 @@ u_int64_t pa_bootinfo;
struct bootinfo bootinfo;
struct pcpu pcpu0;
-extern char kstack[];
-vm_offset_t proc0kstack;
extern u_int64_t kernel_text[], _end[];
@@ -153,8 +151,6 @@ vm_paddr_t phys_avail[PHYSMAP_SIZE + 2];
/* must be 2 less so 0 0 can signal end of chunks */
#define PHYS_AVAIL_ARRAY_END ((sizeof(phys_avail) / sizeof(vm_offset_t)) - 2)
-void mi_startup(void); /* XXX should be in a MI header */
-
struct kva_md_info kmi;
#define Mhz 1000000L
@@ -550,9 +546,10 @@ calculate_frequencies(void)
}
}
-void
+struct ia64_init_return
ia64_init(void)
{
+ struct ia64_init_return ret;
int phys_avail_cnt;
vm_offset_t kernstart, kernend;
vm_offset_t kernstartpfn, kernendpfn, pfn0, pfn1;
@@ -793,8 +790,7 @@ ia64_init(void)
/*
* Init mapping for kernel stack for proc 0
*/
- proc0kstack = (vm_offset_t)kstack;
- thread0.td_kstack = proc0kstack;
+ thread0.td_kstack = pmap_steal_memory(KSTACK_PAGES * PAGE_SIZE);
thread0.td_kstack_pages = KSTACK_PAGES;
mutex_init();
@@ -831,19 +827,9 @@ ia64_init(void)
ia64_set_tpr(0);
ia64_srlz_d();
- /*
- * Save our current context so that we have a known (maybe even
- * sane) context as the initial context for new threads that are
- * forked from us. If any of those threads (including thread0)
- * does something wrong, we may be lucky and return here where
- * we're ready for them with a nice panic.
- */
- if (!savectx(thread0.td_pcb))
- mi_startup();
-
- /* We should not get here. */
- panic("ia64_init: Whooaa there!");
- /* NOTREACHED */
+ ret.bspstore = thread0.td_pcb->pcb_special.bspstore;
+ ret.sp = thread0.td_pcb->pcb_special.sp;
+ return (ret);
}
__volatile void *
diff --git a/sys/ia64/include/md_var.h b/sys/ia64/include/md_var.h
index 738fefa..0520e57 100644
--- a/sys/ia64/include/md_var.h
+++ b/sys/ia64/include/md_var.h
@@ -71,6 +71,11 @@ struct reg;
struct thread;
struct trapframe;
+struct ia64_init_return {
+ uint64_t bspstore;
+ uint64_t sp;
+};
+
void busdma_swi(void);
int copyout_regstack(struct thread *, uint64_t *, uint64_t *);
void cpu_mp_add(u_int, u_int, u_int);
@@ -82,7 +87,7 @@ int ia64_flush_dirty(struct thread *, struct _special *);
uint64_t ia64_get_hcdp(void);
int ia64_highfp_drop(struct thread *);
int ia64_highfp_save(struct thread *);
-void ia64_init(void);
+struct ia64_init_return ia64_init(void);
void ia64_probe_sapics(void);
void interrupt(struct trapframe *);
void map_gateway_page(void);
OpenPOWER on IntegriCloud