summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2002-04-22 06:43:31 +0000
committermarcel <marcel@FreeBSD.org>2002-04-22 06:43:31 +0000
commitf094098e55e8c0555efc769184372be770b875ff (patch)
treedad401ce591c8ec6099d6f01a5e867f1470fa288 /sys/ia64
parent52a5822310dbce0c5b8f55fe556d0de34a4aacf1 (diff)
downloadFreeBSD-src-f094098e55e8c0555efc769184372be770b875ff.zip
FreeBSD-src-f094098e55e8c0555efc769184372be770b875ff.tar.gz
Add ia64_sal_init_state(). This function will initialize the machine
check handling. In its current form, it only determines the largest amount of state information it can get from SAL and allocates a region 7 memory block for it. The next steps involve: o get and log any unconsumed (NVM stored) error records across reboots, o register an OS_MCA handler and enable machine checks.
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/ia64/sal.c58
1 files changed, 51 insertions, 7 deletions
diff --git a/sys/ia64/ia64/sal.c b/sys/ia64/ia64/sal.c
index 134bf36..53f7aea 100644
--- a/sys/ia64/ia64/sal.c
+++ b/sys/ia64/ia64/sal.c
@@ -28,22 +28,31 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
#include <machine/sal.h>
#include <machine/smp.h>
-void os_boot_rendez(void);
-
struct ia64_fdesc {
u_int64_t func;
u_int64_t gp;
};
+int64_t sal_info_size[SAL_INFO_TYPES];
+vm_offset_t sal_info_block;
+
static struct ia64_fdesc sal_fdesc;
static sal_entry_t fake_sal;
extern u_int64_t ia64_pal_entry;
sal_entry_t *ia64_sal_entry = fake_sal;
+static void ia64_sal_init_state(void *p);
+
+void os_boot_rendez(void);
+
static struct ia64_sal_result
fake_sal(u_int64_t a1, u_int64_t a2, u_int64_t a3, u_int64_t a4,
u_int64_t a5, u_int64_t a6, u_int64_t a7, u_int64_t a8)
@@ -91,7 +100,7 @@ ia64_sal_init(struct sal_system_table *saltab)
case 5: {
struct sal_ap_wakeup_descriptor *dp;
#ifdef SMP
- struct ia64_sal_result sal;
+ struct ia64_sal_result result;
struct ia64_fdesc *fptr = (void*)os_boot_rendez;
int ipi;
#endif
@@ -106,10 +115,9 @@ ia64_sal_init(struct sal_system_table *saltab)
for (ipi = 0; ipi < IPI_COUNT; ipi++)
mp_ipi_vector[ipi] = dp->sale_vector + ipi;
- sal = ia64_sal_entry(SAL_SET_VECTORS,
- SAL_OS_BOOT_RENDEZ,
- ia64_tpa(fptr->func), ia64_tpa(fptr->gp), 0,
- 0, 0, 0);
+ result = ia64_sal_entry(SAL_SET_VECTORS,
+ SAL_OS_BOOT_RENDEZ, ia64_tpa(fptr->func),
+ ia64_tpa(fptr->gp), 0, 0, 0, 0);
mp_hardware = 1;
#endif
@@ -119,3 +127,39 @@ ia64_sal_init(struct sal_system_table *saltab)
p += sizes[*p];
}
}
+
+static void
+ia64_sal_init_state(void *p)
+{
+ struct ia64_sal_result result;
+ uint64_t max_size;
+ int i;
+
+ /*
+ * Get the sizes of the state information we can get from SAL and
+ * allocate a common block (forgive me my Fortran) for use by
+ * support functions. We create a region 7 address to make it
+ * easy on the OS_MCA or OS_INIT handlers.
+ */
+ max_size = 0;
+ for (i = 0; i <= SAL_INFO_TYPES; i++) {
+ result = ia64_sal_entry(SAL_GET_STATE_INFO_SIZE, i, 0, 0, 0,
+ 0, 0, 0);
+ if (result.sal_status == 0) {
+ sal_info_size[i] = result.sal_result[0];
+ if (sal_info_size[i] > max_size)
+ max_size = sal_info_size[i];
+ } else
+ sal_info_size[i] = -1;
+ }
+ max_size = round_page(max_size);
+ p = contigmalloc(max_size, M_TEMP, M_WAITOK, 0ul, 256*1024*1024 - 1,
+ PAGE_SIZE, 256*1024*1024);
+ sal_info_block = IA64_PHYS_TO_RR7(ia64_tpa((u_int64_t)p));
+
+ if (bootverbose)
+ printf("SAL: allocated %d bytes for state information\n",
+ max_size);
+}
+
+SYSINIT(sal_mca, SI_SUB_CPU, SI_ORDER_MIDDLE, ia64_sal_init_state, NULL);
OpenPOWER on IntegriCloud