Added: Xeon Phi Manager
authorReto Achermann <acreto@student.ethz.ch>
Mon, 28 Apr 2014 15:42:04 +0000 (17:42 +0200)
committerStefan Kaestle <stefan.kaestle@inf.ethz.ch>
Wed, 20 Aug 2014 13:59:05 +0000 (15:59 +0200)
Responsible for assigning a unique ID to the Xeon Phi drivers and
exchanging the irefs of xeon phi drivers such that they can connect
to eachother

20 files changed:
devices/xeon_phi/xeon_phi_boot.dev
if/Hakefile
if/xeon_phi.if [new file with mode: 0644]
if/xeon_phi_manager.if [new file with mode: 0644]
include/xeon_phi/xeon_phi.h [new file with mode: 0644]
include/xeon_phi/xeon_phi_manager_client.h [new file with mode: 0644]
lib/xeon_phi_manager_client/Hakefile [new file with mode: 0644]
lib/xeon_phi_manager_client/xeon_phi_manager_client.c [new file with mode: 0644]
usr/drivers/xeon_phi/Hakefile
usr/drivers/xeon_phi/main.c
usr/drivers/xeon_phi/service.c
usr/drivers/xeon_phi/service.h [new file with mode: 0644]
usr/drivers/xeon_phi/xeon_phi.c
usr/drivers/xeon_phi/xeon_phi.h
usr/xeon_phi_manager/Hakefile [new file with mode: 0644]
usr/xeon_phi_manager/cardmanager.c [new file with mode: 0644]
usr/xeon_phi_manager/cardmanager.h [new file with mode: 0644]
usr/xeon_phi_manager/main.c [new file with mode: 0644]
usr/xeon_phi_manager/service.c [new file with mode: 0644]
usr/xeon_phi_manager/service.h [new file with mode: 0644]

index 63f550f..c89c337 100644 (file)
@@ -64,92 +64,92 @@ device xeon_phi_boot lsbfirst ( addr sbox_base, addr dbox_base ) "Intel Xeon Phi
     };
     
     register reset rw addr(sbox_base, 0x4010) {
-       reset  1 "Perform device rest";
-       _     31; 
+        reset  1 "Perform device rest";
+        _     31; 
     };
     
     /*
      * Note: The post codes are represented as a two byte ASCII values  
      */
     constants postcodes width(16) "The Xeon Phi Post codes" {
-               postcode_lidt           = 0x3031 "01 LIDT";
-               postcode_sboxinit       = 0x3032 "02 SBOX initialization";
-               postcode_gddrtop        = 0x3033 "03 Set GDDR Top";
-               postcode_memtest        = 0x3034 "04 Begin memory test";
-               postcode_e820           = 0x3035 "05 Program E820 table";
-               postcode_dbox           = 0x3036 "06 Initialize DBOX";
-               postcode_cache          = 0x3039 "09 Enable Cache";    
-               postcode_initap         = 0x3062 "0b Pass initialization params to APs";
-               postcode_code           = 0x3063 "0c Cache C code";
-               postcode_mp             = 0x3045 "0E Program MP table";
-               postcode_apwkup         = 0x3046 "0F Wake up APs";
-               postcode_apboot         = 0x3130 "10 Wait for APs to boot";
-               postcode_sig            = 0x3131 "11 Signal host to download OS";
-               postcode_ready          = 0x3132 "12 Wait for download READY";
-               postcode_boot           = 0x3133 "13 Signal to boot received";
-               postcode_pinfo          = 0x3135 "15 Report platform information";
-               postcode_ptable         = 0x3137 "17 Page table setup";
-               postcode_memtrain       = 0x3330 "30 Begin memory training";
-               postcode_gddrtrain      = 0x3331 "31 GDDR Training to query memory modules";
-               postcode_findgddrtrain  = 0x3332 "32 Find GDDR training parameters in flash";
-               postcode_mmiotrain      = 0x3333 "33 MMIO training";
-               postcode_rcomptrain     = 0x3334 "34 RCOMP training";
-               postcode_dcctrain       = 0x3335 "35 DCC disable training";
-               postcode_hcktrain       = 0x3336 "36 HCK training";
-               postcode_ucodetrain     = 0x3337 "37 UCode Training";
-               postcode_vendortrain    = 0x3338 "38 Vendor specific training";
-               postcode_addrtrain      = 0x3339 "39 GDDR address training";
-               postcode_gddrident      = 0x3341 "3A GDDR memory module identification";
-               postcode_wcktrain       = 0x3362 "3b GDDR WCK training";
-               postcode_cdrdtrain      = 0x3343 "3C GDDR read training with CDR enabled";
-               postcode_cdretrain      = 0x3364 "3d GDDR Read Training with CDR disabled";
-               postcode_wrtrain        = 0x3345 "3E GDDR Write Training";
-               postcode_fintrain       = 0x3346 "3F Finalize GDDR Training";
-               postcode_osauth         = 0x3430 "40 Begin Coprocessor OS authentification";
-               postcode_loading0       = 0x3530 "50 Coprocessor OS Loading 0";
-               postcode_loading1       = 0x3531 "51 Coprocessor OS Loading 1";
-               postcode_loading2       = 0x3532 "52 Coprocessor OS Loading 2";
-               postcode_loading3       = 0x3533 "53 Coprocessor OS Loading 3";
-               postcode_loading4       = 0x3534 "54 Coprocessor OS Loading 4";
-               postcode_loading5       = 0x3535 "55 Coprocessor OS Loading 5";
-               postcode_loading6       = 0x3536 "56 Coprocessor OS Loading 6";
-               postcode_loading7       = 0x3537 "57 Coprocessor OS Loading 7";
-               postcode_loading8       = 0x3538 "58 Coprocessor OS Loading 8";
-               postcode_loading9       = 0x3539 "59 Coprocessor OS Loading 9";
-               postcode_loadingb       = 0x3541 "5A Coprocessor OS Loading A";
-               postcode_loadinga       = 0x3542 "5B Coprocessor OS Loading B";
-               postcode_loadingc       = 0x3543 "5C Coprocessor OS Loading C";
-               postcode_loadingd       = 0x3544 "5D Coprocessor OS Loading D";
-               postcode_loadinge       = 0x3545 "5E Coprocessor OS Loading E";
-               postcode_loadingf       = 0x3546 "5F Coprocessor OS Loading F";
-               postcode_gp             = 0x3650 "6P Int 13 - General Protection Fault";
-               postcode_tss            = 0x3735 "75 Int 10 - Invalid TSS";
-               postcode_fpu            = 0x3837 "87 Int 16 - x87 FPU Error";
-               postcode_algin          = 0x4143 "AC INT 17 - Alignment Check";
-               postcode_bp             = 0x6250 "bP INT 3 - Break Point";
-               postcode_bound          = 0x6272 "br INT 5 - BOUND Range Exceeded";
-               postcode_mc             = 0x4343 "CC INT 18 - Machine Check";
-               postcode_seg            = 0x636F "co INT 9 - Coprocessor Segmenet Overrun";
-               postcode_dbg            = 0x6462 "db INT 1 - Debug";
-               postcode_div            = 0x6445 "dE INT 0 - Divide Error";
-               postcode_df             = 0x6446 "dF INT 8 - Double Fault";
-               postcode_memf           = 0x4545 "EE Memory Test Failed";
-               postcode_pnf            = 0x4630 "F0 GDDR Parameters not found";
-               postcode_pllf           = 0x4631 "F1 GBOX PLL lock failure";
-               postcode_memtf          = 0x4632 "F2 GDDR failed memory training";
-               postcode_memqf          = 0x4633 "F3 GDDR memory module query failed";
-               postcode_mempf          = 0x4634 "F4 Memory preservation failure";
-           postcode_sf             = 0x4635 "F5 INT 12 - Stack Fault";
-           postcode_done           = 0x4646 "FF - Bootstrap finished execution";
-           postcode_ld             = 0x4C64 "Ld - Locking down hardware access";
-           postcode_authf          = 0x6E41 "nA - OS Image failed Authentification";
-           postcode_dna            = 0x6E64 "nd INT 7 - Device not Available";
-           postcode_nmi            = 0x6E6F "no INT 2 - Non-maskable Interrupt";
-           postcode_snp            = 0x6E50 "nP INT 11 - Segment Not Present";
-           postcode_of             = 0x6F46 "oF INT 4 - Overflow";
-           postcode_pf             = 0x5046 "PF INT 14 - Pagefault";
-           postcode_rs             = 0x7235 "r5 INT 15 - Reserved";
-           postcode_iop            = 0x7564 "ud INT 6 - Invalid OP code";
+        postcode_lidt           = 0x3031 "01 LIDT";
+        postcode_sboxinit       = 0x3032 "02 SBOX initialization";
+        postcode_gddrtop        = 0x3033 "03 Set GDDR Top";
+        postcode_memtest        = 0x3034 "04 Begin memory test";
+        postcode_e820           = 0x3035 "05 Program E820 table";
+        postcode_dbox           = 0x3036 "06 Initialize DBOX";
+        postcode_cache          = 0x3039 "09 Enable Cache";    
+        postcode_initap         = 0x3062 "0b Pass initialization params to APs";
+        postcode_code           = 0x3063 "0c Cache C code";
+        postcode_mp             = 0x3045 "0E Program MP table";
+        postcode_apwkup         = 0x3046 "0F Wake up APs";
+        postcode_apboot         = 0x3130 "10 Wait for APs to boot";
+        postcode_sig            = 0x3131 "11 Signal host to download OS";
+        postcode_ready          = 0x3132 "12 Wait for download READY";
+        postcode_boot           = 0x3133 "13 Signal to boot received";
+        postcode_pinfo          = 0x3135 "15 Report platform information";
+        postcode_ptable         = 0x3137 "17 Page table setup";
+        postcode_memtrain       = 0x3330 "30 Begin memory training";
+        postcode_gddrtrain      = 0x3331 "31 GDDR Training to query memory modules";
+        postcode_findgddrtrain  = 0x3332 "32 Find GDDR training parameters in flash";
+        postcode_mmiotrain      = 0x3333 "33 MMIO training";
+        postcode_rcomptrain     = 0x3334 "34 RCOMP training";
+        postcode_dcctrain       = 0x3335 "35 DCC disable training";
+        postcode_hcktrain       = 0x3336 "36 HCK training";
+        postcode_ucodetrain     = 0x3337 "37 UCode Training";
+        postcode_vendortrain    = 0x3338 "38 Vendor specific training";
+        postcode_addrtrain      = 0x3339 "39 GDDR address training";
+        postcode_gddrident      = 0x3341 "3A GDDR memory module identification";
+        postcode_wcktrain       = 0x3362 "3b GDDR WCK training";
+        postcode_cdrdtrain      = 0x3343 "3C GDDR read training with CDR enabled";
+        postcode_cdretrain      = 0x3364 "3d GDDR Read Training with CDR disabled";
+        postcode_wrtrain        = 0x3345 "3E GDDR Write Training";
+        postcode_fintrain       = 0x3346 "3F Finalize GDDR Training";
+        postcode_osauth         = 0x3430 "40 Begin Coprocessor OS authentification";
+        postcode_loading0       = 0x3530 "50 Coprocessor OS Loading 0";
+        postcode_loading1       = 0x3531 "51 Coprocessor OS Loading 1";
+        postcode_loading2       = 0x3532 "52 Coprocessor OS Loading 2";
+        postcode_loading3       = 0x3533 "53 Coprocessor OS Loading 3";
+        postcode_loading4       = 0x3534 "54 Coprocessor OS Loading 4";
+        postcode_loading5       = 0x3535 "55 Coprocessor OS Loading 5";
+        postcode_loading6       = 0x3536 "56 Coprocessor OS Loading 6";
+        postcode_loading7       = 0x3537 "57 Coprocessor OS Loading 7";
+        postcode_loading8       = 0x3538 "58 Coprocessor OS Loading 8";
+        postcode_loading9       = 0x3539 "59 Coprocessor OS Loading 9";
+        postcode_loadingb       = 0x3541 "5A Coprocessor OS Loading A";
+        postcode_loadinga       = 0x3542 "5B Coprocessor OS Loading B";
+        postcode_loadingc       = 0x3543 "5C Coprocessor OS Loading C";
+        postcode_loadingd       = 0x3544 "5D Coprocessor OS Loading D";
+        postcode_loadinge       = 0x3545 "5E Coprocessor OS Loading E";
+        postcode_loadingf       = 0x3546 "5F Coprocessor OS Loading F";
+        postcode_gp             = 0x3650 "6P Int 13 - General Protection Fault";
+        postcode_tss            = 0x3735 "75 Int 10 - Invalid TSS";
+        postcode_fpu            = 0x3837 "87 Int 16 - x87 FPU Error";
+        postcode_algin          = 0x4143 "AC INT 17 - Alignment Check";
+        postcode_bp             = 0x6250 "bP INT 3 - Break Point";
+        postcode_bound          = 0x6272 "br INT 5 - BOUND Range Exceeded";
+        postcode_mc             = 0x4343 "CC INT 18 - Machine Check";
+        postcode_seg            = 0x636F "co INT 9 - Coprocessor Segmenet Overrun";
+        postcode_dbg            = 0x6462 "db INT 1 - Debug";
+        postcode_div            = 0x6445 "dE INT 0 - Divide Error";
+        postcode_df             = 0x6446 "dF INT 8 - Double Fault";
+        postcode_memf           = 0x4545 "EE Memory Test Failed";
+        postcode_pnf            = 0x4630 "F0 GDDR Parameters not found";
+        postcode_pllf           = 0x4631 "F1 GBOX PLL lock failure";
+        postcode_memtf          = 0x4632 "F2 GDDR failed memory training";
+        postcode_memqf          = 0x4633 "F3 GDDR memory module query failed";
+        postcode_mempf          = 0x4634 "F4 Memory preservation failure";
+        postcode_sf             = 0x4635 "F5 INT 12 - Stack Fault";
+        postcode_done           = 0x4646 "FF - Bootstrap finished execution";
+        postcode_ld             = 0x4C64 "Ld - Locking down hardware access";
+        postcode_authf          = 0x6E41 "nA - OS Image failed Authentification";
+        postcode_dna            = 0x6E64 "nd INT 7 - Device not Available";
+        postcode_nmi            = 0x6E6F "no INT 2 - Non-maskable Interrupt";
+        postcode_snp            = 0x6E50 "nP INT 11 - Segment Not Present";
+        postcode_of             = 0x6F46 "oF INT 4 - Overflow";
+        postcode_pf             = 0x5046 "PF INT 14 - Pagefault";
+        postcode_rs             = 0x7235 "r5 INT 15 - Reserved";
+        postcode_iop            = 0x7564 "ud INT 6 - Invalid OP code";
     };
     
     constants postcodes_special width(32) "The Xeon Phi Post codes" {
@@ -159,8 +159,8 @@ device xeon_phi_boot lsbfirst ( addr sbox_base, addr dbox_base ) "Intel Xeon Phi
     
     
     register postcode rw addr(dbox_base, 0x242c) {
-       code  16 type(postcodes);
-       _     16;
+        code  16 type(postcodes);
+        _     16;
     };
     
     register postcode_raw rw also addr(dbox_base, 0x242c) {
index 39ae121..f3f61ee 100644 (file)
                "unixsock",
                "bcache",
                "replay",
+               "xeon_phi",
+               "xeon_phi_manager",
                "block_service",
                "bulk_ctrl",
-               "empty"
+               "empty" 
+               
            ],
              arch <- allArchitectures
 ] ++
diff --git a/if/xeon_phi.if b/if/xeon_phi.if
new file mode 100644 (file)
index 0000000..4b8c584
--- /dev/null
@@ -0,0 +1,21 @@
+/** \file
+ *  \brief Xeon Phi Service Interface
+ */
+
+/*
+ * Copyright (c) 2012, ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+interface xeon_phi "Xeon Phi Service Interface" {
+
+    rpc register(in uint8 id, out errval msgerr);
+    
+    
+    
+    message unused(); // Make compiler work
+};
\ No newline at end of file
diff --git a/if/xeon_phi_manager.if b/if/xeon_phi_manager.if
new file mode 100644 (file)
index 0000000..266a63d
--- /dev/null
@@ -0,0 +1,20 @@
+/** \file
+ *  \brief Xeon Phi Manager Interface
+ */
+
+/*
+ * Copyright (c) 2012, ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+interface xeon_phi_manager "Xeon Phi Manager Interface" {
+    
+    
+    rpc register(in iref svc, out uint8 id, out uint8 cards[n], out errval msgerr);
+    
+    rpc terminate();
+};
\ No newline at end of file
diff --git a/include/xeon_phi/xeon_phi.h b/include/xeon_phi/xeon_phi.h
new file mode 100644 (file)
index 0000000..9469bf6
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2014 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef XEON_PHI_XEON_PHI_H_
+#define XEON_PHI_XEON_PHI_H_
+
+/// The maximum number of coprocessor cards in a system
+#define XEON_PHI_NUM_MAX 8
+
+#endif // XEON_PHI_XEON_PHI_H_
diff --git a/include/xeon_phi/xeon_phi_manager_client.h b/include/xeon_phi/xeon_phi_manager_client.h
new file mode 100644 (file)
index 0000000..6bc22e6
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef XEON_PHI_MANAGER_CLIENT_H
+#define XEON_PHI_MANAGER_CLIENT_H
+
+#define XEON_PHI_MANAGER_SERVICE_NAME "xeon_phi_manager"
+
+#define DEBUG_XPMC(x...) debug_printf(" XPMC | " x)
+
+/**
+ * \brief   registers the Xeon Phi driver card with the Xeon Phi Manager
+ *          this function blocks until we have a connection to the manager
+ *
+ * \param   svc_iref    the iref of the drivers service
+ * \param   id          the own card id
+ * \param   num         returns the number of returned irefs / number of cards
+ * \param   cards       returns the array of irefs
+ *
+ * \return SYS_ERR_OK on success
+ */
+errval_t xeon_phi_manager_client_register(iref_t svc_iref,
+                                          uint8_t *id,
+                                          uint8_t *num,
+                                          iref_t **cards);
+
+/**
+ * \brief   deregisters the Xeon Phi driver with the Xeon Phi Manager
+ *
+ * \return SYS_ERR_OK on success
+ */
+errval_t xeon_phi_manager_client_deregister(void);
+
+#endif // XEON_PHI_MANAGER_CLIENT_H
diff --git a/lib/xeon_phi_manager_client/Hakefile b/lib/xeon_phi_manager_client/Hakefile
new file mode 100644 (file)
index 0000000..92cce06
--- /dev/null
@@ -0,0 +1,20 @@
+
+--------------------------------------------------------------------------
+-- Copyright (c) 2007-2012, ETH Zurich.
+-- All rights reserved.
+--
+-- This file is distributed under the terms in the attached LICENSE file.
+-- If you do not find this file, copies can be found by writing to:
+-- ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+--
+-- Hakefile for lib/xeon_phi_manager_client
+-- 
+--------------------------------------------------------------------------
+
+[ build library { target = "xeon_phi_manager_client",
+                      cFiles = [ "xeon_phi_manager_client.c" ],
+                      flounderDefs = ["xeon_phi_manager"],
+                      flounderBindings = ["xeon_phi_manager"],
+                      architectures = ["x86_64"]
+                }
+]
diff --git a/lib/xeon_phi_manager_client/xeon_phi_manager_client.c b/lib/xeon_phi_manager_client/xeon_phi_manager_client.c
new file mode 100644 (file)
index 0000000..fc974d7
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2014 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <string.h>
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/nameservice_client.h>
+
+#include <xeon_phi/xeon_phi_manager_client.h>
+
+#include <if/xeon_phi_manager_defs.h>
+
+enum xpm_state
+{
+    XPM_STATE_NSLOOKUP,
+    XPM_STATE_BINDING,
+    XPM_STATE_BIND_OK,
+    XPM_STATE_BIND_FAIL,
+    XPM_STATE_REGISTERING,
+    XPM_STATE_REGISTER_OK,
+    XPM_STATE_REGISTER_FAIL
+};
+
+static iref_t xpm_iref = 0;
+struct xeon_phi_manager_binding *xpm_binding = NULL;
+
+enum xpm_state conn_state = XPM_STATE_NSLOOKUP;
+
+/*
+ * --------------------------------------------------------------------------
+ * Registration Protocol
+ */
+
+struct xpm_register_data
+{
+    uint8_t id;
+    iref_t *cards;
+    uint8_t num;
+};
+
+static struct xpm_register_data reg_data;
+
+static void xpm_recv_register_response(struct xeon_phi_manager_binding *_binding,
+                                       uint8_t id,
+                                       uint8_t *cards,
+                                       size_t n,
+                                       xeon_phi_manager_errval_t msgerr)
+{
+    DEBUG_XPMC("Registration response: ID=0x%x, num=0x%lx, err=0x%lx\n", id, n/sizeof(iref_t), msgerr);
+
+    if (err_is_fail(msgerr)) {
+        conn_state = XPM_STATE_REGISTER_FAIL;
+        return;
+    }
+
+    if (n % sizeof(iref_t)) {
+        // the data seems to be corrupt
+        conn_state = XPM_STATE_REGISTER_FAIL;
+    }
+
+    reg_data.id = id;
+    reg_data.num = n / sizeof(iref_t);
+    reg_data.cards = (iref_t *) cards;
+
+    xpm_binding->st = &reg_data;
+
+    conn_state = XPM_STATE_REGISTER_OK;
+}
+
+static void xpm_send_register_request_cb(void *a)
+{
+
+}
+
+static void xpm_send_register_request(void *a)
+{
+    errval_t err;
+    iref_t *svc_iref = a;
+
+    conn_state = XPM_STATE_REGISTERING;
+
+    DEBUG_XPMC("Registering with Xeon Phi manager...\n");
+
+    struct event_closure txcont = MKCONT(xpm_send_register_request_cb, NULL);
+
+    err = xeon_phi_manager_register_call__tx(xpm_binding, txcont, *svc_iref);
+
+    if (err_is_fail(err)) {
+        if (err_no(err) == FLOUNDER_ERR_TX_BUSY) {
+            txcont = MKCONT(xpm_send_register_request, xpm_binding);
+            err = xpm_binding->register_send(xpm_binding,
+                                             get_default_waitset(),
+                                             txcont);
+            if (err_is_fail(err)) {
+                conn_state = XPM_STATE_REGISTER_FAIL;
+            }
+        }
+    }
+}
+
+struct xeon_phi_manager_rx_vtbl xpm_rx_vtbl = {
+    .register_response = xpm_recv_register_response
+};
+
+/*
+ * --------------------------------------------------------------------------
+ * Xeon Phi Manager Binding
+ */
+
+/**
+ * \brief
+ *
+ * \param
+ * \param
+ * \param
+ */
+static void xpm_bind_cb(void *st,
+                        errval_t err,
+                        struct xeon_phi_manager_binding *b)
+{
+
+    if (err_is_fail(err)) {
+        conn_state = XPM_STATE_BIND_FAIL;
+        return;
+    }
+
+    xpm_binding = b;
+
+    xpm_binding->rx_vtbl = xpm_rx_vtbl;
+
+    DEBUG_XPMC("Binding ok.\n");
+
+    conn_state = XPM_STATE_BIND_OK;
+}
+
+/**
+ * \brief
+ */
+static errval_t xpm_bind(void)
+{
+    errval_t err;
+
+    if (xpm_binding != NULL) {
+        return SYS_ERR_OK;
+    }
+
+    DEBUG_XPMC("Nameservice lookup: "XEON_PHI_MANAGER_SERVICE_NAME"\n");
+    err = nameservice_blocking_lookup(XEON_PHI_MANAGER_SERVICE_NAME, &xpm_iref);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    conn_state = XPM_STATE_BINDING;
+
+    DEBUG_XPMC("binding... \n");
+    err = xeon_phi_manager_bind(xpm_iref, xpm_bind_cb, NULL,
+                                get_default_waitset(), IDC_BIND_FLAGS_DEFAULT);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    return SYS_ERR_OK;
+}
+
+/*
+ * --------------------------------------------------------------------------
+ * Public Interface
+ */
+
+/**
+ * \brief   registers the Xeon Phi driver card with the Xeon Phi Manager
+ *          this function blocks until we have a connection to the manager
+ *
+ * \param   svc_iref    the iref of the drivers service
+ * \param   id          the own card id
+ * \param   num         returns the number of returned irefs / number of cards
+ * \param   cards       returns the array of irefs
+ *
+ * \return SYS_ERR_OK on success
+ */
+errval_t xeon_phi_manager_client_register(iref_t svc_iref,
+                                          uint8_t *id,
+                                          uint8_t *num,
+                                          iref_t **cards)
+{
+    DEBUG_XPMC("Registring with Xeon Phi Manager\n");
+    errval_t err;
+    err = xpm_bind();
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    while (conn_state == XPM_STATE_BINDING) {
+        messages_wait_and_handle_next();
+    }
+
+    if (conn_state == XPM_STATE_BIND_FAIL) {
+        return FLOUNDER_ERR_BIND;
+    }
+
+    xpm_send_register_request(&svc_iref);
+
+    while (conn_state == XPM_STATE_REGISTERING) {
+        messages_wait_and_handle_next();
+    }
+
+    if (conn_state == XPM_STATE_REGISTER_FAIL) {
+        // TODO ERROR CODE
+        DEBUG_XPMC("Registration failed.\n");
+        return -1;
+    }
+
+    assert(xpm_binding->st == &reg_data);
+
+    struct xpm_register_data *rd = xpm_binding->st;
+    *id = rd->id;
+    *num = rd->num;
+    *cards = rd->cards;
+
+    xpm_binding->st = NULL;
+
+    return SYS_ERR_OK;
+}
+
+/**
+ * \brief   deregisters the Xeon Phi driver with the Xeon Phi Manager
+ *
+ * \return SYS_ERR_OK on success
+ */
+errval_t xeon_phi_manager_client_deregister(void)
+{
+    return SYS_ERR_OK;
+}
index b55fe4b..6f4d5b5 100644 (file)
@@ -12,7 +12,7 @@
 
 [ build application { target = "xeon_phi",
                       cFiles = [ "main.c",
-                                        "xeon_phi.c", 
+                                 "xeon_phi.c", 
                                  "boot.c", 
                                  "serial.c", 
                                  "host_bootstrap.c", 
                                  "smpt.c", 
                                  "sleep.c" ],
                       addLibraries = libDeps ["skb", 
-                                                                 "pci", 
-                                                                 "spawndomain", 
-                                                                 "elf", 
-                                                                 "bench" ],
+                                              "pci", 
+                                              "spawndomain", 
+                                              "elf", 
+                                              "bench", 
+                                              "xeon_phi_manager_client" ],
                       flounderExtraDefs = [ ("monitor_blocking",["rpcclient"]) ],
-                      flounderDefs = ["monitor"],
+                      flounderDefs = ["monitor", "xeon_phi_manager", "xeon_phi"],
+                      flounderBindings = ["xeon_phi"],
                       architectures= ["x86_64"],
                       mackerelDevices = [ "xeon_phi/xeon_phi_apic", 
                                           "xeon_phi/xeon_phi_boot", 
index f23c2e3..6dec9c3 100644 (file)
 #include <stdio.h>
 #include <string.h>
 #include <barrelfish/barrelfish.h>
+#include <xeon_phi/xeon_phi_manager_client.h>
 
 #include "xeon_phi.h"
 #include "smpt.h"
-
+#include "service.h"
 
 volatile uint32_t bootstrap_done = 0;
 
@@ -39,6 +40,26 @@ int main(int argc,
         messages_wait_and_handle_next();
     }
 
+    err = service_init(&xphi);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "could not start the driver service\n");
+    }
+
+    uint8_t num;
+    iref_t *irefs;
+    err = xeon_phi_manager_client_register(xphi.iref, &xphi.id, &num, &irefs);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "could not register with the Xeon Phi manager\n");
+    }
+
+#if !0
+    err = service_register(&xphi, irefs, num);
+    if (err_is_fail(err)) {
+        DEBUG_ERR(err, "could not register with the other drivers");
+    }
+
+    service_start();
+#endif
     xphi.state = XEON_PHI_STATE_NULL;
 
     err = xeon_phi_init(&xphi);
@@ -46,13 +67,18 @@ int main(int argc,
         USER_PANIC_ERR(err, "could not do the card initialization\n");
     }
 
-    err = xeon_phi_boot(&xphi,
-                  XEON_PHI_BOOTLOADER,
-                  XEON_PHI_MULTIBOOT);
+    err = xeon_phi_boot(&xphi, XEON_PHI_BOOTLOADER, XEON_PHI_MULTIBOOT);
     if (err_is_fail(err)) {
-            DEBUG_ERR(err, "could not boot the card\n");
+        DEBUG_ERR(err, "could not boot the card\n");
     }
 
+    err = service_register(&xphi, irefs, num);
+    if (err_is_fail(err)) {
+        DEBUG_ERR(err, "could not register with the other drivers");
+    }
+
+    service_start();
+
     debug_printf("Xeon Phi host module terminated.\n");
 
     return 0;
index eec6807..cf69de4 100644 (file)
 #include <stdio.h>
 #include <string.h>
 #include <barrelfish/barrelfish.h>
+#include <xeon_phi/xeon_phi.h>
+
+#include <if/xeon_phi_defs.h>
 
 #include "xeon_phi.h"
+#include "service.h"
+
+static uint32_t is_exported;
+
+static iref_t svc_iref;
+
+/*
+ * ---------------------------------------------------------------------------
+ * Intra Xeon Phi Driver Communication Regigistration
+ */
+
+static void register_response_sent_cb(void *a)
+{
+
+}
+
+static void register_response_send(void *a)
+{
+    errval_t err;
+
+    struct xnode *topology = a;
+
+    struct event_closure txcont = MKCONT(register_response_sent_cb, a);
+
+    if (topology->state == XNODE_STATE_READY) {
+        err = SYS_ERR_OK;
+    } else {
+        err = -1;  // TODO> ERROR NUMBEr
+    }
+
+    err = xeon_phi_register_response__tx(topology->binding, txcont, err);
+    if (err_is_fail(err)) {
+        if (err_no(err) == FLOUNDER_ERR_TX_BUSY) {
+            struct waitset *ws = get_default_waitset();
+            txcont = MKCONT(register_response_send, a);
+            err = topology->binding->register_send(topology->binding, ws, txcont);
+            if (err_is_fail(err)) {
+                topology->state = XNODE_STATE_FAILURE;
+            }
+        }
+    }
+}
+
+/**
+ *
+ */
+static void register_call_recv(struct xeon_phi_binding *_binding,
+                               uint8_t id)
+{
+
+    assert(((struct xnode * )(_binding->st))->binding != _binding);
+    struct xeon_phi *phi = _binding->st;
+
+    assert(id < XEON_PHI_NUM_MAX);
+    phi->topology[id].binding = _binding;
+    phi->topology[id].state = XNODE_STATE_READY;
+
+    phi->connected++;
+
+    XSERVICE_DEBUG("[%u] New register call: id=0x%x, num_connected=%i\n",
+                   phi->id,
+                   id,
+                   phi->connected);
+
+    _binding->st = &phi->topology[id];
+
+    register_response_send(&phi->topology[id]);
+}
+
+/**
+ *
+ */
+static void register_response_recv(struct xeon_phi_binding *_binding,
+                                   xeon_phi_errval_t msgerr)
+{
+    assert(((struct xnode * )(_binding->st))->binding == _binding);
+
+    struct xnode *topology = _binding->st;
+
+    if (err_is_fail(msgerr)) {
+        topology->state = XNODE_STATE_FAILURE;
+    } else {
+        topology->local->connected++;
+        topology->state = XNODE_STATE_READY;
+    }
+
+    XSERVICE_DEBUG("[%u] New register response: 0x%lx, num_connected=%u\n",
+                   topology->local->id,
+                   msgerr,
+                   topology->local->connected);
+}
+
+static void register_call_sent_cb(void *a)F
+{
+
+}
+
+static void register_call_send(void *a)
+{
+    errval_t err;
+
+    struct xnode *topology = a;
+
+    struct event_closure txcont = MKCONT(register_call_sent_cb, a);
+
+    topology->state = XNODE_STATE_REGISTERING;
+
+    err = xeon_phi_register_call__tx(topology->binding, txcont, topology->local->id);
+    if (err_is_fail(err)) {
+        if (err_no(err) == FLOUNDER_ERR_TX_BUSY) {
+            struct waitset *ws = get_default_waitset();
+            txcont = MKCONT(register_call_send, a);
+            err = topology->binding->register_send(topology->binding, ws, txcont);
+            if (err_is_fail(err)) {
+                topology->state = XNODE_STATE_FAILURE;
+            }
+        }
+    }
+}
+
+/// Receive handler table
+static struct xeon_phi_rx_vtbl xps_rx_vtbl = {
+    .register_call = register_call_recv,
+    .register_response = register_response_recv
+};
+
+/*
+ * ---------------------------------------------------------------------------
+ * Service Setup
+ */
+static void svc_bind_cb(void *st,
+                        errval_t err,
+                        struct xeon_phi_binding *b)
+{
+    struct xnode *node = st;
+
+    XSERVICE_DEBUG("binding done.\n");
+    b->rx_vtbl = xps_rx_vtbl;
+    node->binding = b;
+    b->st = node;
+    node->state = XNODE_STATE_REGISTERING;
+}
+
+static errval_t svc_register(struct xnode *node)
+{
+    XSERVICE_DEBUG("binding to node %i (iref = 0x%x)\n", node->id, node->iref);
+    errval_t err;
+
+    err = xeon_phi_bind(node->iref,
+                        svc_bind_cb,
+                        node,
+                        get_default_waitset(),
+                        IDC_BIND_FLAGS_DEFAULT);
+    if (err_is_fail(err)) {
+        node->state = XNODE_STATE_FAILURE;
+        return err;
+    }
+
+    return SYS_ERR_OK;
+}
+
+static errval_t svc_connect_cb(void *st,
+                               struct xeon_phi_binding *b)
+{
+    struct xeon_phi *phi = st;
+
+    XSERVICE_DEBUG("[%u] New connection\n", phi->id);
+
+    b->st = st;
+    b->rx_vtbl = xps_rx_vtbl;
+    return SYS_ERR_OK;
+}
+
+static void svc_export_cb(void *st,
+                          errval_t err,
+                          iref_t iref)
+{
+    if (err_is_fail(err)) {
+        svc_iref = 0x0;
+        return;
+    }
+
+    svc_iref = iref;
+
+    struct xeon_phi *phi = st;
+    phi->iref = iref;
+
+    is_exported = 0x1;
+}
+
+/**
+ * \brief initializes the service
+ *
+ * \param iref  returns the iref of the initialized service
+ *
+ * \return SYS_ERR_OK on success
+ */
+errval_t service_init(struct xeon_phi *phi)
+{
+    errval_t err;
+
+    for (uint32_t i = 0; i < XEON_PHI_NUM_MAX; ++i) {
+        phi->topology[i].local = phi;
+    }
+
+    err = xeon_phi_export(phi,
+                          svc_export_cb,
+                          svc_connect_cb,
+                          get_default_waitset(),
+                          IDC_EXPORT_FLAGS_DEFAULT);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    while (!is_exported) {
+        messages_wait_and_handle_next();
+    }
+
+    if (svc_iref == 0x0) {
+        return -1;
+    }
+
+    return SYS_ERR_OK;
+
+}
+
+/**
+ * \brief registers the local service with the other Xeon Phi drivers
+ *        in the topology
+ *
+ * \param phi   pointer to the local card structure
+ * \param irefs the irefs of the other cards
+ * \param num   the number of irefs in the array
+ */
+errval_t service_register(struct xeon_phi *phi,
+                          iref_t *irefs,
+                          size_t num)
+{
+    struct xnode *xnode;
+    XSERVICE_DEBUG("start binding to nodes\n");
+    for (uint32_t i = 0; i < num; ++i) {
+        xnode = &phi->topology[i];
+        if (i == phi->id) {
+            xnode->iref = phi->iref;
+            xnode->id = i;
+            xnode->state = XNODE_STATE_READY;
+            continue;
+        }
+
+        xnode->iref = irefs[i];
+        xnode->id = i;
+        xnode->state = XNODE_STATE_NONE;
+        svc_register(xnode);
+        while (xnode->state == XNODE_STATE_NONE) {
+            messages_wait_and_handle_next();
+        }
+    }
+
+    XSERVICE_DEBUG("Start registring\n");
+
+    for (uint32_t i = 0; i < num; ++i) {
+        if (i == phi->id) {
+            continue;
+        }
+        xnode = &phi->topology[i];
+        register_call_send(xnode);
+        while (xnode->state == XNODE_STATE_READY) {
+            messages_wait_and_handle_next();
+        }
+    }
+
+    return SYS_ERR_OK;
+}
+
+/**
+ * \brief starts the service request handling
+ */
+errval_t service_start(void)
+{
+    messages_handler_loop();
+
+    return SYS_ERR_OK;
+}
 
diff --git a/usr/drivers/xeon_phi/service.h b/usr/drivers/xeon_phi/service.h
new file mode 100644 (file)
index 0000000..f11c388
--- /dev/null
@@ -0,0 +1,43 @@
+/**
+ * \file
+ * \brief Driver for booting the Xeon Phi Coprocessor card on a Barrelfish Host
+ */
+
+/*
+ * Copyright (c) 2014 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef XEON_PHI_SERVICE_H_
+#define XEON_PHI_SERVICE_H_
+
+/**
+ * \brief initializes the service
+ *
+ * \param iref  returns the iref of the initialized service
+ *
+ * \return SYS_ERR_OK on success
+ */
+errval_t service_init(struct xeon_phi *phi);
+
+
+/**
+ * \brief registers the local service with the other Xeon Phi drivers
+ *        in the topology
+ *
+ * \param phi   pointer to the local card structure
+ * \param irefs the irefs of the other cards
+ * \param num   the number of irefs in the array
+ */
+errval_t service_register(struct xeon_phi *phi, iref_t *irefs, size_t num);
+
+/**
+ * \brief starts the service request handling
+ */
+errval_t service_start(void);
+
+#endif // XEON_PHI_SERVICE_H_
index 982d2ca..bc6666c 100644 (file)
@@ -28,7 +28,6 @@ static uint32_t initialized = 0;
 
 #define XEON_PHI_RESET_TIME 300
 
-
 static struct xeon_phi *card;
 
 static uint32_t pci_bus = PCI_DONT_CARE;
@@ -67,40 +66,34 @@ static uint32_t pci_function = PCI_DONT_CARE;
 #define PCI_DEVICE_KNC_225d 0x225d
 #define PCI_DEVICE_KNC_225e 0x225e
 
-
-
 #define XEON_PHI_APT_BAR 0
 #define XEON_PHI_MMIO_BAR 4
 
-
 static void device_init(struct xeon_phi *phi)
 {
 
-
 #if 0
     scratch13 = SBOX_READ(mic_ctx->mmio.va, SBOX_SCRATCH13);
-        mic_ctx->bi_stepping = SCRATCH13_STEP_ID(scratch13);
-        mic_ctx->bi_substepping = SCRATCH13_SUB_STEP(scratch13);
-    #ifdef MIC_IS_EMULATION
-        mic_ctx->bi_platform = PLATFORM_EMULATOR;
-    #else
-        mic_ctx->bi_platform = SCRATCH13_PLATFORM_ID(scratch13);
-    #endif
-        mic_enable_msi_interrupts(mic_ctx);
-        mic_enable_interrupts(mic_ctx);
-
-        mic_reg_irqhandler(mic_ctx, 1, "MIC SHUTDOWN DoorBell 1",
-                    mic_shutdown_host_doorbell_intr_handler);
+    mic_ctx->bi_stepping = SCRATCH13_STEP_ID(scratch13);
+    mic_ctx->bi_substepping = SCRATCH13_SUB_STEP(scratch13);
+#ifdef MIC_IS_EMULATION
+    mic_ctx->bi_platform = PLATFORM_EMULATOR;
+#else
+    mic_ctx->bi_platform = SCRATCH13_PLATFORM_ID(scratch13);
+#endif
+    mic_enable_msi_interrupts(mic_ctx);
+    mic_enable_interrupts(mic_ctx);
 
+    mic_reg_irqhandler(mic_ctx, 1, "MIC SHUTDOWN DoorBell 1",
+                    mic_shutdown_host_doorbell_intr_handler);
 
 #endif
 
-    initialized=true;
+    initialized = true;
 }
 
-static void
-pci_init_card(struct device_mem* bar_info,
-              int bar_count)
+static void pci_init_card(struct device_mem* bar_info,
+                          int bar_count)
 {
     errval_t err;
 
@@ -124,12 +117,12 @@ pci_init_card(struct device_mem* bar_info,
         USER_PANIC_ERR(err, "Failed to map MMIO range");
     }
 
-    card->apt.vbase = (lvaddr_t)bar_info[XEON_PHI_APT_BAR].vaddr;
+    card->apt.vbase = (lvaddr_t) bar_info[XEON_PHI_APT_BAR].vaddr;
     card->apt.length = bar_info[XEON_PHI_APT_BAR].bytes;
-    card->apt.pbase = (lpaddr_t)bar_info[XEON_PHI_APT_BAR].paddr;
-    card->mmio.vbase = (lvaddr_t)bar_info[XEON_PHI_MMIO_BAR].vaddr;
+    card->apt.pbase = (lpaddr_t) bar_info[XEON_PHI_APT_BAR].paddr;
+    card->mmio.vbase = (lvaddr_t) bar_info[XEON_PHI_MMIO_BAR].vaddr;
     card->mmio.length = bar_info[XEON_PHI_MMIO_BAR].bytes;
-    card->mmio.pbase = (lpaddr_t)bar_info[XEON_PHI_MMIO_BAR].paddr;
+    card->mmio.pbase = (lpaddr_t) bar_info[XEON_PHI_MMIO_BAR].paddr;
 
     card->state = XEON_PHI_STATE_PCI_OK;
 }
@@ -143,12 +136,17 @@ static void pci_register(struct xeon_phi *phi)
         USER_PANIC_ERR(err, "Could not connect to PCI\n");
     }
 
-    err = pci_register_driver_irq(pci_init_card, PCI_DONT_CARE,
+    err = pci_register_driver_irq(pci_init_card,
+                                  PCI_DONT_CARE,
                                   PCI_DONT_CARE,
                                   PCI_DONT_CARE,
                                   PCI_VENDOR_ID_INTEL,
-                                  PCI_DEVICE_KNC_225e, pci_bus, pci_device,
-                                  pci_function, interrupt_handler, phi);
+                                  PCI_DEVICE_KNC_225e,
+                                  pci_bus,
+                                  pci_device,
+                                  pci_function,
+                                  interrupt_handler,
+                                  phi);
 
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "Could not register the PCI device");
@@ -211,16 +209,16 @@ errval_t xeon_phi_reset(struct xeon_phi *phi)
     xeon_phi_boot_postcodes_t pc;
     for (uint32_t time = 0; time < XEON_PHI_RESET_TIME; ++time) {
         postcode = xeon_phi_boot_postcode_rd(&boot_registers);
-        pc = xeon_phi_boot_postcode_extract(postcode);
+        pc = xeon_phi_boot_postcode_code_extract(postcode);
         debug_printf("Resetting; %s\n", xeon_phi_boot_postcodes_describe(pc));
         XBOOT_DEBUG("Resetting (Post Code %c%c)\n",
-                     xeon_phi_boot_postcode_raw_code0_extract(postcode),
-                     xeon_phi_boot_postcode_raw_code1_extract(postcode));
+                    xeon_phi_boot_postcode_raw_code0_extract(postcode),
+                    xeon_phi_boot_postcode_raw_code1_extract(postcode));
 
-        if (postcode == xeon_phi_boot_postcode_invalid
-                || postcode == xeon_phi_boot_postcode_fatal
-                || pc == xeon_phi_boot_postcode_memtf
-                || pc == xeon_phi_boot_postcode_mempf) {
+        if (postcode == xeon_phi_boot_postcode_invalid || postcode
+                        == xeon_phi_boot_postcode_fatal
+            || pc == xeon_phi_boot_postcode_memtf
+            || pc == xeon_phi_boot_postcode_mempf) {
             break;
         }
 
@@ -230,10 +228,10 @@ errval_t xeon_phi_reset(struct xeon_phi *phi)
             /*
              * XXX; Maybe we should re-enable the IRQ if they were enabled beforehand
              * if (mic_ctx->msie)
-                    mic_enable_msi_interrupts(mic_ctx);
-                mic_enable_interrupts(mic_ctx);
-                mic_smpt_restore(mic_ctx);
-                micscif_start(mic_ctx);
+             mic_enable_msi_interrupts(mic_ctx);
+             mic_enable_interrupts(mic_ctx);
+             mic_smpt_restore(mic_ctx);
+             micscif_start(mic_ctx);
              */
             return SYS_ERR_OK;
         }
@@ -244,8 +242,8 @@ errval_t xeon_phi_reset(struct xeon_phi *phi)
     if (phi->state != XEON_PHI_STATE_READY) {
         debug_printf("Reset Failed; %s\n", xeon_phi_boot_postcodes_describe(pc));
         XBOOT_DEBUG("Reset Failed (Post Code %c%c)\n",
-                             xeon_phi_boot_postcode_raw_code0_extract(postcode),
-                             xeon_phi_boot_postcode_raw_code1_extract(postcode));
+                    xeon_phi_boot_postcode_raw_code0_extract(postcode),
+                    xeon_phi_boot_postcode_raw_code1_extract(postcode));
 
         return 1;
     }
@@ -253,4 +251,3 @@ errval_t xeon_phi_reset(struct xeon_phi *phi)
     return SYS_ERR_OK;
 }
 
-
index 35f7eda..05cbdcb 100644 (file)
@@ -10,6 +10,8 @@
 #ifndef XEON_PHI_H_
 #define XEON_PHI_H_
 
+#include <xeon_phi/xeon_phi.h>
+
 /*
  * Common setting values
  */
@@ -36,8 +38,6 @@
 #define XDEBUG_SMPT     1
 #define XDEBUG_SERVICE  1
 
-
-
 /*
  * This defines are used to reference the MMIO registers on the host side.
  *
@@ -53,7 +53,6 @@
 #define XEON_PHI_MMIO_TO_DBOX(phi) \
     ((mackerel_addr_t)((lvaddr_t)(phi->mmio.vbase)+HOST_DBOX_OFFSET))
 
-
 /*
  * --------------------------------------------------------------------------
  * Debug output generation
 #define XSERVICE_DEBUG(x...)
 #endif
 
-
 /*
  * --------------------------------------------------------------------------
  * Xeon Phi Management structure
  */
 
 /// represents the state of the Xeon Phi
-typedef enum xeon_phi_state {
+typedef enum xeon_phi_state
+{
     XEON_PHI_STATE_NULL,    ///< The card has not yet been initialized
     XEON_PHI_STATE_PCI_OK,  ///< The card has been registered with PCI
     XEON_PHI_STATE_RESET,   ///< The card has been reset
     XEON_PHI_STATE_READY,   ///< The card is ready to load the os
-    XEON_PHI_STATE_BOOTING, ///< The card is in the booting state
+    XEON_PHI_STATE_BOOTING,  ///< The card is in the booting state
     XEON_PHI_STATE_ONLINE   ///< the card has booted and is online
 } xeon_phi_state_t;
 
+typedef enum xnode_state {
+    XNODE_STATE_NONE,
+    XNODE_STATE_REGISTERING,
+    XNODE_STATE_READY,
+    XNODE_STATE_FAILURE
+} xnode_state_t;
 
 /// represents the memory ranges occupied by the Xeon Phi card
-struct mbar {
+struct mbar
+{
     lvaddr_t vbase;
     lpaddr_t pbase;
-    size_t   length;
+    size_t length;
     /*
      * XXX: may it be useful to store the cap here aswell ?
      */
 };
 
+struct xnode
+{
+    struct xeon_phi_binding *binding;
+    iref_t                   iref;
+    xnode_state_t state;
+    uint8_t         id;
+    struct xeon_phi *local;
+};
+
 struct xeon_phi
 {
     xeon_phi_state_t state;
@@ -123,15 +138,17 @@ struct xeon_phi
     struct mbar apt;        ///< pointer to the aperture address range
 
     uint8_t id;             ///< card id for identifying the card
-
-
+    iref_t iref;
     uint32_t apicid;        ///< APIC id used for sending the boot interrupt
 
+    uint8_t      connected;
+    struct xnode topology[XEON_PHI_NUM_MAX];
+
     char *cmdline;          ///< pointer to the bootloader cmdline
 
-    struct smpt_info  *smpt; ///< pointer to the SMPT information struct
-    struct irq_info   *irq;  ///< pointer to the IRQ information struct
-    struct dma_infi   *dma;  ///< pointer to the DMA information struct
+    struct smpt_info *smpt;  ///< pointer to the SMPT information struct
+    struct irq_info *irq;  ///< pointer to the IRQ information struct
+    struct dma_infi *dma;  ///< pointer to the DMA information struct
 };
 
 /**
@@ -172,6 +189,4 @@ errval_t xeon_phi_init(struct xeon_phi *phi);
  */
 errval_t host_bootstrap(void);
 
-
-
 #endif /* XEON_PHI_H_ */
diff --git a/usr/xeon_phi_manager/Hakefile b/usr/xeon_phi_manager/Hakefile
new file mode 100644 (file)
index 0000000..d474536
--- /dev/null
@@ -0,0 +1,23 @@
+--------------------------------------------------------------------------
+-- Copyright (c) 2007-2009, ETH Zurich.
+-- All rights reserved.
+--
+-- This file is distributed under the terms in the attached LICENSE file.
+-- If you do not find this file, copies can be found by writing to:
+-- ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+--
+-- Hakefile for /usr/xeon_phi_manager
+--
+--------------------------------------------------------------------------
+
+[ build application { target = "xeon_phi_manager",
+                        cFiles = [ "main.c", 
+                                   "service.c",
+                                   "cardmanager.c" ],
+                   flounderDefs = ["xeon_phi_manager"],
+                   flounderBindings = ["xeon_phi_manager"],
+                   architectures = ["x86_64"]
+                   
+                    }
+]
+
diff --git a/usr/xeon_phi_manager/cardmanager.c b/usr/xeon_phi_manager/cardmanager.c
new file mode 100644 (file)
index 0000000..2489983
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2014 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+#include <stdio.h>
+
+#include <barrelfish/barrelfish.h>
+#include <xeon_phi/xeon_phi.h>
+
+#include <if/xeon_phi_manager_defs.h>
+
+#include "cardmanager.h"
+
+struct xeon_phi_card {
+    struct xeon_phi_manager_binding *binding;
+    iref_t driver_iref;
+};
+
+
+static uint8_t num_cards = 0;
+
+static iref_t  driver_irefs[XEON_PHI_NUM_MAX];
+
+static struct xeon_phi_card xeon_phis[XEON_PHI_NUM_MAX];
+
+/**
+ * \brief   Inserts the information about the new Xeon Phi into the
+ *          card manager
+ *
+ * \param   binding the flounder binding for this card
+ * \param   driver  the iref to the driver
+ * \param   id      returns the id of the newly inserted card
+ */
+errval_t cm_new_xeon_phi(struct xeon_phi_manager_binding *binding,
+                         iref_t driver,
+                         uint8_t *id)
+{
+    if (num_cards == XEON_PHI_NUM_MAX) {
+        // TODO: ERROR CODE
+        return -1;
+    }
+
+    struct xeon_phi_card *card = xeon_phis+num_cards;
+
+    card->driver_iref = driver;
+    card->binding = binding;
+    binding->st = card;
+
+    driver_irefs[num_cards] = driver;
+
+    if (id) {
+        *id = num_cards;
+    }
+
+    ++num_cards;
+
+    return SYS_ERR_OK;
+}
+
+
+/**
+ * \brief  returns an array of irefs with the assciated xeon phi drivers
+ *
+ * \param  iref the iref array
+ * \param  num  the number of irefs in the iref array
+ *
+ * \return SYS_ERR_OK
+ */
+errval_t cm_get_irefs(iref_t **iref, uint8_t *num)
+{
+    if (iref) {
+        *iref = driver_irefs;
+    }
+    if (num) {
+        *num = num_cards;
+    }
+    return SYS_ERR_OK;
+}
+
+
+
diff --git a/usr/xeon_phi_manager/cardmanager.h b/usr/xeon_phi_manager/cardmanager.h
new file mode 100644 (file)
index 0000000..b70d985
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef XEON_PHI_MANAGER_CARDS_H_
+#define XEON_PHI_MANAGER_CARDS_H_
+
+
+/**
+ * \brief   Inserts the information about the new Xeon Phi into the
+ *          card manager
+ *
+ * \param   binding the flounder binding for this card
+ * \param   driver  the iref to the driver
+ * \param   id      returns the id of the newly inserted card
+ */
+errval_t cm_new_xeon_phi(struct xeon_phi_manager_binding *binding,
+                         iref_t driver,
+                         uint8_t *id);
+
+
+/**
+ * \brief  returns an array of irefs with the assciated xeon phi drivers
+ *
+ * \param  iref the iref array
+ * \param  num  the number of irefs in the iref array
+ *
+ * \return SYS_ERR_OK
+ */
+errval_t cm_get_irefs(iref_t **iref, uint8_t *num);
+
+#endif /* SERVICE_H_ */
diff --git a/usr/xeon_phi_manager/main.c b/usr/xeon_phi_manager/main.c
new file mode 100644 (file)
index 0000000..9fd68d4
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2007-12 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ */
+#include <barrelfish/barrelfish.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "service.h"
+
+int main(int argc, char **argv)
+{
+    errval_t err;
+
+    debug_printf("Xeon Phi Manager started.\n");
+
+    err = service_start();
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "could not start the service\n");
+    }
+}
+
+
diff --git a/usr/xeon_phi_manager/service.c b/usr/xeon_phi_manager/service.c
new file mode 100644 (file)
index 0000000..707e38a
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2014 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+#include <stdio.h>
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/nameservice_client.h>
+#include <xeon_phi/xeon_phi_manager_client.h>
+
+#include <if/xeon_phi_manager_defs.h>
+
+#include "service.h"
+#include "cardmanager.h"
+
+enum xpm_svc_state
+{
+    XPM_SVC_STATE_EXPORTING,
+    XPM_SVC_STATE_EXPORT_OK,
+    XPM_SVC_STATE_EXPORT_FAIL,
+    XPM_SVC_STATE_NS_REGISTERING,
+    XPM_SVC_STATE_NS_REGISTER_OK,
+    XPM_SVC_STATE_NS_REGISTER_FAIL,
+    XPM_SVC_STATE_RUNNING
+};
+
+static enum xpm_svc_state svc_state = XPM_SVC_STATE_EXPORTING;
+
+static iref_t manager_iref;
+
+/**
+ * --------------------------------------------------------------------------
+ * Registration protocol
+ */
+
+struct reg_data
+{
+    errval_t err;
+    uint8_t id;
+    iref_t *cards;
+    uint8_t num;
+    struct xeon_phi_manager_binding *b;
+};
+
+struct reg_data reg_data_fail = {
+    // TODO: ERROR CODE
+    .err = -1
+};
+
+static void register_response_sent_cb(void *a)
+{
+    if (a != &reg_data_fail) {
+        free(a);
+    }
+}
+
+static void register_response_send(void *a)
+{
+    errval_t err;
+
+    struct reg_data *rd = a;
+
+    DEBUG_SVC("Registration response: id=%x, num=%x\n", rd->id, rd->num);
+
+    struct event_closure txcont = MKCONT(register_response_sent_cb, a);
+    size_t n = rd->num * sizeof(iref_t);
+    uint8_t *irefs = (uint8_t *) rd->cards;
+    err = xeon_phi_manager_register_response__tx(rd->b,
+                                                 txcont,
+                                                 rd->id,
+                                                 irefs,
+                                                 n,
+                                                 rd->err);
+    if (err_is_fail(err)) {
+        if (err_no(err) == FLOUNDER_ERR_TX_BUSY) {
+            txcont = MKCONT(register_response_send, a);
+        }
+        struct waitset *ws = get_default_waitset();
+        err = rd->b->register_send(rd->b, ws, txcont);
+        if (err_is_fail(err)) {
+            DEBUG_ERR(err, "register_send on binding failed!");
+            register_response_sent_cb(a);
+        }
+    }
+}
+
+static void register_call_recv(struct xeon_phi_manager_binding *_binding,
+                               iref_t svc)
+{
+    DEBUG_SVC("New registration: iref=%x\n", svc);
+
+    struct reg_data *reply = malloc(sizeof(struct reg_data));
+    if (!reply) {
+        register_response_send(&reg_data_fail);
+    }
+    reply->b = _binding;
+    reply->err = cm_new_xeon_phi(_binding, svc, &reply->id);
+    if (err_is_fail(reply->err)) {
+        register_response_send(reply);
+    }
+
+    reply->err = cm_get_irefs(&reply->cards, &reply->num);
+    if (err_is_fail(reply->err)) {
+        register_response_send(reply);
+    }
+
+    register_response_send(reply);
+}
+
+static struct xeon_phi_manager_rx_vtbl xpm_rx_vtbl = {
+    .register_call = register_call_recv
+};
+
+/*
+ * --------------------------------------------------------------------------
+ * Export and Connect functions
+ */
+
+static errval_t svc_connect_cb(void *st,
+                               struct xeon_phi_manager_binding *b)
+{
+    DEBUG_SVC("connect request\n");
+    b->rx_vtbl = xpm_rx_vtbl;
+
+    return SYS_ERR_OK;
+}
+
+/**
+ * \brief
+ */
+static void svc_export_cb(void *st,
+                          errval_t err,
+                          iref_t iref)
+{
+    DEBUG_SVC("exported\n");
+    if (err_is_fail(err)) {
+        svc_state = XPM_SVC_STATE_EXPORT_FAIL;
+        return;
+    }
+
+    manager_iref = iref;
+
+    svc_state = XPM_SVC_STATE_NS_REGISTERING;
+
+    err = nameservice_register(XEON_PHI_MANAGER_SERVICE_NAME, iref);
+    if (err_is_fail(err)) {
+        svc_state = XPM_SVC_STATE_NS_REGISTER_FAIL;
+    }
+    DEBUG_SVC("ns registered\n");
+    svc_state = XPM_SVC_STATE_NS_REGISTER_OK;
+}
+
+/**
+ * \brief   starts Xeon Phi manager service
+ *
+ * \return  SYS_ERR_OK on succes
+ */
+errval_t service_start(void)
+{
+    DEBUG_SVC("starting service...\n");
+    errval_t err;
+
+    struct waitset *ws = get_default_waitset();
+
+    err = xeon_phi_manager_export(NULL,
+                                  svc_export_cb,
+                                  svc_connect_cb,
+                                  ws,
+                                  IDC_EXPORT_FLAGS_DEFAULT);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    while (svc_state == XPM_SVC_STATE_EXPORTING) {
+        messages_wait_and_handle_next();
+    }
+
+    if (svc_state == XPM_SVC_STATE_EXPORT_FAIL) {
+        return FLOUNDER_ERR_BIND;
+    } else if (svc_state == XPM_SVC_STATE_NS_REGISTER_FAIL) {
+        return LIB_ERR_NAMESERVICE_CLIENT_INIT;
+    }
+
+    DEBUG_SVC("Service up and running.\n");
+
+    svc_state = XPM_SVC_STATE_RUNNING;
+    messages_handler_loop();
+
+    DEBUG_SVC("Message handler terminated.\n");
+    return -1;
+}
diff --git a/usr/xeon_phi_manager/service.h b/usr/xeon_phi_manager/service.h
new file mode 100644 (file)
index 0000000..97139dc
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2014 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef XEON_PHI_MANAGER_SERVICE_H_
+#define XEON_PHI_MANAGER_SERVICE_H_
+
+
+#define DEBUG_SVC(x...) debug_printf("SVC | " x);
+//#define DEBUG_SVC(x...)
+
+/**
+ * \brief   starts Xeon Phi manager service
+ *
+ * \return  SYS_ERR_OK on succes
+ */
+errval_t service_start(void);
+
+
+
+
+#endif /* SERVICE_H_ */