Merge branch 'master' of ssh://code.systems.ethz.ch:8006/diffusion/BFI/barrelfish
authorAdam Turowski <adam.turowski@inf.ethz.ch>
Tue, 26 Jul 2016 11:58:57 +0000 (13:58 +0200)
committerAdam Turowski <adam.turowski@inf.ethz.ch>
Tue, 26 Jul 2016 11:58:57 +0000 (13:58 +0200)
Signed-off-by: Adam Turowski <adam.turowski@inf.ethz.ch>

94 files changed:
devices/ahci_port.dev
errors/errno.fugu
hake/ARMv7.hs
hake/menu.lst.armv7_a15ve
hake/menu.lst.armv7_a9ve
hake/menu.lst.armv7_pandaboard
hake/menu.lst.armv7_zynq7
if/acpi.if
include/acpi_client/acpi_client.h
include/arch/aarch64/hw_records_arch.h [new file with mode: 0644]
include/arch/x86/hw_records_arch.h [new file with mode: 0644]
include/arch/x86_32/hw_records_arch.h [new file with mode: 0644]
include/arch/x86_64/hw_records_arch.h [new file with mode: 0644]
include/barrelfish_kpi/dispatcher_shared.h
include/blk/ahci.h [new file with mode: 0644]
include/device_interfaces/device_queue_interface.h [deleted file]
include/devif/queue.h [new file with mode: 0644]
include/hw_records.h [new file with mode: 0644]
include/omap44xx_map.h
include/pci/pci_client_debug.h
kernel/arch/armv7/plat_omap44xx.c
kernel/arch/armv8/paging.c
kernel/arch/armv8/startup_arch.c
kernel/arch/x86_32/startup_arch.c
kernel/capabilities.c
lib/acpi_client/acpi_client.c
lib/ahci/ahci_util.c
lib/barrelfish/arch/arm/pmap_arch.c
lib/barrelfish/arch/arm/sys_debug.c
lib/barrelfish/debug.c
lib/barrelfish/waitset.c
lib/blk/Hakefile [new file with mode: 0644]
lib/blk/blk.c [new file with mode: 0644]
lib/blk/blk_ahci/ahci_dev.c [new file with mode: 0644]
lib/blk/blk_ahci/ahci_dev.h [new file with mode: 0644]
lib/blk/blk_ahci/ahci_init.c [new file with mode: 0644]
lib/blk/blk_ahci/ahci_port.c [new file with mode: 0644]
lib/blk/blk_ahci/blk_ahci.h [new file with mode: 0644]
lib/blk/blk_ahci/device_impl.c [new file with mode: 0644]
lib/blk/blk_ahci/sata_fis.c [new file with mode: 0644]
lib/blk/blk_ahci/sata_fis.h [new file with mode: 0644]
lib/blk/blk_debug.h [new file with mode: 0644]
lib/blk/dma_mem/dma_mem.c [new file with mode: 0644]
lib/blk/dma_mem/dma_mem.h [new file with mode: 0644]
lib/crt/arch/arm/crt0.S
lib/mm/mm.c
lib/pci/pci_client.c
platforms/Hakefile
tools/harness/barrelfish.py
tools/harness/harness.py
tools/harness/machines/eth_machinedata.py
tools/harness/reprocess.py
tools/harness/results.py
tools/harness/tests/blk_tests.py [new file with mode: 0644]
tools/usbboot/arch/omap4/clock.c
usr/acpi/Hakefile
usr/acpi/acpi.c
usr/acpi/acpi_service.c
usr/acpi/acpi_shared.h
usr/acpi/acpica_osglue.c
usr/acpi/arch/armv8/acpi_interrupts_arch.c [new file with mode: 0644]
usr/acpi/arch/armv8/acpi_main.c
usr/acpi/arch/x86/acpi_interrupts_arch.c [new file with mode: 0644]
usr/acpi/arch/x86/acpi_main.c
usr/acpi/interrupts.c
usr/acpi/ioapic.h
usr/ahcid/Hakefile [deleted file]
usr/ahcid/ahcid.c [deleted file]
usr/ahcid/ahcid.h [deleted file]
usr/ahcid/ahcid_debug.h [deleted file]
usr/ahcid/ahcid_hwinit.c [deleted file]
usr/drivers/ahcid/Hakefile [new file with mode: 0644]
usr/drivers/ahcid/ahcid.c [new file with mode: 0644]
usr/drivers/ahcid/ahcid.h [new file with mode: 0644]
usr/drivers/ahcid/test.c [new file with mode: 0644]
usr/drivers/ahcid/test.h [new file with mode: 0644]
usr/drivers/cpuboot/Hakefile
usr/drivers/cpuboot/coreboot.h
usr/drivers/cpuboot/main.c
usr/drivers/cpuboot/x86boot.c
usr/eclipseclp/Kernel/src/elipsys_fd.c
usr/eclipseclp/README_BARRELFISH [new file with mode: 0644]
usr/eclipseclp/icparc_solvers/ic.c
usr/fish/fish_x86.c
usr/init/spawn.c
usr/kaluga/boot_modules.c
usr/kaluga/boot_modules.h
usr/kaluga/start_cpu.c
usr/pci/pci.c
usr/pci/pci_service.c
usr/pci/pcie.c
usr/pci/pcimain.c
usr/skb/Hakefile
usr/skb/skb_simple/Hakefile

index 23715e8..8b0afa6 100644 (file)
  * ahci_port.dev
  *
  * DESCRIPTION: AHCI (SATA) Host bus adaptor, per-port registers
- * 
+ *
  * Section numbers refer to the Serial ATA Advanced Host Controller
  *   Interface (AHCI) specification 1.3, June 2008
  */
 
 device ahci_port msbfirst (addr b) "AHCI port" {
 
-    // 3.3.1-2 
+    // 3.3.1-2
     // Low 10 bits mbz
     register clb rw addr(b,0x00) "Command list base address" type(uint64);
-    
+
     // 3.3.3-4
     // Low 10 bits mbz
     register fb rw addr(b,0x08) "FIS base address" type(uint64);
-    
+
     // 3.3.5
     register is addr(b,0x10) "Interrupt status" {
        cpds    1 rw1c "Cold port detect";
@@ -47,7 +47,7 @@ device ahci_port msbfirst (addr b) "AHCI port" {
        pss     1 rw1c "PIO setup FIS interrupt";
        dhrs    1 rw1c "Device to host register FIS interrupt";
     };
-    
+
     // 3.3.6
     register ie addr(b,0x14) "Interrupt enable" {
        cpde    1 rw "Cold port detect";
@@ -70,8 +70,8 @@ device ahci_port msbfirst (addr b) "AHCI port" {
        pse     1 rw "PIO setup FIS interrupt";
        dhre    1 rw "Device to host register FIS interrupt";
     };
-    
-    // 3.3.7 
+
+    // 3.3.7
     constants icct "Interface communication control" {
        slumber = 0x6 "Slumber";
        partial = 0x2 "Partial";
@@ -104,13 +104,17 @@ device ahci_port msbfirst (addr b) "AHCI port" {
        st      1 rw "Start";
     };
 
-    // 3.3.8 
+    // 3.3.8
     register tfd ro addr(b,0x20) "Task file data" {
        _       16 rsvd;
        err     8 "Error";
-       sts     8 "Status (task file status)";
+    bsy 1 ro    "Indicates the interface is busy";
+    cs2 3 ro    "Command specific";
+    drq 1 ro    "Indicates a data transfer is requested";
+    cs1 2 ro    "Command specific";
+    serr 1 ro    "Indicates an error during the transfer.";
     };
-    
+
     // 3.3.9
     register sig ro addr(b,0x24) "Signature" {
        lbah    8 "LBA high";
@@ -118,7 +122,7 @@ device ahci_port msbfirst (addr b) "AHCI port" {
        lbal    8 "LBA low";
        sectors 8 "Sector count";
     };
-    
+
     // 3.3.10
     constants speed "Interface speed" {
        gen1    = 0b0001 "Gen 1 (1.5 Gbps)";
@@ -137,7 +141,7 @@ device ahci_port msbfirst (addr b) "AHCI port" {
        spd     4 type(speed) "Current interface speed";
        det     4 type(dets) "Device detection";
     };
-    
+
     // 3.3.11
     constants ipmall "Interface transitions" {
        noipm   = 0x0 "No interface restrictions";
@@ -183,13 +187,13 @@ device ahci_port msbfirst (addr b) "AHCI port" {
 
     // 3.3.14
     register ci rw addr(b,0x38) "Command issue" type(uint32);
-    
-    // 3.3.15 
+
+    // 3.3.15
     register sntf addr(b,0x3c) "Serial ATA notification" {
        _       16 mbz;
        pmn     16 rw1c "PMN notify";
     };
-    
+
     // 3.3.16
     register fbs addr(b,0x40) "FIS-based switching control" {
        _       12 mbz;
@@ -214,12 +218,11 @@ device ahci_port msbfirst (addr b) "AHCI port" {
        w       1 "Write";
        a       1 "ATAPI";
        cfl     5 "Command FIS length";
-       
+
        prdbc   32 "Physical region descriptor byte count";
-       
-       ctba    32 "Command table descriptor base address";
-       
-       ctbau   32 "Command table descriptor base address upper";
+
+       ctba    64 "Command table descriptor base address";
+
        _       32;
        _       32;
        _       32;
@@ -235,7 +238,7 @@ device ahci_port msbfirst (addr b) "AHCI port" {
        _       9;
        dbc     22 "Data byte count";
     };
-    
+
     // 12.2
     constants emtype "Enclosure message type" {
        led     = 0x0 "LED";
@@ -250,7 +253,7 @@ device ahci_port msbfirst (addr b) "AHCI port" {
        msize   8 "Message size";
        _       8;
     };
-    
+
     // 12.2.1
     constants emledstate "Enclosure LED state" {
        off     = 0b000 "LED shall be off";
index f731e04..ae3d347 100755 (executable)
@@ -132,7 +132,7 @@ errors kernel SYS_ERR_ {
     failure VMKIT_CTRL_INVALID          "Invalid frame capability passed for control structure",
     failure VMKIT_ENDPOINT              "Error setting monitor endpoint for dispatcher",
     failure VMKIT_ENDPOINT_INVALID      "Invalid monitor endpoint capability passed",
-    failure VMKIT_VMX_VMFAIL_INVALID   "The VMCS pointer is invalid", 
+    failure VMKIT_VMX_VMFAIL_INVALID   "The VMCS pointer is invalid",
     failure VMKIT_VMX_VMFAIL_VALID      "VMX instruction failed (VM-instruction error field = ErrorNumber)",
 
     // Serial port errors
@@ -1001,8 +1001,9 @@ errors vbe VBE_ERR_ {
     failure BIOS_CALL_FAILED    "Unknown error returned from VBE BIOS call",
 };
 
-// errors generated by ahcid and libahci
+// errors generated by lib/blk/ahci
 errors ahcid AHCI_ERR_ {
+    failure PORT_INIT           "Port initialization failed",
     failure PORT_INVALID        "Provided port id is not valid",
     failure PORT_BUSY           "Port has been opened elsewhere",
     failure PORT_MISMATCH       "Port is not opened by client",
@@ -1010,6 +1011,17 @@ errors ahcid AHCI_ERR_ {
     failure ILLEGAL_ARGUMENT    "Illegal argument in call",
 };
 
+// errors generated by devif
+errors ahcid DEV_ERR_ {
+    failure NOT_INITIALIZED     "Queue exists but could not be initialized.",
+    failure NOT_FOUND           "Invalid queue requested, not found?",
+    failure ALREADY_CREATED     "The queue specified has already been created.",
+    failure REGISTER_BUFFER     "Unable to register the buffer with the driver.",
+    failure INVALID_BUFFER_ARGS "Invalid arguments for specified buffer.",
+    failure QUEUE_EMPTY         "Nothing to dequeue.",
+    failure QUEUE_FULL          "The queue is full.",
+};
+
 errors sata SATA_ERR_ {
     failure INVALID_TYPE        "Unknown FIS type or invalid/unimplemented field for type",
 };
@@ -1081,8 +1093,8 @@ errors bulk_transfer BULK_TRANSFER_ {
     failure SM_EXCLUSIVE_WS     "BULK_SM: Exclusive waitset required per channel.",
     failure NET_MAX_QUEUES      "The number of maximum queues is reached",
     failure NET_POOL_USED       "The pool is already used over a no-copy channel.",
-    
-    
+
+
 };
 
 errors virtio VIRTIO_ERR_ {
@@ -1102,14 +1114,14 @@ errors virtio VIRTIO_ERR_ {
     failure QUEUE_INVALID        "The selected queue does not exist",
     failure QUEUE_BUSY           "The queue is busy.",
     failure BUFFER_SIZE          "The buffer size is invalid.",
-    failure BUFFER_STATE         "The state of the buffer / buffer list is invalid",               
+    failure BUFFER_STATE         "The state of the buffer / buffer list is invalid",
     failure ARG_INVALID          "The given argument is invalid.",
     failure NO_BUFFER            "No buffer given, number of buffers is 0",
     failure ALLOC_FULL           "The allocator is already full",
     failure BUFFER_USED          "The buffer is already enqueued and used",
     failure NO_DESC_AVAIL        "There is no descriptor availabe",
     failure DEQ_CHAIN            "Not the entire chain could be dequeued",
-    failure INVALID_RING_INDEX   "The supplied index is not valid", 
+    failure INVALID_RING_INDEX   "The supplied index is not valid",
     failure BLK_REQ_IOERR        "The request ended in an IO error",
     failure BLK_REQ_UNSUP        "The request type was not supported",
 };
index bc38325..73fdf32 100644 (file)
@@ -4,7 +4,7 @@
 --
 -- 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, Universitätstasse 6, CH-8092 Zurich. Attn: Systems Group.
+-- ETH Zurich D-INFK, Universitaetstasse 6, CH-8092 Zurich. Attn: Systems Group.
 --
 -- Architectural definitions for Barrelfish on ARMv5 ISA.
 --
@@ -65,7 +65,6 @@ cxxFlags = ArchDefaults.commonCxxFlags
 cDefines = ArchDefaults.cDefines options
 
 ourLdFlags = [ Str "-Wl,-section-start,.text=0x400000",
-               Str "-Wl,-section-start,.data=0x600000",
                Str "-Wl,--build-id=none" ]
 
 ldFlags = ArchDefaults.ldFlags arch ++ ourLdFlags
index 8427b72..523702e 100644 (file)
@@ -20,6 +20,8 @@ module        /armv7/sbin/monitor
 # Special boot time domains spawned by monitor
 module /armv7/sbin/ramfsd boot
 module /armv7/sbin/skb boot
+modulenounzip /eclipseclp_ramfs.cpio.gz nospawn
+modulenounzip /skb_ramfs.cpio.gz nospawn
 module /armv7/sbin/spawnd boot
 module /armv7/sbin/startd boot
 
index 5a44761..74c7a7e 100644 (file)
@@ -20,6 +20,8 @@ module        /armv7/sbin/monitor
 # Special boot time domains spawned by monitor
 module /armv7/sbin/ramfsd boot
 module /armv7/sbin/skb boot
+modulenounzip /eclipseclp_ramfs.cpio.gz nospawn
+modulenounzip /skb_ramfs.cpio.gz nospawn
 module /armv7/sbin/spawnd boot
 module /armv7/sbin/startd boot
 
index 78d6259..0f4adcf 100644 (file)
@@ -18,6 +18,8 @@ module /armv7/sbin/monitor
 # Special boot time domains spawned by monitor
 module /armv7/sbin/ramfsd boot
 module /armv7/sbin/skb boot
+modulenounzip /eclipseclp_ramfs.cpio.gz nospawn
+modulenounzip /skb_ramfs.cpio.gz nospawn
 module /armv7/sbin/kaluga boot
 module /armv7/sbin/spawnd boot bootarm=0
 module /armv7/sbin/startd boot
index 654e643..12835ff 100644 (file)
@@ -19,6 +19,8 @@ module        /armv7/sbin/monitor
 # Special boot time domains spawned by monitor
 module /armv7/sbin/ramfsd boot
 module /armv7/sbin/skb boot
+modulenounzip /eclipseclp_ramfs.cpio.gz nospawn
+modulenounzip /skb_ramfs.cpio.gz nospawn
 module /armv7/sbin/spawnd boot
 module /armv7/sbin/startd boot
 
index 3b1b1ee..fdda0ba 100644 (file)
@@ -39,6 +39,9 @@ interface acpi "acpi RPC Interface" {
     rpc reset(out errval err);
     rpc sleep(in uint32 state, out errval err);
 
+    rpc get_handle(in String devid[2048], out uint64 handle, out errval err);
+    rpc eval_integer(in uint64 handle, in String path[2048], out uint64 val, out errval err);
+
     // Kludge: retrieve frame cap to VBE BIOS;
     rpc get_vbe_bios_cap(out errval err, out cap cap, out uint32 size);
 
@@ -61,4 +64,3 @@ interface acpi "acpi RPC Interface" {
                                out cap devframe, out errval err);
     rpc mm_free_proxy(in cap devframe, in uint64 base, in uint8 sizebits, out errval err);
 };
-
index 9f249b4..b7ad66c 100644 (file)
 #define ACPI_CLIENT_H_
 
 #include <errors/errno.h>
-#include <if/acpi_rpcclient_defs.h>
+
+/* forward declaration */
+struct acpi_rpc_client;
+
+typedef uint64_t acpi_device_handle_t;
+
 
 struct acpi_rpc_client* get_acpi_rpc_client(void);
 errval_t connect_to_acpi(void);
 
+errval_t acpi_client_get_device_handle(const char *dev_id,
+                                       acpi_device_handle_t *ret_handle);
+errval_t acpi_client_eval_integer(acpi_device_handle_t handle,
+                                  const char *path, uint64_t *data);
+
 errval_t acpi_reset(void);
 errval_t acpi_sleep(int state);
 errval_t acpi_get_vbe_bios_cap(struct capref *retcap, size_t *retsize);
diff --git a/include/arch/aarch64/hw_records_arch.h b/include/arch/aarch64/hw_records_arch.h
new file mode 100644 (file)
index 0000000..f264fb3
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * \file hw.h
+ * \brief 
+ */
+
+/*
+ * Copyright (c) 2016, 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef INCLUDE_ARCH_AARCH64_HW_RECORDS_ARCH_H_
+#define INCLUDE_ARCH_AARCH64_HW_RECORDS_ARCH_H_
+
+#include <hw_records.h>
+
+#define HW_PROCESSOR_ARMV8_FIELDS "{ " HW_PROCESSOR_GENERIC_FIELDS ", " \
+                                      "cpu_interface_number: %d, " \
+                                      "uid: %d, " \
+                                      "mailbox: %" PRIx64 ", " \
+                                      "parkingversion: %d, " \
+                                      "mpdir: %" PRIx64 " }"
+
+#define HW_PROCESSOR_ARMV8_RECORD_FORMAT "hw.processor.%d " HW_PROCESSOR_ARMV8_FIELDS
+
+
+
+#define HW_PROCESSOR_ARMV8_REGEX  "r'hw\\.processor\\.[0-9]+' { " \
+                                      "cpu_interface_number: _, " \
+                                      "uid: _, " \
+                                      "hw_id: _," \
+                                      "mailbox: _, " \
+                                      "parkingversion: _, " \
+                                      "mpdir: _, " \
+                                      "enabled: 1, " \
+                                      "barrelfish_id: _, " \
+                                      "type: _ }"
+
+
+
+#endif /* INCLUDE_ARCH_AARCH64_HW_RECORDS_ARCH_H_ */
diff --git a/include/arch/x86/hw_records_arch.h b/include/arch/x86/hw_records_arch.h
new file mode 100644 (file)
index 0000000..a76beb3
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * \file hw.h
+ * \brief 
+ */
+
+/*
+ * Copyright (c) 2016, 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef INCLUDE_ARCH_X86_HW_RECORDS_ARCH_H_
+#define INCLUDE_ARCH_X86_HW_RECORDS_ARCH_H_
+
+#include <hw_records.h>
+
+#define HW_PROCESSOR_X86_FIELDS "{ " HW_PROCESSOR_GENERIC_FIELDS ", " \
+                                     "processor_id: %d, " \
+                                     "apic_id: %d }"
+
+#define HW_PROCESSOR_X86_RECORD_FORMAT "hw.processor.%d " HW_PROCESSOR_X86_FIELDS
+
+
+
+#define HW_PROCESSOR_X86_REGEX  "r'hw\\.processor\\.[0-9]+' { " \
+                                      "processor_id: _, " \
+                                      "apic_id: _, " \
+                                      "enabled: 1, " \
+                                      "barrelfish_id: _, " \
+                                      "type: _ }"
+
+
+
+#endif /* INCLUDE_ARCH_X86_HW_RECORDS_ARCH_H_ */
diff --git a/include/arch/x86_32/hw_records_arch.h b/include/arch/x86_32/hw_records_arch.h
new file mode 100644 (file)
index 0000000..328f7cb
--- /dev/null
@@ -0,0 +1,20 @@
+/**
+ * \file hw.h
+ * \brief 
+ */
+
+/*
+ * Copyright (c) 2016, 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef INCLUDE_ARCH_X86_32_HW_RECORDS_ARCH_H_
+#define INCLUDE_ARCH_X86_32_HW_RECORDS_ARCH_H_
+
+#include <arch/x86/hw_records_arch.h>
+
+#endif /* INCLUDE_ARCH_X86_32_HW_RECORDS_ARCH_H_ */
diff --git a/include/arch/x86_64/hw_records_arch.h b/include/arch/x86_64/hw_records_arch.h
new file mode 100644 (file)
index 0000000..c3c7de7
--- /dev/null
@@ -0,0 +1,20 @@
+/**
+ * \file hw.h
+ * \brief 
+ */
+
+/*
+ * Copyright (c) 2016, 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef INCLUDE_ARCH_X86_64_HW_RECORDS_ARCH_H_
+#define INCLUDE_ARCH_X86_64_HW_RECORDS_ARCH_H_
+
+#include <arch/x86/hw_records_arch.h>
+
+#endif /* INCLUDE_ARCH_X86_64_HW_RECORDS_ARCH_H_ */
index 85003fd..dbabeee 100644 (file)
@@ -88,12 +88,12 @@ static inline void dump_dispatcher(struct dispatcher_shared_generic *disp)
     printf("  dispatcher_pagefault          = 0x%"PRIxLVADDR"\n", disp->dispatcher_pagefault );
     printf("  dispatcher_pagefault_disabled = 0x%"PRIxLVADDR"\n", disp->dispatcher_pagefault_disabled );
     printf("  dispatcher_trap               = 0x%"PRIxLVADDR"\n", disp->dispatcher_trap );
-    printf("  systime      = 0x%lx\n", disp->systime );
-    printf("  wakeup       = 0x%lx\n", disp->wakeup );
+    printf("  systime      = 0x%" PRIuSYSTIME "\n", disp->systime );
+    printf("  wakeup       = 0x%" PRIuSYSTIME "\n", disp->wakeup );
     printf("  name         = %.*s\n", DISP_NAME_LEN, disp->name );
     printf("  fpu_used     = %d\n", disp->fpu_used );
     printf("  fpu_trap     = %d\n", disp->fpu_trap );
-    printf("  curr_core_id = 0x%x\n", disp->curr_core_id );
+    printf("  curr_core_id = 0x%" PRIxCOREID "\n", disp->curr_core_id );
 }
 
 
diff --git a/include/blk/ahci.h b/include/blk/ahci.h
new file mode 100644 (file)
index 0000000..8c726e3
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2016, 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef _AHCI_
+#define _AHCI_
+
+#include <barrelfish/barrelfish.h>
+#include <pci/mem.h>
+
+struct ahci_disk;
+
+errval_t blk_ahci_init(struct device_mem* bar5, struct ahci_disk** out);
+errval_t blk_ahci_stop(struct ahci_disk* ad);
+
+#endif // _AHCI_
diff --git a/include/device_interfaces/device_queue_interface.h b/include/device_interfaces/device_queue_interface.h
deleted file mode 100644 (file)
index 478e91f..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (c) 2016 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
- */
-#ifndef DEVICE_QUEUE_INTERFACE_H_
-#define DEVICE_QUEUE_INTERFACE_H_ 1
-
-
-#include <barrelfish/barrelfish.h>
-
-typedef uint32_t regionid_t;
-typedef uint32_t bufferid_t;
-
-/**
- * Represent the device queue itself
- */
-struct device_queue {
-
-    uint32_t queue_id;
-
-    // name of the device
-    char* device_name;
-    // pointer to device queue state
-    void* q_state;
-
-    //TODO Other state needed ...
-    
-};
-
-
-struct device_queue_buffer {
-    // region id to which the buffer belongs
-    regionid_t region_id;
-    // id within the region
-    bufferid_t buffer_id;
-    // physical base address of the buffer
-    lpaddr_t base;
-    // length of the buffer
-    size_t len;
-}
-
-/*
- * ===========================================================================
- * Device queue creation and destruction
- * ===========================================================================
- */
-
-
- /**
-  * @brief creates a queue 
-  *
-  * @param q             Return pointer to the device_queue (handle)
-  * @param device_name   Device name of the device to which this queue belongs
-  *                      (Driver itself is running in a separate process)
-  * @param misc          Anything you can think of that makes sense for the device
-  *                      and its driver?
-  *
-  * @returns error on failure or SYS_ERR_OK on success
-  */
-
-errval_t device_queue_create(struct device_queue **q,
-                             char* device_name,
-                             char* misc);
-
-
- /**
-  * @brief destroys the device queue
-  *
-  * @param q           The queue state to free (and the device queue to be 
-                       shut down in the driver)
-  *
-  * @returns error on failure or SYS_ERR_OK on success
-  */
-errval_t device_queue_destroy(struct device_queue *qp);
-
-
-/*
- * ===========================================================================
- * Datapath functions
- * ===========================================================================
- */
-
-/**
- * @brief enqueue a buffer into the device queue
- *
- * @param q             The device queue to call the operation on
- * @param region_id     Id of the memory region the buffer belongs to
- * @param base          Physical address of the start of the enqueued buffer
- * @param lenght        Lenght of the enqueued buffer
- * @param buffer_id     The buffer id of the enqueue buffer (TODO only for 
- *                      fixed size buffers?)
- * @param misc_flags    Any other argument that makes sense to the device queue
- *
- * @returns error on failure or SYS_ERR_OK on success
- *
- */
-errval_t device_queue_enqueue(struct device_queue *q,
-                              regionid_t region_id,
-                              lpaddr_t base,
-                              size_t length,
-                              bufferid_t buffer_id,
-                              char* misc_flags);
-
-/**
- * @brief enqueue some memory into the device queue
- *
- * @param q             The device queue to call the operation on
- * @param buf           Buffer to enqueue (includes physical address, lenght, 
- *                      region id and buffer id)
- * @param misc_flags    Any other argument that makes sense to the device queue
- *
- * @returns error on failure or SYS_ERR_OK on success
- *
- */
-errval_t device_queue_enqueue(struct device_queue *q,
-                              struct device_queue_buffer* buf,
-                              char* misc_flags);
-
-
-/**
- * @brief dequeue a buffer from the device queue
- *
- * @param q             The device queue to call the operation on
- * @param region_id     Return pointer to the id of the memory 
- *                      region the buffer belongs to
- * @param base          Return pointer to the physical address of 
- *                      the of the buffer
- * @param lenght        Return pointer to the lenght of the dequeue buffer
- * @param buffer_id     Return pointer to thehe buffer id of the dequeued buffer
- *
- * @returns error on failure or SYS_ERR_OK on success
- *
- */
-errval_t device_queue_dequeue(struct device_queue *q,
-                              regionid_t* region_id,
-                              lpaddr_t* base,
-                              size_t* length,
-                              bufferid_t* buffer_id);
-
-/**
- * @brief dequeue a buffer from the device queue
- *
- * @param q             The device queue to call the operation on
- * @param buf           Return pointer to the dequeued buffer
- *
- * @returns error on failure or SYS_ERR_OK on success
- *
- */
-errval_t device_queue_dequeue(struct device_queue *q,
-                              struct device_queue_buf** buf);
-/*
- * ===========================================================================
- * Control Path
- * ===========================================================================
- */
-
-/**
-* @brief Add a memory region that can be used as buffers to 
-*        the device queue
-*
-* @param q              The device queue to call the operation on
-* @param cap            A Capability for some memory
-* @param region_id      Return pointer to a region id that is assigned
-*                       to the memory
-*
-* @returns error on failure or SYS_ERR_OK on success
-*
-*/
-errval_t device_queue_register(struct device_queue *q,
-                               struct capref cap,
-                               regionid_t* region_id);
-
-/**
-* @brief Remove a memory region 
-*
-* @param q              The device queue to call the operation on
-* @param region_id      The region id to remove from the device 
-*                       queues memory
-* @param cap            The capability to the removed memory
-*
-* @returns error on failure or SYS_ERR_OK on success
-*
-*/
-errval_t device_queue_register(struct device_queue *q,
-                               regionid_t region_id,
-                               struct capref* cap);
-
-/**
-* @brief Send a notification about new buffers on the queue
-*
-* @param q      The device queue to call the operation on
-*
-* @returns error on failure or SYS_ERR_OK on success
-*
-*/
-errval_t device_queue_sync(struct device_queue *q);
-
-/**
-* @brief Send a control message to the device queue
-*
-* @param q      The device queue to call the operation on
-* @param ctrl   A sting encoding the control message
-*
-* @returns error on failure or SYS_ERR_OK on success
-*
-*/
-errval_t device_queue_control(struct device_queue *q,
-                              char* ctrl);
-
-#endif /* DEVICE_QUEUE_INTERFACE_H_ */
diff --git a/include/devif/queue.h b/include/devif/queue.h
new file mode 100644 (file)
index 0000000..b2869bd
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2016 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+#ifndef DEVICE_QUEUE_INTERFACE_H_
+#define DEVICE_QUEUE_INTERFACE_H_ 1
+
+#include <barrelfish/barrelfish.h>
+
+typedef uint64_t regionid_t;
+typedef uint64_t bufferid_t;
+
+/*
+ * ===========================================================================
+ * Device queue creation and destruction
+ * ===========================================================================
+ */
+
+/**
+ * @brief creates a queue
+ * @returns error on failure or SYS_ERR_OK on success
+ */
+
+errval_t devq_create(void* st, char *device_name, uint64_t flags, void **queue);
+
+/**
+ * @brief destroys the device queue
+ *
+ * @param q           The queue state to free (and the device queue to be
+                      shut down in the driver)
+ *
+ * @returns error on failure or SYS_ERR_OK on success
+ */
+errval_t devq_destroy(void *queue);
+
+/*
+ * ===========================================================================
+ * Datapath functions
+ * ===========================================================================
+ */
+
+/**
+ * @brief enqueue a buffer into the device queue
+ *
+ * @param q             The device queue to call the operation on
+ * @param region_id     Id of the memory region the buffer belongs to
+ * @param base          Physical address of the start of the enqueued buffer
+ * @param length        Length of the enqueued buffer
+ * @param buffer_id     The buffer id of the enqueue buffer (TODO only for
+ *                      fixed size buffers?)
+ * @param misc_flags    Any other argument that makes sense to the device queue
+ *
+ * @returns error on failure or SYS_ERR_OK on success
+ *
+ */
+errval_t devq_enqueue(void *q, regionid_t region_id, lpaddr_t base,
+                      size_t length, bufferid_t buffer_id, uint64_t flags);
+
+/**
+ * @brief dequeue a buffer from the device queue
+ *
+ * @param q             The device queue to call the operation on
+ * @param region_id     Return pointer to the id of the memory
+ *                      region the buffer belongs to
+ * @param base          Return pointer to the physical address of
+ *                      the of the buffer
+ * @param length        Return pointer to the length of the dequeue buffer
+ * @param buffer_id     Return pointer to the buffer id of the dequeued buffer
+ *
+ * @returns error on failure or SYS_ERR_OK on success
+ *
+ */
+errval_t devq_dequeue(void *q, regionid_t *region_id, lpaddr_t *base,
+                      size_t *length, bufferid_t *buffer_id);
+/*
+ * ===========================================================================
+ * Control Path
+ * ===========================================================================
+ */
+
+/**
+* @brief Add a memory region that can be used as buffers to
+*        the device queue
+*
+* @param q              The device queue to call the operation on
+* @param cap            A Capability for some memory
+* @param region_id      Return pointer to a region id that is assigned
+*                       to the memory
+*
+* @returns error on failure or SYS_ERR_OK on success
+*
+*/
+errval_t devq_register(void *q, struct capref cap, regionid_t *region_id);
+
+/**
+* @brief Remove a memory region
+*
+* @param q              The device queue to call the operation on
+* @param region_id      The region id to remove from the device
+*                       queues memory
+* @param cap            The capability to the removed memory
+*
+* @returns error on failure or SYS_ERR_OK on success
+*
+*/
+errval_t devq_remove(void *q, regionid_t region_id);
+
+/**
+* @brief Send a notification about new buffers on the queue
+*
+* @param q      The device queue to call the operation on
+*
+* @returns error on failure or SYS_ERR_OK on success
+*
+*/
+errval_t devq_sync(void *q);
+
+/**
+* @brief Send a control message to the device queue
+*
+* @param q       The device queue to call the operation on
+* @param request A sting encoding the control message
+* @param value   A value for the request.
+*
+* @returns error on failure or SYS_ERR_OK on success
+*
+*/
+errval_t devq_control(void *q, uint64_t request, uint64_t value);
+
+#endif /* DEVICE_QUEUE_INTERFACE_H_ */
diff --git a/include/hw_records.h b/include/hw_records.h
new file mode 100644 (file)
index 0000000..d533527
--- /dev/null
@@ -0,0 +1,47 @@
+/**
+ * \file hw.h
+ * \brief 
+ */
+
+/*
+ * Copyright (c) 2016, 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef INCLUDE_HW_RECORDS_ARCH_H_
+#define INCLUDE_HW_RECORDS_ARCH_H_
+
+/*
+ * ===========================================================================
+ * Generic Processor Record
+ * ===========================================================================
+ *
+ * @enabled         flag whether this processor is enabled
+ * @barrelfish_id   barrelfish ID of this processor
+ * @hw_id           hardware assigned ID of this processor
+ * @type            processor type, represents enum cpu_type
+ */
+
+/**
+ * @brief the generic fields of a processor record
+ */
+#define HW_PROCESSOR_GENERIC_FIELDS "enabled: %d, " \
+                                    "barrelfish_id: %d, " \
+                                    "hw_id: %d, " \
+                                    "type: %d"
+
+/**
+ * @brief regular expression to match for new generic processors
+ */
+#define HW_PROCESSOR_GENERIC_REGEX "r'hw\\.processor\\.[0-9]+' { " \
+                                      "enabled: 1, " \
+                                      "barrelfish_id: _, " \
+                                      "hw_id: _, " \
+                                      "type: _ }"
+
+
+#endif /* INCLUDE_HW_RECORDS_ARCH_H_ */
index bcb4e4b..07de60e 100644 (file)
 #define OMAP44XX_MAP_L4_CKGEN_PRM                       0x4A306100
 #define OMAP44XX_MAP_L4_CKGEN_PRM_SIZE                  0x100
 
+#define OMAP44XX_MAP_L4_DEVICE_PRM                      0x4A307B00
+#define OMAP44XX_MAP_L4_DEVICE_PRM_SIZE                 0x100
+
 #define OMAP44XX_MAP_L4_WKUP_SRCM                       0x4A30A000
 #define OMAP44XX_MAP_L4_WKUP_SRCM_SIZE                  0x1000
 #define OMAP44XX_MAP_L4_WKUP_SYSCTRL_GENERAL_WKUP       0x4A30C000
index 687fd13..430a7c9 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef PCI_CLIENT_DEBUG_H
 #define PCI_CLIENT_DEBUG_H
 
+#define PCI_LIB_DEBUG 1
+
 #if defined(PCI_LIB_DEBUG) || defined(GLOBAL_DEBUG)
 #define PCI_CLIENT_DEBUG(x...) printf("pci_client: " x)
 #else
index e57bfa4..3127069 100644 (file)
@@ -205,6 +205,9 @@ static omap44xx_ckgen_cm1_t ckgen_cm1;
 static lvaddr_t ckgen_prm_base= 0;
 static omap44xx_ckgen_prm_t ckgen_prm;
 
+#define IN_MHZ(f) ((f) / 1000 / 1000)
+#define KHZ_DIGIT(f) (((f) / 1000 / 100) % 10)
+
 void
 a9_probe_tsc(void) {
     /* Read the base clock frequency, SYS_CLK. */
@@ -238,7 +241,8 @@ a9_probe_tsc(void) {
             panic("sys_clksel_status is invalid.\n");
     }
 
-    MSG("SYS_CLK is %"PRIu32"kHz\n", sys_clk / 1000);
+    MSG("SYS_CLK is %"PRIu32".%01"PRIu32"MHz\n",
+        IN_MHZ(sys_clk), KHZ_DIGIT(sys_clk));
 
     /* This is the main clock generator. */
     ckgen_cm1_base=
@@ -257,7 +261,11 @@ a9_probe_tsc(void) {
     uint32_t divisor = /* This is N+1 */
         omap44xx_ckgen_cm1_cm_clksel_dpll_mpu_dpll_div_rdf(&ckgen_cm1) + 1;
 
-    uint64_t f_dpll= (sys_clk * 2 * mult) / divisor;
+    MSG("M = %"PRIx32", N = %"PRIx32"\n", mult, divisor - 1);
+
+    uint64_t f_dpll= ((uint64_t)sys_clk * 2 * mult) / divisor;
+
+    MSG("f_dpll = %"PRIu64"\n", f_dpll);
 
     /* See TI SWPU235AB Figures 3-40 and 3-50. */
     bool dcc_en=
@@ -278,6 +286,7 @@ a9_probe_tsc(void) {
          * post-oscillator divider. */
         int m2=
             omap44xx_ckgen_cm1_cm_div_m2_dpll_mpu_dpll_clkout_div_rdf(&ckgen_cm1);
+        MSG("m2 = %d\n", m2);
         assert(m2 != 0);
         f_cpu= (f_dpll / 2) / m2;
     }
@@ -285,7 +294,10 @@ a9_probe_tsc(void) {
     /* The CPU clock is divided once more to generate the peripheral clock. */
     uint32_t f_periph= f_cpu / 2;
 
-    MSG("CPU frequency %lukHz, PERIPHCLK %lukHz\n", f_cpu/1000, f_periph/1000);
+    MSG("CPU frequency %"PRIu32".%01"PRIu32"MHz, "
+        "PERIPHCLK %"PRIu32".%01"PRIu32"MHz\n",
+        IN_MHZ(f_cpu), KHZ_DIGIT(f_cpu),
+        IN_MHZ(f_periph), KHZ_DIGIT(f_periph));
 
     tsc_hz= f_periph;
 }
index 891e55a..7c30b1b 100644 (file)
@@ -545,6 +545,6 @@ void paging_context_switch(lpaddr_t ttbr)
         sysreg_invalidate_tlb();
         //this isn't necessary on gem5, since gem5 doesn't implement the cache
         //maintenance instructions, but ensures coherency by itself
-        sysreg_invalidate_i_and_d_caches();
+        //sysreg_invalidate_i_and_d_caches();
     }
 }
index 4ba80fb..10cffa8 100644 (file)
@@ -356,7 +356,6 @@ void create_module_caps(struct spawn_state *st)
     struct multiboot_tag_module_64 *module = (struct multiboot_tag_module_64 *)
             multiboot2_find_header(multiboot, size, MULTIBOOT_TAG_TYPE_MODULE_64);
     while (module) {
-        printf("%s:%d module=%p\n", __FUNCTION__, __LINE__, module);
         // Set memory regions within bootinfo
         struct mem_region *region =
             &bootinfo->regions[bootinfo->regions_length++];
@@ -422,15 +421,9 @@ static void create_phys_caps(lpaddr_t reserved_start, lpaddr_t reserved_end)
             local_phys_to_mem(glbl_core_data->efi_mmap);
 
     lpaddr_t last_end_addr = 0;
-#if 0
-    lpaddr_t region_base = 0;
-    size_t region_size = 0;
-    enum region_type region_type = RegionType_Max;
-#endif
     for (size_t i = 0; i < (mmap->size - sizeof(struct multiboot_tag_efi_mmap)) / mmap->descr_size; i++) {
         efi_memory_descriptor *desc = (efi_memory_descriptor *)(mmap->efi_mmap + mmap->descr_size * i);
         printf("efi_memory_descriptor. type=%u, base=%lx (%lx), size=%lukb\n", desc->Type, desc->PhysicalStart, desc->VirtualStart, desc->NumberOfPages * 4);
-        //size_t start_region = 0;
 
         enum region_type region_type = RegionType_Max;
         switch(desc->Type) {
@@ -448,65 +441,14 @@ static void create_phys_caps(lpaddr_t reserved_start, lpaddr_t reserved_end)
            break;
         };
 
-        if (last_end_addr < desc->PhysicalStart + desc->NumberOfPages * BASE_PAGE_SIZE) {
-            last_end_addr = desc->PhysicalStart + desc->NumberOfPages * BASE_PAGE_SIZE;
+        if (last_end_addr < desc->PhysicalStart) {
+            // create cap for gap in mmap
+            create_phys_caps_region(reserved_start, reserved_end, last_end_addr, desc->PhysicalStart - last_end_addr, RegionType_PhyAddr);
         }
+        last_end_addr = desc->PhysicalStart + desc->NumberOfPages * BASE_PAGE_SIZE;
 
         create_phys_caps_region(reserved_start, reserved_end, desc->PhysicalStart, desc->NumberOfPages * BASE_PAGE_SIZE, region_type);
-
-#if 0
-
-        if (region_base && region_base + region_size == desc->PhysicalStart) {
-            // We have an adjacent region
-            if (desc->Type == EfiConventionalMemory && region_type == RegionType_Empty) {
-                // available memory
-                region_size += desc->NumberOfPages * BASE_PAGE_SIZE;
-            } else if (desc->Type != EfiConventionalMemory && region_type == RegionType_PlatformData) {
-                // device memory
-                region_size += desc->NumberOfPages * BASE_PAGE_SIZE;
-            } else if (desc->Type == EfiConventionalMemory && region_type == RegionType_PlatformData && desc->NumberOfPages < 16384) {
-                // device memory
-                region_size += desc->NumberOfPages * BASE_PAGE_SIZE;
-            } else {
-                // new region started
-
-                // map old region
-                create_phys_caps_region(reserved_start, reserved_end, region_base, region_size, region_type);
-
-                // store new region data
-                start_region = 1;
-            }
-        } else if (region_base) {
-            // have previous region, but found a gap
-
-            // map old region
-            create_phys_caps_region(reserved_start, reserved_end, region_base, region_size, region_type);
-            // map gap
-            lpaddr_t gap_start = region_base + region_size;
-            size_t gap_size = desc->PhysicalStart - gap_start;
-            create_phys_caps_region(reserved_start, reserved_end, gap_start, gap_size, RegionType_PhyAddr);
-
-            // store new region data
-            start_region = 1;
-        } else {
-            // no previous region
-            // store new region data
-            start_region = 1;
-        }
-
-        if (start_region) {
-            // store new region data
-            region_base = desc->PhysicalStart;
-            region_size = desc->NumberOfPages * BASE_PAGE_SIZE;
-            if (desc->Type == EfiConventionalMemory) {
-                region_type = RegionType_Empty;
-            } else {
-                region_type = RegionType_PlatformData;
-            }
-        }
-#endif
-//             if (last_end_addr >= reserved_end
-       }
+    }
 
     size_t size = (1UL << 48) - last_end_addr;
 
@@ -689,10 +631,6 @@ static struct dcb *spawn_init_common(const char *name,
     errval_t  err = caps_create_new(ObjType_IO, 0, 0, 0, my_core_id, iocap);
     assert(err_is_ok(err));*/
 
-    struct cte *iocap = caps_locate_slot(CNODE(spawn_state.taskcn), TASKCN_SLOT_IO);
-    errval_t  err = caps_create_new(ObjType_DevFrame, 0x10000000, 1UL << 28,
-                                    1UL << 28, my_core_id, iocap);
-        assert(err_is_ok(err));        
 
     struct dispatcher_shared_generic *disp
         = get_dispatcher_shared_generic(init_dcb->disp);
index ac76f63..968c91b 100644 (file)
@@ -398,14 +398,18 @@ static void init_page_tables(struct spawn_state *st, alloc_phys_func alloc_phys)
 static struct dcb *spawn_init_common(struct spawn_state *st, const char *name,
                                      int argc, const char *argv[],
                                      lpaddr_t bootinfo_phys,
-                                     alloc_phys_func alloc_phys)
+                                     alloc_phys_func alloc_phys,
+                                     alloc_phys_aligned_func alloc_phys_aligned)
 {
     errval_t err;
 
     /* Perform arch-independent spawn */
     lvaddr_t paramaddr;
     struct dcb *init_dcb = spawn_module(st, name, argc, argv, bootinfo_phys,
-                                        ARGS_BASE, alloc_phys, &paramaddr);
+                                        ARGS_BASE, alloc_phys, alloc_phys_aligned,
+                                        &paramaddr);
+
+
 
     /* Init page tables */
     init_page_tables(st, alloc_phys);
@@ -461,7 +465,8 @@ static struct dcb *spawn_init_common(struct spawn_state *st, const char *name,
     return init_dcb;
 }
 
-struct dcb *spawn_bsp_init(const char *name, alloc_phys_func alloc_phys)
+struct dcb *spawn_bsp_init(const char *name, alloc_phys_func alloc_phys,
+                           alloc_phys_aligned_func alloc_phys_aligned)
 {
     errval_t err;
 
@@ -480,7 +485,8 @@ struct dcb *spawn_bsp_init(const char *name, alloc_phys_func alloc_phys)
     int argc = 2;
 
     struct dcb *init_dcb = spawn_init_common(&spawn_state, name, argc, argv,
-                                             bootinfo_phys, alloc_phys);
+                                             bootinfo_phys, alloc_phys,
+                                             alloc_phys_aligned);
 
     /* Map bootinfo R/W into VSpace at vaddr 0x200000 (BOOTINFO_BASE) */
 #ifdef CONFIG_PAE
@@ -537,7 +543,8 @@ struct dcb *spawn_bsp_init(const char *name, alloc_phys_func alloc_phys)
 }
 
 struct dcb *spawn_app_init(struct x86_core_data *core_data,
-                           const char *name, alloc_phys_func alloc_phys)
+                           const char *name, alloc_phys_func alloc_phys,
+                           alloc_phys_aligned_func alloc_phys_aligned)
 {
     errval_t err;
 
@@ -559,7 +566,7 @@ struct dcb *spawn_app_init(struct x86_core_data *core_data,
     int argc = 4;
 
     struct dcb *init_dcb = spawn_init_common(&spawn_state, name, argc, argv,
-                                             0, alloc_phys);
+                                             0, alloc_phys, alloc_phys_aligned);
 
     // Urpc frame cap
     struct cte *urpc_frame_cte = caps_locate_slot(CNODE(spawn_state.taskcn),
index d58f1c3..c7a065e 100644 (file)
@@ -58,11 +58,11 @@ int sprint_cap(char *buf, size_t len, struct capability *cap)
     switch (cap->type) {
     case ObjType_PhysAddr:
         return snprintf(buf, len,
-                        "physical address range cap (0x%" PRIxGENPADDR ":0x%zx)",
+                        "physical address range cap (0x%" PRIxGENPADDR ":0x%" PRIxGENSIZE ")",
                         cap->u.physaddr.base, cap->u.physaddr.bytes);
 
     case ObjType_RAM:
-        return snprintf(buf, len, "RAM cap (0x%" PRIxGENPADDR ":0x%zx)",
+        return snprintf(buf, len, "RAM cap (0x%" PRIxGENPADDR ":0x%" PRIxGENSIZE ")",
                         cap->u.ram.base, cap->u.ram.bytes);
 
     case ObjType_CNode: {
@@ -80,11 +80,11 @@ int sprint_cap(char *buf, size_t len, struct capability *cap)
         return snprintf(buf, len, "Dispatcher cap %p", cap->u.dispatcher.dcb);
 
     case ObjType_Frame:
-        return snprintf(buf, len, "Frame cap (0x%" PRIxGENPADDR ":0x%zx)",
+        return snprintf(buf, len, "Frame cap (0x%" PRIxGENPADDR ":0x%" PRIxGENSIZE ")",
                         cap->u.frame.base, cap->u.frame.bytes);
 
     case ObjType_DevFrame:
-        return snprintf(buf, len, "Device Frame cap (0x%" PRIxGENPADDR ":0x%zx)",
+        return snprintf(buf, len, "Device Frame cap (0x%" PRIxGENPADDR ":0x%" PRIxGENSIZE ")",
                         cap->u.frame.base, cap->u.devframe.bytes);
 
     case ObjType_VNode_ARM_l1:
@@ -579,7 +579,7 @@ static errval_t caps_create(enum objtype type, lpaddr_t lpaddr, gensize_t size,
     genpaddr_t genpaddr = local_phys_to_gen_phys(lpaddr);
 
     debug(SUBSYS_CAPS, "creating caps for %#"PRIxGENPADDR
-                       ", %zu bytes, objsize=%"PRIuGENSIZE
+                       ", %" PRIuGENSIZE " bytes, objsize=%"PRIuGENSIZE
                        ", count=%zu, owner=%d, type=%d\n",
             genpaddr, size, objsize, count, (int)owner, (int)type);
 
@@ -1372,7 +1372,8 @@ errval_t caps_retype(enum objtype type, gensize_t objsize, size_t count,
         return SYS_ERR_INVALID_RETYPE;
     }
 
-    debug(SUBSYS_CAPS, "%s: Retyping to type=%d, from offset=%zu, objsize=%zu, count=%zu\n",
+    debug(SUBSYS_CAPS, "%s: Retyping to type=%d, from offset=%" PRIuGENSIZE
+            ", objsize=%" PRIuGENSIZE ", count=%zu\n",
             __FUNCTION__, type, offset, objsize, count);
 
     /* check that offset into source cap is multiple of BASE_PAGE_SIZE */
@@ -1383,7 +1384,7 @@ errval_t caps_retype(enum objtype type, gensize_t objsize, size_t count,
 
     // check that size is multiple of BASE_PAGE_SIZE for mappable types
     if (type_is_mappable(type) && objsize % BASE_PAGE_SIZE != 0) {
-        printk(LOG_WARN, "%s: objsize = %zu\n", __FUNCTION__, objsize);
+        printk(LOG_WARN, "%s: objsize = %" PRIuGENSIZE "\n", __FUNCTION__, objsize);
         return SYS_ERR_INVALID_SIZE;
     }
     // CNode is special for now, as we still specify CNode size in #slots
@@ -1391,7 +1392,7 @@ errval_t caps_retype(enum objtype type, gensize_t objsize, size_t count,
     else if (type == ObjType_CNode &&
             ((objsize * sizeof(struct cte)) % BASE_PAGE_SIZE != 0))
     {
-        printk(LOG_WARN, "%s: CNode: objsize = %zu\n", __FUNCTION__, objsize);
+        printk(LOG_WARN, "%s: CNode: objsize = %" PRIuGENSIZE "\n", __FUNCTION__, objsize);
         return SYS_ERR_INVALID_SIZE;
     }
     // TODO: clean up semantics for type == ObjType_CNode
@@ -1465,7 +1466,8 @@ errval_t caps_retype(enum objtype type, gensize_t objsize, size_t count,
         // TODO: convince ourselves that this is the only condition on offset
         if (offset + count * objsize > get_size(src_cap)) {
             debug(SUBSYS_CAPS, "caps_retype: cannot create all %zu objects"
-                    " of size 0x%zx from offset 0x%zx\n", count, objsize, offset);
+                    " of size 0x%" PRIxGENSIZE " from offset 0x%" PRIxGENSIZE "\n",
+                    count, objsize, offset);
             return SYS_ERR_RETYPE_INVALID_OFFSET;
         }
         // adjust base address for new objects
index 455292b..e0d76c1 100644 (file)
@@ -28,6 +28,25 @@ static struct acpi_connection {
 
 static struct acpi_rpc_client* rpc_client;
 
+errval_t acpi_client_get_device_handle(const char *dev_id,
+                                       acpi_device_handle_t *ret_handle)
+{
+    assert(rpc_client != NULL);
+    errval_t err, msgerr;
+    err = rpc_client->vtbl.get_handle(rpc_client, dev_id, ret_handle, &msgerr);
+    return err_is_fail(err) ? err : msgerr;
+}
+
+errval_t acpi_client_eval_integer(acpi_device_handle_t handle,
+                                  const char *path, uint64_t *data)
+{
+    assert(rpc_client != NULL);
+    errval_t err, msgerr;
+    err = rpc_client->vtbl.eval_integer(rpc_client, handle, path, data, &msgerr);
+    return err_is_fail(err) ? err : msgerr;
+}
+
+
 errval_t acpi_reset(void)
 {
     assert(rpc_client != NULL);
index 21afd14..73abc75 100644 (file)
@@ -106,8 +106,7 @@ errval_t ahci_setup_command(int *command, struct ahci_port_info *port,
     ahci_port_chdr_t chdr = (ahci_port_chdr_t) command_header_entry;
     ahci_port_chdr_cfl_insert(chdr, fis_length / 4);
     ahci_port_chdr_w_insert(chdr, is_write);
-    ahci_port_chdr_ctba_insert(chdr, (uint32_t)ct->paddr);
-    ahci_port_chdr_ctbau_insert(chdr, (uint32_t)(ct->paddr >> 32));
+    ahci_port_chdr_ctba_insert(chdr, ct->paddr);
 
     // copy fis into command table
     memset(ct->vaddr, 0, cmd_table_size);
index d442b08..3fc633f 100644 (file)
@@ -65,7 +65,7 @@
 // Amount of virtual address space reserved for mapping frames
 // backing refill_slabs.
 //#define META_DATA_RESERVED_SPACE (BASE_PAGE_SIZE * 128) // 64
-#define META_DATA_RESERVED_SPACE (BASE_PAGE_SIZE * 256)
+#define META_DATA_RESERVED_SPACE (BASE_PAGE_SIZE * 1024)
 // increased above value from 128 for pandaboard port
 
 // Convenience macros to figure out user space page table indices
index 8a56aae..23981d9 100644 (file)
 #include <stdio.h>
 #include <inttypes.h>
 
+errval_t sys_debug_get_tsc_per_ms(uint64_t *ret)
+{
+    struct sysret sr = syscall2(SYSCALL_DEBUG, DEBUG_GET_TSC_PER_MS);
+    *ret = sr.value;
+    return sr.error;
+}
+
 errval_t sys_debug_hardware_timer_read(uintptr_t* v)
 {
     struct sysret sr
index 94776c3..fee7b45 100644 (file)
@@ -138,11 +138,11 @@ int debug_print_cap(char *buf, size_t len, struct capability *cap)
     switch (cap->type) {
     case ObjType_PhysAddr:
         return snprintf(buf, len,
-                        "physical address range cap (0x%" PRIxGENPADDR ":0x%zx)",
+                        "physical address range cap (0x%" PRIxGENPADDR ":0x%" PRIuGENSIZE ")",
                         cap->u.physaddr.base, cap->u.physaddr.bytes);
 
     case ObjType_RAM:
-        return snprintf(buf, len, "RAM cap (0x%" PRIxGENPADDR ":0x%zx)",
+        return snprintf(buf, len, "RAM cap (0x%" PRIxGENPADDR ":0x%" PRIuGENSIZE ")",
                         cap->u.ram.base, cap->u.ram.bytes);
 
     case ObjType_CNode: {
@@ -160,11 +160,11 @@ int debug_print_cap(char *buf, size_t len, struct capability *cap)
         return snprintf(buf, len, "Dispatcher cap %p", cap->u.dispatcher.dcb);
 
     case ObjType_Frame:
-        return snprintf(buf, len, "Frame cap (0x%" PRIxGENPADDR ":0x%zx)",
+        return snprintf(buf, len, "Frame cap (0x%" PRIxGENPADDR ":0x%" PRIuGENSIZE ")",
                         cap->u.frame.base, cap->u.frame.bytes);
 
     case ObjType_DevFrame:
-        return snprintf(buf, len, "Device Frame cap (0x%" PRIxGENPADDR ":%zx)",
+        return snprintf(buf, len, "Device Frame cap (0x%" PRIxGENPADDR ":%" PRIuGENSIZE ")",
                         cap->u.frame.base, cap->u.devframe.bytes);
 
     case ObjType_VNode_ARM_l1:
index c676029..e13437e 100644 (file)
@@ -213,6 +213,13 @@ void arranet_polling_loop_proxy(void)
     USER_PANIC("Network polling not available without Arranet!\n");
 }
 
+void poll_ahci(struct waitset_chanstate *) __attribute__((weak));
+void poll_ahci(struct waitset_chanstate *chan)
+{
+    errval_t err = waitset_chan_trigger(chan);
+    assert(err_is_ok(err)); // should not be able to fail
+}
+
 /// Check polled channels
 void poll_channels_disabled(dispatcher_handle_t handle) {
     struct dispatcher_generic *dp = get_dispatcher_generic(handle);
@@ -239,7 +246,9 @@ void poll_channels_disabled(dispatcher_handle_t handle) {
         case CHANTYPE_LWIP_SOCKET:
             arranet_polling_loop_proxy();
             break;
-
+        case CHANTYPE_AHCI:
+            poll_ahci(chan);
+            break;
         default:
             assert(!"invalid channel type to poll!");
         }
@@ -259,7 +268,9 @@ static void reregister_channel(struct waitset *ws, struct waitset_chanstate *cha
     }
 
     chan->token = 0;
-    if (chan->chantype == CHANTYPE_UMP_IN) {
+    if (chan->chantype == CHANTYPE_UMP_IN
+        || chan->chantype == CHANTYPE_LWIP_SOCKET 
+        || chan->chantype == CHANTYPE_AHCI) {
         enqueue(&ws->polled, chan);
         enqueue_polled(&get_dispatcher_generic(handle)->polled_channels, chan);
         chan->state = CHAN_POLLED;
diff --git a/lib/blk/Hakefile b/lib/blk/Hakefile
new file mode 100644 (file)
index 0000000..2401859
--- /dev/null
@@ -0,0 +1,7 @@
+[
+  build library {
+    target = "blk",
+    mackerelDevices = [ "ata_identify", "ahci_port", "ahci_hba" ],
+    cFiles = [ "blk.c", "blk_ahci/ahci_init.c", "blk_ahci/ahci_port.c", "blk_ahci/ahci_dev.c", "blk_ahci/sata_fis.c", "blk_ahci/device_impl.c", "dma_mem/dma_mem.c" ]
+  }
+]
diff --git a/lib/blk/blk.c b/lib/blk/blk.c
new file mode 100644 (file)
index 0000000..c0ed394
--- /dev/null
@@ -0,0 +1,19 @@
+/**
+ * \file
+ * \brief
+ */
+/*
+ * Copyright (c) 2016, 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <barrelfish/barrelfish.h>
diff --git a/lib/blk/blk_ahci/ahci_dev.c b/lib/blk/blk_ahci/ahci_dev.c
new file mode 100644 (file)
index 0000000..5c6992f
--- /dev/null
@@ -0,0 +1,149 @@
+///! AHCI Device helper functions
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/deferred.h>
+
+#include "blk_ahci.h"
+#include "../blk_debug.h"
+
+#include "ahci_dev.h"
+
+size_t ahci_port_offset(uint32_t port)
+{
+    return 0x100 + port * 0x80;
+}
+
+bool ahci_port_is_idle(ahci_port_t* port)
+{
+    ahci_port_cmd_t cmd = ahci_port_cmd_rd(port);
+    uint8_t st = ahci_port_cmd_st_extract(cmd);
+    uint8_t cr = ahci_port_cmd_cr_extract(cmd);
+    uint8_t fre = ahci_port_cmd_fre_extract(cmd);
+
+    return st == 0 && cr == 0 && fre == 0;
+}
+
+bool ahci_port_is_ready(ahci_port_t* port)
+{
+    uint8_t busy = ahci_port_tfd_bsy_rdf(port);
+    uint8_t drq = ahci_port_tfd_drq_rdf(port);
+    return busy == 0 && drq == 0;
+}
+
+bool ahci_port_is_functional(ahci_port_t* port)
+{
+    uint8_t det = ahci_port_ssts_det_rdf(port);
+    return ahci_port_is_ready(port) && det == 0x3;
+}
+
+bool ahci_port_slot_free(ahci_port_t* port, uint8_t slot)
+{
+    bool ci_free = (ahci_port_ci_rd(port) & (1<<slot)) == 0;
+    bool sact_free = (ahci_port_sact_rd(port) & (1<<slot)) == 0;
+    return ci_free && sact_free;
+}
+
+void ahci_port_start(ahci_port_t* port)
+{
+    assert(ahci_port_is_functional(port));
+    ahci_port_cmd_st_wrf(port, 0x1);
+}
+
+void ahci_port_stop(ahci_port_t* port)
+{
+    ahci_port_cmd_st_wrf(port, 0);
+
+    ahci_port_cmd_t cmd = ahci_port_cmd_rd(port);
+    while (ahci_port_cmd_cr_extract(cmd) != 0) {
+        // TODO should clear in 500ms
+    }
+
+    ahci_port_cmd_fre_wrf(port, 0);
+    while (ahci_port_cmd_fr_rdf(port) != 0) {
+        // TODO should clear in 500ms
+    }
+}
+
+bool ahci_port_is_running(ahci_port_t* port)
+{
+    return ahci_port_cmd_st_rdf(port) > 0;
+}
+
+uint32_t ahci_port_probe(ahci_port_t* port)
+{
+    if (ahci_port_ssts_det_rdf(port) == 0x03) {
+        return ahci_port_sig_rd(port);
+    }
+
+    return 0;
+}
+
+void ahci_hba_reset(ahci_hba_t* controller)
+{
+    ahci_hba_ghc_t ghc = ahci_hba_ghc_rd(controller);
+    BLK_DEBUG("Resetting HBA (setting ghc = %x)...\n", ghc);
+    ghc = ahci_hba_ghc_hr_insert(ghc, 1);
+    ahci_hba_ghc_wr(controller, ghc);
+    barrelfish_usleep(200000);
+    while (1) {
+        ghc = ahci_hba_ghc_rd(controller);
+        if (ahci_hba_ghc_hr_extract(ghc) == 0) {
+            BLK_DEBUG("reset done\n");
+            break;
+        }
+    }
+}
+
+void ahci_hba_irq_enable(ahci_hba_t* controller)
+{
+    BLK_DEBUG("Enabling HBA Interrupts\n");
+    ahci_hba_ghc_t ghc = ahci_hba_ghc_rd(controller);
+    ghc = ahci_hba_ghc_ie_insert(ghc, 1);
+    ahci_hba_ghc_wr(controller, ghc);
+}
+
+void ahci_hba_irq_disable(ahci_hba_t* controller)
+{
+    BLK_DEBUG("Disable HBA Interrupts\n");
+    ahci_hba_ghc_t ghc = ahci_hba_ghc_rd(controller);
+    ghc = ahci_hba_ghc_ie_insert(ghc, 1);
+    ahci_hba_ghc_wr(controller, ghc);
+}
+
+uint32_t ahci_hba_get_num_ports(ahci_hba_t* controller)
+{
+    return ahci_hba_cap_np_extract(ahci_hba_cap_rd(controller)) + 1;
+}
+
+uint32_t ahci_hba_get_command_slots(ahci_hba_t* controller)
+{
+    return ahci_hba_cap_ncs_extract(ahci_hba_cap_rd(controller));
+}
+
+bool ahci_port_is_implemented(ahci_hba_t* controller, size_t port)
+{
+    return (ahci_hba_pi_rd(controller) & (1 << port)) > 0;
+}
+
+void ahci_port_print_identification(ata_identify_t *id)
+{
+    char* buf2 = malloc(10*4096);
+    assert(buf2 != NULL);
+    ata_identify_pr(buf2, 10*4096, id);
+    puts(buf2);
+    free(buf2);
+}
+
+errval_t ahci_hba_init(ahci_hba_t* controller)
+{
+    ahci_hba_reset(controller);
+
+    // Make sure AHCI is enabled:
+    BLK_DEBUG("Setting controller into AHCI mode\n");
+    ahci_hba_ghc_t ghc = ahci_hba_ghc_rd(controller);
+    ghc = ahci_hba_ghc_ae_insert(ghc, 1);
+    ahci_hba_ghc_wr(controller, ghc);
+
+    ahci_hba_irq_disable(controller);
+
+    return SYS_ERR_OK;
+}
diff --git a/lib/blk/blk_ahci/ahci_dev.h b/lib/blk/blk_ahci/ahci_dev.h
new file mode 100644 (file)
index 0000000..0e1705f
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016, 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef AHCI_DEV_H_
+#define AHCI_DEV_H_
+
+#include <stdbool.h>
+#include <errors/errno.h>
+#include <dev/ahci_hba_dev.h>
+#include <dev/ahci_port_dev.h>
+#include <dev/ata_identify_dev.h>
+
+void ahci_hba_reset(ahci_hba_t* controller);
+void ahci_hba_irq_enable(ahci_hba_t* controller);
+void ahci_hba_irq_disable(ahci_hba_t* controller);
+uint32_t ahci_hba_get_num_ports(ahci_hba_t* controller);
+errval_t ahci_hba_init(ahci_hba_t* controller);
+uint32_t ahci_hba_get_command_slots(ahci_hba_t* controller);
+bool ahci_port_is_implemented(ahci_hba_t* controller, size_t port);
+uint32_t ahci_port_probe(ahci_port_t* port);
+
+void ahci_port_start(ahci_port_t* port);
+void ahci_port_stop(ahci_port_t* port);
+bool ahci_port_is_running(ahci_port_t* port);
+bool ahci_port_is_idle(ahci_port_t* port);
+bool ahci_port_is_functional(ahci_port_t* port);
+bool ahci_port_is_ready(ahci_port_t* port);
+size_t ahci_port_offset(uint32_t port);
+bool ahci_port_slot_free(ahci_port_t* port, uint8_t slot);
+
+void ahci_port_print_identification(ata_identify_t *id);
+
+#endif // AHCI_DEV_H_
diff --git a/lib/blk/blk_ahci/ahci_init.c b/lib/blk/blk_ahci/ahci_init.c
new file mode 100644 (file)
index 0000000..25f9ba5
--- /dev/null
@@ -0,0 +1,56 @@
+#include <barrelfish/barrelfish.h>
+#include <pci/pci.h>
+
+#include "blk_ahci.h"
+#include "../blk_debug.h"
+#include "ahci_dev.h"
+
+lvaddr_t blk_ahci_get_bar5_vaddr(struct ahci_disk* ad)
+{
+    assert(ad->bar5->vaddr != NULL);
+    return (lvaddr_t)ad->bar5->vaddr;
+}
+
+errval_t blk_ahci_init(struct device_mem* bar5, struct ahci_disk** out)
+{
+    errval_t err;
+
+    err = map_device(bar5);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "Map BAR5 failed.");
+    }
+
+    struct ahci_disk* ad = calloc(sizeof(struct ahci_disk), 1);
+    assert (ad != NULL);
+
+    ad->bar5 = bar5;
+
+    ahci_hba_initialize(&ad->controller, (void *)(bar5->vaddr));
+    BLK_DEBUG("Accessing conf regs starting at %p\n", (void *)(bar5->vaddr));
+    BLK_DEBUG("Physical address of conf regs: %p\n",  (void *)(bar5->paddr));
+
+    err = ahci_hba_init(&ad->controller);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "Init HBA failed.");
+    }
+
+    ahci_hba_irq_enable(&ad->controller);
+
+    err = blk_ahci_ports_init(ad);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "Port init failed.");
+    }
+
+    *out = ad;
+    return err;
+}
+
+
+errval_t blk_ahci_stop(struct ahci_disk* ad)
+{
+    // stop device
+    // devmem free (ad->bar5)
+    // free (ad)
+
+    return SYS_ERR_OK;
+}
diff --git a/lib/blk/blk_ahci/ahci_port.c b/lib/blk/blk_ahci/ahci_port.c
new file mode 100644 (file)
index 0000000..ddec091
--- /dev/null
@@ -0,0 +1,378 @@
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/deferred.h>
+
+#include <pci/pci.h>
+
+#include "blk_ahci.h"
+#include "ahci_dev.h"
+#include "sata_fis.h"
+
+#include "../blk_debug.h"
+#include "../dma_mem/dma_mem.h"
+
+static ahci_port_chdr_t get_command_header(struct ahci_port* port, uint8_t slot)
+{
+    return (ahci_port_chdr_t) ((uint8_t*)port->clb.vaddr) + (ahci_port_chdr_size * slot);
+}
+
+static struct region_descriptor region_descriptor_new(uint64_t dba, uint32_t dbc, bool irq)
+{
+    struct region_descriptor d;
+    d.dba = dba;
+    d.dbc = dbc;
+    d.dbc |= irq << 31;
+
+    return d;
+}
+
+static void command_table_set_cfis(struct command_table* ct, struct sata_fis_reg_h2d* fis)
+{
+    assert(sizeof(ct->cfis) >= sizeof(*fis));
+    struct sata_fis_reg_h2d* fis_ptr = (struct sata_fis_reg_h2d*) ct->cfis;
+    *fis_ptr = *fis;
+}
+
+static errval_t port_init_fb(struct ahci_port* port)
+{
+    assert(port != NULL);
+
+    errval_t err = dma_mem_alloc(1024, &port->fb);
+    if (err_is_fail(err)) {
+        DEBUG_ERR(err, "DMA alloc failed");
+        return err_push(err, AHCI_ERR_PORT_INIT);
+    }
+    memset((void*)port->fb.vaddr, 0x0, 1024);
+
+    assert(port->fb.paddr % 4096 == 0);
+    ahci_port_fb_wr(&port->port, port->fb.paddr);
+    return err;
+}
+
+static errval_t port_init_clb(struct ahci_port* port)
+{
+    assert (port != NULL);
+    assert (ahci_port_chdr_size*32 == 0x400);
+
+    errval_t err = dma_mem_alloc(ahci_port_chdr_size*32, &port->clb);
+    if (err_is_fail(err)) {
+        DEBUG_ERR(err, "DMA alloc failed");
+        return err_push(err, AHCI_ERR_PORT_INIT);
+    }
+    memset((void*)port->clb.vaddr, 0x0, ahci_port_chdr_size*32);
+
+    assert(port->clb.paddr % 1024 == 0);
+    ahci_port_clb_wr(&port->port, port->clb.paddr);
+    return err;
+}
+
+static errval_t port_init_ctba(struct ahci_port* port, size_t command_slot)
+{
+    assert(port != NULL);
+    assert(command_slot < MAX_CTBA_SLOTS);
+
+    errval_t err = dma_mem_alloc(4096, &port->ctba_mem[command_slot]);
+    if (err_is_fail(err)) {
+        DEBUG_ERR(err, "DMA alloc failed");
+        return err_push(err, AHCI_ERR_PORT_INIT);
+    }
+    memset((void*)port->ctba_mem[command_slot].vaddr, 0x0, 4096);
+    port->command_table[command_slot] = (struct command_table*) port->ctba_mem[command_slot].vaddr;
+
+    return err;
+}
+
+static void blk_ahci_interrupt(struct ahci_port* port, struct dev_queue *queue)
+{
+    ahci_port_is_t status = ahci_port_is_rd(&port->port);
+
+    // A request was handled:
+    //if (ahci_port_is_dhrs_extract(status) > 0) {
+        BLK_DEBUG("Done with DMA command.\n");
+
+        for (size_t slot = 0; slot < queue->port->ncs; slot++) {
+            struct dev_queue_request *dqr = &queue->requests[slot];
+
+            bool slot_has_request = dqr->status == RequestStatus_InProgress;
+            bool slot_done = ahci_port_slot_free(&port->port, slot);
+            if (slot_has_request && !slot_done) {
+                //printf("waiting for slot %zu.\n", slot);
+            }
+            if (slot_has_request && slot_done) {
+                //printf("AHCI slot %zu is done now.\n", slot);
+                dqr->status = RequestStatus_Done;
+            }
+        }
+
+        if (ahci_port_is_dhrs_extract(status)) {
+            ahci_port_is_dhrs_wrf(&port->port, 0x1);
+        }
+    //}
+
+    // Did something happen we can't yet handle?
+    if (status > 0x1) {
+#if defined(BLK_DEBUG_ENABLE)
+        char buf[4096];
+        ahci_port_is_pr(buf, 4096, &port->port);
+        BLK_DEBUG("GOT unhandled IRQ: %u\n", ahci_port_is_rd(&port->port));
+        puts(buf);
+#else
+        printf("[BLK] unhandled irq: %u", ahci_port_is_rd(&port->port));
+#endif
+    }
+    else {
+        //printf("[BLK] IRQ handled\n");
+    }
+}
+
+errval_t blk_ahci_port_dma_async(struct ahci_port *port, size_t slot, uint64_t block, lpaddr_t base, size_t length, bool write)
+{
+    assert(length % 512 == 0);
+    assert(ahci_port_slot_free(&port->port, 1 << slot));
+
+    errval_t err = SYS_ERR_OK;
+
+    ahci_port_chdr_t header = get_command_header(port, slot);
+    memset(header, 0, ahci_port_chdr_size);
+    ahci_port_chdr_a_insert(header, 0);
+    ahci_port_chdr_w_insert(header, write);
+    ahci_port_chdr_cfl_insert(header, sizeof(struct sata_fis_reg_h2d) / sizeof(uint32_t));
+    ahci_port_chdr_prdtl_insert(header, 1);
+    ahci_port_chdr_ctba_insert(header, port->ctba_mem[slot].paddr);
+
+    uint8_t command = write ? ATA_CMD_WRITE_DMA_EXT : ATA_CMD_READ_DMA_EXT;
+    uint16_t sectors = length / 512;
+
+    struct command_table* ct = port->command_table[slot];
+    struct sata_fis_reg_h2d fis;
+    sata_h2d_fis_new(&fis, command, block, sectors);
+    command_table_set_cfis(ct, &fis);
+    ct->prdt[0] = region_descriptor_new(base, (length - 1) | 0x1, false);
+
+    while (!ahci_port_is_ready(&port->port)) {
+        // TODO: Abort return error on timeout
+    }
+
+    // Issue command in slot 0
+    ahci_port_ci_rawwr(&port->port, 1 << slot);
+    BLK_DEBUG("Issued async DMA command.\n");
+
+#if 0
+    while ((ahci_port_ci_rd(&port->port) & (1<<slot)) > 0) {
+        // TODO: abort on timeout
+        //barrelfish_usleep(10000);
+    }
+    BLK_DEBUG("Done with DMA command.\n");
+#endif
+
+    return err;
+}
+
+errval_t blk_ahci_port_dma(struct ahci_port *port, uint64_t block, struct dma_mem *buffer, bool write)
+{
+    errval_t err = SYS_ERR_OK;
+    size_t slot = 0;
+
+    // TODO: use only slot 0
+    assert(ahci_port_slot_free(&port->port, 1 << slot));
+
+    ahci_port_chdr_t header = get_command_header(port, slot);
+    memset(header, 0, ahci_port_chdr_size);
+    ahci_port_chdr_a_insert(header, 0);
+    ahci_port_chdr_w_insert(header, write);
+    ahci_port_chdr_cfl_insert(header, sizeof(struct sata_fis_reg_h2d) / sizeof(uint32_t));
+    ahci_port_chdr_prdtl_insert(header, 1);
+    ahci_port_chdr_ctba_insert(header, port->ctba_mem[slot].paddr);
+
+    uint8_t command = write ? ATA_CMD_WRITE_DMA_EXT : ATA_CMD_READ_DMA_EXT;
+    assert(buffer->bytes % 512 == 0);
+    uint16_t sectors = buffer->bytes / 512;
+
+    struct command_table* ct = port->command_table[slot];
+    struct sata_fis_reg_h2d fis;
+    sata_h2d_fis_new(&fis, command, block, sectors);
+    command_table_set_cfis(ct, &fis);
+    ct->prdt[0] = region_descriptor_new(buffer->paddr, (buffer->bytes - 1) | 0x1, false);
+
+    while (!ahci_port_is_ready(&port->port)) {
+        // TODO: Abort return error on timeout
+    }
+
+    // Issue command in slot 0
+    ahci_port_ci_wr(&port->port, 1 << slot);
+
+    BLK_DEBUG("Issued DMA command (w=%d) block=%zu.\n", write, block);
+    while ((ahci_port_ci_rd(&port->port) & (1<<slot)) > 0) {
+        // TODO: abort on timeout
+        barrelfish_usleep(10000);
+    }
+
+    BLK_DEBUG("Done with DMA command.\n");
+    // Clear expected interrupt:
+    ahci_port_is_dhrs_wrf(&port->port, 0x1);
+
+    if (ahci_port_is_rd(&port->port) != 0x0) {
+#if defined(BLK_DEBUG_ENABLE)
+        char buf[4096];
+        ahci_port_is_pr(buf, 4096, &port->port);
+        BLK_DEBUG("GOT unhandled IRQ: %u\n", ahci_port_is_rd(&port->port));
+        puts(buf);
+#endif
+    }
+
+    printf("%s:%s:%d: write? %d %zu\n", __FILE__, __FUNCTION__, __LINE__, write, ((uint64_t*)buffer->vaddr)[0]);
+    return err;
+}
+
+static errval_t port_identify(struct ahci_port *port)
+{
+    // TODO: this function needs proper error handling
+    errval_t err = SYS_ERR_OK;
+    assert(ahci_port_slot_free(&port->port, 1));
+
+    err = dma_mem_alloc(512, &port->identify_mem);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "dma memory allocation failed.");
+    }
+    memset((void*)port->identify_mem.vaddr, 0, 512);
+
+    // Write command into command list
+    ahci_port_chdr_t header = get_command_header(port, 0);
+    memset(header, 0, ahci_port_chdr_size);
+    ahci_port_chdr_w_insert(header, 0);
+    ahci_port_chdr_a_insert(header, 0);
+    ahci_port_chdr_cfl_insert(header, sizeof(struct sata_fis_reg_h2d) / sizeof(uint32_t));
+    ahci_port_chdr_prdtl_insert(header, 1); // we use 1 PRD
+    ahci_port_chdr_ctba_insert(header, port->ctba_mem[0].paddr);
+
+    struct command_table* ct = port->command_table[0];
+
+    struct sata_fis_reg_h2d fis;
+    memset(&fis, 0, sizeof(struct sata_fis_reg_h2d));
+    fis.type = SATA_FIS_TYPE_H2D;
+    fis.command = 0xEC; // ATA_CMD_IDENTIFY
+    fis.device = 0;
+    fis.specialstuff = 0x80; // Command
+    command_table_set_cfis(ct, &fis);
+
+    ct->prdt[0] = region_descriptor_new(port->identify_mem.paddr, 511, false);
+
+    while (!ahci_port_is_ready(&port->port)) {}
+
+    // Ensure command processing is on
+    ahci_port_cmd_t cmd = ahci_port_cmd_rd(&port->port);
+    assert(ahci_port_cmd_cr_extract(cmd) == 1);
+
+    // Issue command in slot 0
+    ahci_port_ci_wr(&port->port, 0x1);
+
+    BLK_DEBUG("Issued IDENTIFY command.\n");
+    while ((ahci_port_ci_rd(&port->port) & 0x1) > 0) {
+        // TODO: abort on timeout
+        barrelfish_usleep(10000);
+    }
+
+    // Clear the interrupts
+    ahci_port_is_pss_wrf(&port->port, 0x1);
+
+    // Nothing else should've happened:
+    if (ahci_port_is_rd(&port->port) != 0x0) {
+#if defined(BLK_DEBUG_ENABLE)
+        char buf[4096];
+        ahci_port_is_pr(buf, 4096, &port->port);
+        BLK_DEBUG("GOT unhandled IRQ: %u\n", ahci_port_is_rd(&port->port));
+        puts(buf);
+#endif
+    }
+    assert(ahci_port_is_rd(&port->port) == 0x0);
+
+    BLK_DEBUG("IDENTIFY command processed.\n");
+    ata_identify_initialize(&port->identify, (mackerel_addr_t)port->identify_mem.vaddr);
+
+#if defined(BLK_DEBUG_ENABLE)
+    ahci_port_print_identification(&port->identify);
+#endif
+    return err;
+}
+
+errval_t blk_ahci_ports_init(struct ahci_disk *ad)
+{
+    errval_t err = SYS_ERR_OK;
+    size_t ports = ahci_hba_get_num_ports(&ad->controller);
+    size_t ncs = ahci_hba_cap_ncs_rdf(&ad->controller);
+    BLK_DEBUG("Implemented ports: %zu\n", ports);
+    BLK_DEBUG("Implemented command slots: %zu\n", ncs);
+
+    lvaddr_t base_address = blk_ahci_get_bar5_vaddr(ad);
+
+    // Determine which ports are implemented by the HBA, by reading the PI register. This bit
+    // map value will aid software in determining how many ports are available and which port
+    // registers need to be initialized.
+    for (size_t i = 0; i < ports; i++) {
+        struct ahci_port *port = &ad->ports[i];
+        if (!ahci_port_is_implemented(&ad->controller, i)) {
+            continue;
+        }
+        ahci_port_initialize(&port->port, (mackerel_addr_t)base_address + ahci_port_offset(i));
+
+        BLK_DEBUG("Initializing port: %zu\n", i);
+        uint32_t probe = ahci_port_probe(&port->port);
+        if (probe == 0) {
+            BLK_DEBUG("Port %zu no connection\n", i);
+            continue;
+        }
+        else if (probe == 0x00000101) {
+            BLK_DEBUG("Port %zu found SATA device, initializing.\n", i);
+        }
+        else {
+            BLK_DEBUG("Port %zu unkown signature: %d\n", i, ahci_port_sig_rd(&port->port));
+            continue;
+        }
+
+        // Ensure that the controller is not in the running state by reading and examining each
+        // implemented port’s PxCMD register. If PxCMD.ST, PxCMD.CR, PxCMD.FRE and
+        // PxCMD.FR are all cleared, the port is in an idle state.
+        if (!ahci_port_is_idle(&port->port)) {
+            BLK_DEBUG("Port %zu is running, stopping it.", i);
+            ahci_port_stop(&port->port);
+        }
+        assert(ahci_port_is_idle(&port->port)); // if this triggers, try a port reset...
+
+        // For each implemented port, system software shall allocate memory for and program:
+        //  - PxCLB and PxCLBU
+        //  - PxFB and PxFBU
+        port_init_clb(port);
+        port_init_fb(port);
+
+        // After setting PxFB and PxFBU to the physical address of the FIS receive area,
+        // system software shall set PxCMD.FRE to ‘1’.
+        ahci_port_cmd_fre_wrf(&port->port, 0x1);
+
+        // For each implemented port, clear the PxSERR register, by writing ‘1s’ to each bit location.
+        uint32_t serr = ahci_port_serr_rd(&port->port);
+        ahci_port_serr_wr(&port->port, serr);
+
+        // Determine which events should cause an interrupt, and set each implemented port’s PxIE
+        ahci_port_ie_wr(&port->port, 0xffffffff);
+
+        assert(ncs < MAX_CTBA_SLOTS);
+        for (size_t slot = 0; slot < ncs; slot++) {
+            port_init_ctba(port, slot);
+        }
+
+        BLK_DEBUG("Waiting for port %zu to become ready\n", i);
+        while(!ahci_port_is_functional(&port->port)) {
+            barrelfish_usleep(5000);
+        }
+        ahci_port_start(&port->port);
+
+        BLK_DEBUG("Initialized port %zu\n", i);
+        err = port_identify(port);
+        assert(err_is_ok(err));
+
+        port->ncs = ahci_hba_get_command_slots(&ad->controller);
+        port->interrupt = blk_ahci_interrupt;
+        port->is_initialized = true;
+    }
+
+    return err;
+}
diff --git a/lib/blk/blk_ahci/blk_ahci.h b/lib/blk/blk_ahci/blk_ahci.h
new file mode 100644 (file)
index 0000000..00396b6
--- /dev/null
@@ -0,0 +1,110 @@
+
+/*
+ * Copyright (c) 2016, 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef _BLK_AHCI_
+#define _BLK_AHCI_
+
+#include <barrelfish/barrelfish.h>
+#include <pci/mem.h>
+#include <blk/ahci.h>
+#include <devif/queue.h>
+
+#include <dev/ahci_hba_dev.h>
+#include <dev/ahci_port_dev.h>
+#include <dev/ata_identify_dev.h>
+
+#include "../dma_mem/dma_mem.h"
+
+#define MAX_AHCI_PORTS 32
+#define MAX_CTBA_SLOTS 32
+
+#define MAX_HBA 32
+#define MAX_BUFFERS 256
+#define MAX_REQUESTS MAX_CTBA_SLOTS
+
+struct __attribute__((__packed__)) region_descriptor {
+    /// Data base address
+    uint64_t dba;
+    uint32_t reserved;
+    /// Byte count and Interrupt bit (31)
+    uint32_t dbc;
+};
+
+struct __attribute__((__packed__)) command_table {
+    /// Command FIS
+    uint8_t cfis[64];
+    /// ATAPI command
+    uint8_t acmd[16];
+    uint8_t reserved[48];
+    /// Physical Descriptior Region Table entries
+    /// Can be up to 65536 entries, we limit this to 248 for now
+    /// (which limits the size of CommandTable to a single page).
+    struct region_descriptor prdt[248];
+};
+
+
+struct ahci_port;
+struct dev_queue;
+typedef void (*ahci_port_interrupt_handler_fn)(struct ahci_port*, struct dev_queue*);
+
+struct ahci_port {
+    bool is_initialized; //< Port is up and running, ready to read/write.
+    ahci_port_t port;
+    struct dma_mem fb;
+    struct dma_mem clb;
+    struct dma_mem ctba_mem[MAX_CTBA_SLOTS];
+    struct command_table* command_table[MAX_CTBA_SLOTS]; //< Points to ctba_mem[i].vaddr
+    size_t ncs; //< Number of command slots actually implemented
+    ahci_port_interrupt_handler_fn interrupt;
+    struct ahci_mgmt_binding *binding;
+    struct dma_mem identify_mem;
+    ata_identify_t identify; //< Points to identify_mem.vaddr, valid after port_identify() is done.
+};
+
+struct ahci_disk {
+    struct device_mem* bar5;
+    ahci_hba_t controller;
+    struct ahci_port ports[MAX_AHCI_PORTS];
+};
+
+
+enum RequestStatus {
+    RequestStatus_Unused = 0,
+    RequestStatus_InProgress = 1,
+    RequestStatus_Done = 2
+};
+
+struct dev_queue_request {
+    regionid_t region_id;
+    struct dma_mem region;
+    uint64_t command_slot;
+
+    lpaddr_t base;
+    size_t length;
+    bufferid_t buffer_id;
+
+    errval_t error;
+    enum RequestStatus status;
+};
+
+struct dev_queue {
+    struct ahci_port* port;
+    struct dma_mem buffers[MAX_BUFFERS];
+    struct dev_queue_request requests[MAX_REQUESTS];
+};
+
+/* ahci_port_init.h */
+errval_t blk_ahci_ports_init(struct ahci_disk *ad);
+errval_t blk_ahci_port_dma(struct ahci_port *port, uint64_t block, struct dma_mem *buffer, bool write);
+errval_t blk_ahci_port_dma_async(struct ahci_port *port, size_t slot, uint64_t block, lpaddr_t base, size_t length, bool write);
+
+lvaddr_t blk_ahci_get_bar5_vaddr(struct ahci_disk* ad);
+
+#endif // _BLK_AHCI_
diff --git a/lib/blk/blk_ahci/device_impl.c b/lib/blk/blk_ahci/device_impl.c
new file mode 100644 (file)
index 0000000..67f864e
--- /dev/null
@@ -0,0 +1,237 @@
+#include <barrelfish/barrelfish.h>
+#include <assert.h>
+#include <devif/queue.h>
+
+#include "blk_ahci.h"
+#include "ahci_dev.h" // TODO: get rid of this include
+#include "../dma_mem/dma_mem.h"
+#include "../blk_debug.h"
+
+static bool is_valid_buffer(struct dev_queue* dq, size_t slot)
+{
+    return !capref_is_null(dq->buffers[slot].frame);
+}
+
+static errval_t request_slot_alloc(struct dev_queue* dq, size_t* slot)
+{
+    assert(dq->port->ncs <= MAX_REQUESTS);
+
+    for (size_t i=0; i < dq->port->ncs; i++) {
+        struct dev_queue_request *dqr = &dq->requests[i];
+        if (dqr->status == RequestStatus_Unused) {
+            dqr->status = RequestStatus_InProgress;
+            *slot = i;
+            return SYS_ERR_OK;
+        }
+    }
+
+    return DEV_ERR_QUEUE_FULL;
+}
+
+static errval_t get_port(struct ahci_disk* hba, size_t port_num, struct ahci_port** p) {
+    assert(hba != NULL);
+    assert(port_num < MAX_AHCI_PORTS);
+    errval_t err = SYS_ERR_OK;
+
+    struct ahci_port* port = &hba->ports[port_num];
+    if (!port->is_initialized) {
+        return err_push(err, DEV_ERR_NOT_INITIALIZED);
+    }
+
+    *p = port;
+    return SYS_ERR_OK;
+}
+
+static errval_t init_queue(struct dev_queue** dq, struct ahci_port *port) {
+    struct dev_queue* queue = calloc(1, sizeof(struct dev_queue));
+    if (dq == NULL) {
+        return LIB_ERR_MALLOC_FAIL;
+    }
+
+    queue->port = port;
+    for (size_t i = 0; i< MAX_BUFFERS; i++) {
+        queue->buffers[i].frame = NULL_CAP;
+    }
+
+    *dq = queue;
+    return SYS_ERR_OK;
+}
+
+static bool slice_is_in_range(struct dma_mem *mem, lpaddr_t base, size_t length)
+{
+    bool lower_bound = mem->paddr <= base;
+    bool upper_bound = mem->paddr+mem->bytes >= base+length;
+
+    return lower_bound && upper_bound;
+}
+
+static uint64_t flags_get_block(uint64_t flags)
+{
+    return flags & ((1ULL<<49) - 1);
+}
+
+static bool flags_is_write(uint64_t flags) {
+    return (flags & (1ULL << 63)) > 0;
+}
+
+void devq_interrupt_handler(void* q);
+void devq_interrupt_handler(void* q)
+{
+    if (q == NULL) {
+        BLK_DEBUG("Ignored interrupt, device not yet initialized?\n");
+        return;
+    }
+    struct dev_queue *queue = q;
+    struct ahci_port *port = queue->port;
+
+    assert(port->interrupt != NULL);
+    port->interrupt(port, queue);
+}
+
+errval_t devq_create(void* st, char *device_name, uint64_t flags, void **queue)
+{
+    errval_t err = SYS_ERR_OK;
+
+    struct ahci_port* port;
+    err = get_port(st, flags, &port);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    struct dev_queue *dq;
+    err = init_queue(&dq, port);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    *queue = dq;
+
+    return err;
+}
+
+errval_t devq_destroy(void *qp)
+{
+    struct dev_queue *queue = qp;
+
+    // TODO: Wait for stuff to finish...!
+
+    // Clean-up memory:
+    for (size_t i = 0; i< MAX_BUFFERS; i++) {
+        dma_mem_free(&queue->buffers[i]);
+    }
+    free(qp);
+    return SYS_ERR_OK;
+}
+
+errval_t devq_enqueue(void *q, regionid_t region_id, lpaddr_t base, size_t length, bufferid_t buffer_id, uint64_t flags)
+{
+    struct dev_queue *queue = q;
+    assert(region_id < MAX_BUFFERS);
+    assert(is_valid_buffer(queue, region_id));
+    assert(base != 0);
+    assert(length >= 512);
+
+    struct dma_mem* mem = &queue->buffers[region_id];
+
+    if (!slice_is_in_range(mem, base, length)) {
+        return DEV_ERR_INVALID_BUFFER_ARGS;
+    }
+
+    size_t slot;
+    errval_t err = request_slot_alloc(queue, &slot);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    struct dev_queue_request *dqr = &queue->requests[slot];
+    dqr->status = RequestStatus_InProgress;
+    dqr->buffer_id = buffer_id;
+    dqr->base = base;
+    dqr->length = length;
+    dqr->region_id = region_id;
+    dqr->command_slot = slot;
+
+    uint64_t block = flags_get_block(flags);
+    bool write = flags_is_write(flags);
+    return blk_ahci_port_dma_async(queue->port, slot, block, base, length, write);
+}
+
+errval_t devq_dequeue(void *q,
+                      regionid_t* region_id,
+                      lpaddr_t* base,
+                      size_t* length,
+                      bufferid_t* buffer_id)
+{
+    assert(q != NULL);
+    assert(region_id != NULL);
+    assert(base != NULL);
+    assert(length != NULL);
+    assert(length != NULL);
+
+    struct dev_queue *queue = q;
+
+    for (size_t i=0; i<queue->port->ncs; i++) {
+        struct dev_queue_request *dqr = &queue->requests[i];
+        if (dqr->status == RequestStatus_Done) {
+            *base = dqr->base;
+            *length = dqr->length;
+            *buffer_id = dqr->buffer_id;
+            *region_id = dqr->region_id;
+
+            dqr->status = RequestStatus_Unused;
+            return dqr->error;
+        }
+    }
+
+    return DEV_ERR_QUEUE_EMPTY;
+}
+
+errval_t devq_register(void *q,
+                       struct capref cap,
+                       regionid_t* region_id)
+{
+    errval_t err = DEV_ERR_REGISTER_BUFFER;
+    assert(!capref_is_null(cap));
+    struct dev_queue *queue = q;
+
+    for (size_t i=0; i<MAX_BUFFERS; i++) {
+        if (is_valid_buffer(q, i)) {
+            printf("Don't overwrite existing buffer\n");
+            continue;
+        }
+
+        struct dma_mem* mem = &queue->buffers[i];
+        err = dma_mem_from_capref(cap, mem);
+        if (err_is_fail(err)) {
+            DEBUG_ERR(err, "call failed");
+            return err_push(err, DEV_ERR_REGISTER_BUFFER);
+        }
+
+        *region_id = i;
+        return SYS_ERR_OK;
+    }
+
+    return err;
+}
+
+errval_t devq_remove(void *q, regionid_t region_id)
+{
+    assert(region_id < MAX_BUFFERS);
+    assert(q != NULL);
+    struct dev_queue *queue = q;
+
+    struct dma_mem* mem = &queue->buffers[region_id];
+    assert(!capref_is_null(mem->frame));
+
+    return dma_mem_free(mem);
+}
+
+errval_t devq_sync(void *q)
+{
+    return SYS_ERR_OK;
+}
+
+errval_t devq_control(void *q, uint64_t request, uint64_t value)
+{
+    return SYS_ERR_OK;
+}
diff --git a/lib/blk/blk_ahci/sata_fis.c b/lib/blk/blk_ahci/sata_fis.c
new file mode 100644 (file)
index 0000000..fff051c
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2011 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 <stdlib.h>
+#include <errors/errno.h>
+#include "sata_fis.h"
+
+void sata_h2d_fis_new(struct sata_fis_reg_h2d* fis, uint8_t command, uint64_t lba, uint16_t sectors)
+{
+    sata_h2d_fis_init(fis);
+    sata_h2d_set_command(fis, command);
+    sata_h2d_set_lba48(fis, lba);
+    sata_h2d_set_count(fis, sectors);
+}
+
+void sata_h2d_fis_init(struct sata_fis_reg_h2d* fis)
+{
+    fis->type = SATA_FIS_TYPE_H2D;
+
+    /* Device Shadow Register layout (see: [1])
+     * [  7  |  6  |  5  |  4  |  3  |  2  |  1  |  0  ]
+     * [  -  |  L  |  -  | DEV | HS3 | HS2 | HS1 | HS0 ]
+     *
+     * L is the address mode, cleared implies CHS addressing, set, LBA addressing
+     * DEV device select, cleared and set imply Device 0 and 1 resp.
+     *   for SATA this should always be cleared (see: [2])
+     * HS3-HS0 are bits 28-25 of the LBA 28 (not used for LBA 48, see [3])
+     *
+     * [1] Serial ATA NSSD Rev. 1.0 (Sept 2008), section 6.3.1
+     * [2] Serial ATA Rev. 2.6 (15-February-2007), section 13.1, paragraph 2
+     * [3] ATA8-ACS Rev. 3f (December 11, 2006), section 7.1.5.2
+     */
+    fis->device |= (1 << 6);
+}
+
+void sata_h2d_set_command(struct sata_fis_reg_h2d* fis, uint8_t command)
+{
+    fis->command = command;
+    /* set bit to indicate update of command register (see [1])
+     *
+     * [1]: SATA Rev. 2.6 (15-February-2007), section 10.3.4
+     */
+    fis->specialstuff |= (1 << 7);
+}
+
+void sata_h2d_set_feature(struct sata_fis_reg_h2d* fis, uint8_t feature)
+{
+    fis->feature = feature;
+}
+
+void sata_h2d_set_lba28(struct sata_fis_reg_h2d* fis, uint32_t lba)
+{
+    fis->lba0 = lba & 0xFF;
+    fis->lba1 = (lba >> 8) & 0xFF;
+    fis->lba2 = (lba >> 16) & 0xFF;
+    fis->device = (fis->device & ~0x0F) | ((lba >> 24) & 0x0F);
+}
+
+void sata_h2d_set_lba48(struct sata_fis_reg_h2d* fis, uint64_t lba)
+{
+    fis->lba0 = lba & 0xFF;
+    fis->lba1 = (lba >> 8) & 0xFF;
+    fis->lba2 = (lba >> 16) & 0xFF;
+    fis->device &= 0xF0; // clear bits otherwise used by lba28
+
+    fis->lba3 = (lba >> 24) & 0xFF;
+    fis->lba4 = (lba >> 32) & 0xFF;
+    fis->lba5 = (lba >> 40) & 0xFF;
+}
+
+void sata_h2d_set_count(struct sata_fis_reg_h2d* fis, uint16_t count)
+{
+    fis->countl = count & 0xFF;
+    fis->counth = (count >> 8) & 0xFF;
+}
diff --git a/lib/blk/blk_ahci/sata_fis.h b/lib/blk/blk_ahci/sata_fis.h
new file mode 100644 (file)
index 0000000..07896d8
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2011 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.
+ */
+
+#ifndef _AHCI_SATA_FIS_H
+#define _AHCI_SATA_FIS_H
+
+#include <stdint.h>
+
+#define SATA_FIS_TYPE_H2D      0x27 // Register FIS - Host to Device
+#define SATA_FIS_TYPE_D2H      0x34 // Register FIS - Device to Host
+#define SATA_FIS_TYPE_DMAA     0x39 // DMA Activate FIS - Device to Host
+#define SATA_FIS_TYPE_DMAS     0x41 // DMA Setup FIS - Bi-directional
+#define SATA_FIS_TYPE_DATA     0x46 // Data FIS - Bi-directional
+#define SATA_FIS_TYPE_BIST     0x58 // BIST Activate FIS - Bi-directional
+#define SATA_FIS_TYPE_PIO      0x5F // PIO Setup FIS - Device to Host
+#define SATA_FIS_TYPE_SDB      0xA1 // Set Device Bits FIS - Device to Host
+
+#define ATA_CMD_READ_PIO          0x20
+#define ATA_CMD_READ_PIO_EXT      0x24
+#define ATA_CMD_READ_DMA          0xC8
+#define ATA_CMD_READ_DMA_EXT      0x25
+#define ATA_CMD_WRITE_PIO         0x30
+#define ATA_CMD_WRITE_PIO_EXT     0x34
+#define ATA_CMD_WRITE_DMA         0xCA
+#define ATA_CMD_WRITE_DMA_EXT     0x35
+#define ATA_CMD_CACHE_FLUSH       0xE7
+#define ATA_CMD_CACHE_FLUSH_EXT   0xEA
+#define ATA_CMD_PACKET            0xA0
+#define ATA_CMD_IDENTIFY_PACKET   0xA1
+#define ATA_CMD_IDENTIFY          0xEC
+
+struct sata_fis_reg_h2d {
+       unsigned char type;
+       unsigned char specialstuff;
+       unsigned char command;
+       unsigned char feature;
+
+       unsigned char lba0;
+       unsigned char lba1;
+       unsigned char lba2;
+       unsigned char device;
+
+       unsigned char lba3;
+       unsigned char lba4;
+       unsigned char lba5;
+       unsigned char featureh;
+
+       unsigned char countl;
+       unsigned char counth;
+       unsigned char icc;
+       unsigned char control;
+
+       unsigned char reserved[4];
+};
+
+struct sata_fis_reg_d2h {
+       unsigned char type;
+       unsigned char specialstuff;
+       unsigned char status;
+       unsigned char error;
+
+       unsigned char lba0;
+       unsigned char lba1;
+       unsigned char lba2;
+       unsigned char device;
+
+       unsigned char lba3;
+       unsigned char lba4;
+       unsigned char lba5;
+       unsigned char reserved;
+
+       unsigned char countl;
+       unsigned char counth;
+       unsigned char reserved2[2];
+
+       unsigned char reserved3[4];
+};
+
+
+void sata_h2d_fis_new(struct sata_fis_reg_h2d* fis, uint8_t command, uint64_t lba, uint16_t sectors);
+void sata_h2d_fis_init(struct sata_fis_reg_h2d* fis);
+void sata_h2d_set_command(struct sata_fis_reg_h2d* fis, uint8_t command);
+void sata_h2d_set_feature(struct sata_fis_reg_h2d* fis, uint8_t feature);
+void sata_h2d_set_lba28(struct sata_fis_reg_h2d* fis, uint32_t lba);
+void sata_h2d_set_lba48(struct sata_fis_reg_h2d* fis, uint64_t lba);
+void sata_h2d_set_count(struct sata_fis_reg_h2d* fis, uint16_t count);
+
+
+#endif // _AHCI_SATA_FIS_H
diff --git a/lib/blk/blk_debug.h b/lib/blk/blk_debug.h
new file mode 100644 (file)
index 0000000..a3aea1e
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef BLK_DEBUG_H_
+#define BLK_DEBUG_H_
+
+//#define BLK_DEBUG_ENABLE 1
+
+#if defined(BLK_DEBUG_ENABLE) || defined(GLOBAL_DEBUG)
+#define BLK_DEBUG(x...) printf("BLK: " x)
+#else
+#define BLK_DEBUG(x...) ((void)0)
+#endif
+
+#endif
diff --git a/lib/blk/dma_mem/dma_mem.c b/lib/blk/dma_mem/dma_mem.c
new file mode 100644 (file)
index 0000000..2412b96
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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 "dma_mem.h"
+
+errval_t dma_mem_from_capref(struct capref frame, struct dma_mem *mem)
+{
+    errval_t err = SYS_ERR_OK;
+    if (mem == NULL) {
+        return DMA_ERR_ARG_INVALID;
+    }
+
+    struct frame_identity id;
+    err = invoke_frame_identify(frame, &id);
+    if (err_is_fail(err)) {
+        DEBUG_ERR(err, "invoke frame id");
+        return err;
+    }
+
+    mem->paddr = id.base;
+    mem->bytes = id.bytes;
+    mem->requested = id.bytes;
+    mem->frame = frame;
+
+    void *addr;
+    err = vspace_map_one_frame_attr(&addr, mem->bytes, mem->frame, VREGION_FLAGS_READ_WRITE,
+                                    NULL, NULL);
+    if (err_is_fail(err)) {
+        dma_mem_free(mem);
+        return err;
+    }
+
+    mem->vaddr = (lvaddr_t)addr;
+
+    return SYS_ERR_OK;
+}
+
+/**
+ * \brief allocates and maps a memory region to be used for DMA purposes
+ *
+ * \param bytes minimum size of the memory region in bytes
+ * \param flags VREGION flags how the region gets mapped
+ * \param mem   returns the mapping information
+ *
+ * \returns SYS_ERR_OK on success
+ *          errval on error
+ */
+errval_t dma_mem_alloc(size_t bytes, struct dma_mem *mem)
+{
+    errval_t err = SYS_ERR_OK;
+    mem->requested = bytes;
+    bytes = ROUND_UP(BASE_PAGE_SIZE, bytes);
+
+    if (mem == NULL) {
+        return DMA_ERR_ARG_INVALID;
+    }
+
+    err = frame_alloc(&mem->frame, bytes, &mem->bytes);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    struct frame_identity id;
+    err = invoke_frame_identify(mem->frame, &id);
+    if (err_is_fail(err)) {
+        dma_mem_free(mem);
+        return err;
+    }
+
+    mem->paddr = id.base;
+
+    void *addr;
+    err = vspace_map_one_frame_attr(&addr, mem->bytes, mem->frame, VREGION_FLAGS_READ_WRITE,
+                                    NULL, NULL);
+    if (err_is_fail(err)) {
+        dma_mem_free(mem);
+        return err;
+    }
+
+    mem->vaddr = (lvaddr_t)addr;
+
+    return SYS_ERR_OK;
+}
+
+/**
+ * \brief tries to free the allocated memory region
+ *
+ * \returns SYS_ERR_OK on success
+ *          errval on error
+ */
+errval_t dma_mem_free(struct dma_mem *mem)
+{
+    errval_t err;
+
+    if (mem->vaddr) {
+        err = vspace_unmap((void*)mem->vaddr);
+        if (err_is_fail(err)) {
+            USER_PANIC_ERR(err, "call failed.");
+        }
+    }
+
+    if (!capref_is_null(mem->frame)) {
+        err = cap_destroy(mem->frame);
+        if (err_is_fail(err)) {
+            if (err_is_fail(err)) {
+                USER_PANIC_ERR(err, "call failed.");
+            }
+        }
+    }
+
+    memset(mem, 0, sizeof(*mem));
+
+    return SYS_ERR_OK;
+}
diff --git a/lib/blk/dma_mem/dma_mem.h b/lib/blk/dma_mem/dma_mem.h
new file mode 100644 (file)
index 0000000..26f0350
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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 LIB_DMA_MEM_UTILS_H
+#define LIB_DMA_MEM_UTILS_H
+
+#include <barrelfish/types.h>
+#include <barrelfish/capabilities.h>
+
+struct dma_mem
+{
+    lvaddr_t vaddr;         ///< virtual address of the mapped region
+    lpaddr_t paddr;         ///< physical address of the underlying frame
+    uint64_t bytes;         ///< size of the region in bytes
+    uint64_t requested;     ///< requested size of the region in bytes (<= bytes)
+    struct capref frame;    ///< frame capability backing this region
+};
+
+/**
+ * \brief allocates and maps a memory region to be used for DMA purposes
+ *
+ * \param bytes minimum size of the memory region in bytes
+ * \param mem   returns the mapping information
+ *
+  * \returns SYS_ERR_OK on success
+ *          errval on error
+ */
+errval_t dma_mem_alloc(size_t bytes, struct dma_mem *mem);
+
+/**
+ * \brief Initializes a dma_mem struct for a given capref
+ *
+ * \param frame The frame with a reference to memory
+ *
+ * \returns SYS_ERR_OK on success
+ *          errval on error
+ */
+errval_t dma_mem_from_capref(struct capref frame, struct dma_mem *mem);
+
+/**
+ * \brief tries to free the allocated memory region
+ *
+ * \returns SYS_ERR_OK on success
+ *          errval on error
+ */
+errval_t dma_mem_free(struct dma_mem *mem);
+
+
+
+#endif /* LIB_DMA_MEM_UTILS_H */
index 875b18c..2cce41d 100644 (file)
@@ -14,8 +14,8 @@
 
 #include <asmoffsets.h>
     .syntax unified
-       .text
-       .globl  _start, _start_init
+    .text
+    .globl  _start, _start_init
 
 _start:
         // Entry for processes other than init
@@ -25,8 +25,8 @@ _start:
 
 _start_generic:
         ldr     sp, =crt0_temp_stack
-           // Call barrelfish_init_disabled(struct dispatcher* d, bool init_dom_arg)
-           b   barrelfish_init_disabled
+        // Call barrelfish_init_disabled(struct dispatcher* d, bool init_dom_arg)
+        b    barrelfish_init_disabled
 
 _start_init:
         // Entry for the init process
@@ -35,16 +35,6 @@ _start_init:
         mov     r1, #1
         b       _start_generic
 
-        // TODO: Remove. These are temporary kludges. It looks as though
-        // We need to build own libgcc to avoid these.
-        .globl __aeabi_unwind_cpp_pr0
-        .globl __aeabi_unwind_cpp_pr1
-        .globl raise
-
-raise:
-__aeabi_unwind_cpp_pr0:
-__aeabi_unwind_cpp_pr1:
-        bl      abort
 
 .section ".bss"
 crt0_temp_stack_base:
index 68f7892..6cc9beb 100644 (file)
@@ -375,7 +375,8 @@ static errval_t chunk_node(struct mm *mm, uint8_t sizebits,
 
     // retype node into 2^(maxchildbits) smaller nodes
     DEBUG("retype: current size: %zu, child size: %zu, count: %u\n",
-          1UL << *nodesizebits, 1UL << (*nodesizebits - childbits), UNBITS_CA(childbits));
+          (size_t)1 << *nodesizebits, (size_t)1  << (*nodesizebits - childbits),
+          UNBITS_CA(childbits));
     err = cap_retype(cap, node->cap, 0, mm->objtype,
                      1UL << (*nodesizebits - childbits),
                      UNBITS_CA(childbits));
@@ -447,12 +448,15 @@ static errval_t chunk_node(struct mm *mm, uint8_t sizebits,
  */
 void mm_debug_print(struct mmnode *mmnode, int space)
 {
+    if (!mmnode) {
+        return;
+    }
     for(int i = 0; i < space; i++) {
         printf("  ");
     }
     printf("%d. type %d, children %d\n",
            space, mmnode->type, 1<<mmnode->childbits);
-    if (mmnode->type == NodeType_Chunked) {
+    if ((mmnode->type == NodeType_Chunked) || (mmnode->type == NodeType_Dummy)) {
         for(int i = 0; i < (1<<mmnode->childbits); i++) {
             mm_debug_print(mmnode->children[i], space + 1);
         }
@@ -579,7 +583,8 @@ errval_t mm_add(struct mm *mm, struct capref cap, uint8_t sizebits, genpaddr_t b
  */
 errval_t mm_add_multi(struct mm *mm, struct capref cap, gensize_t size, genpaddr_t base)
 {
-    DEBUG("%s: mm=%p, base=%#"PRIxGENPADDR", bytes=%zu\n", __FUNCTION__, mm, base, size);
+    DEBUG("%s: mm=%p, base=%#"PRIxGENPADDR", bytes=%" PRIuGENSIZE "\n",
+          __FUNCTION__, mm, base, size);
     gensize_t offset = 0;
     errval_t err;
     size_t rcount = 0;
index 00ac28c..85a8ed9 100644 (file)
@@ -22,6 +22,7 @@
 #include <pci/pci_client_debug.h>
 #include <if/pci_defs.h>
 #include <if/pci_rpcclient_defs.h>
+#include <if/acpi_rpcclient_defs.h>
 #include <acpi_client/acpi_client.h>
 
 #define INVALID_VECTOR ((uint32_t)-1)
@@ -188,7 +189,10 @@ errval_t pci_register_driver_movable_irq(pci_driver_init_fn init_func, uint32_t
                 bar->frame_cap[nc] = cap;
                 if (nc == 0) {
                     struct frame_identity id = { .base = 0, .bytes = 0 };
-                    invoke_frame_identify(cap, &id);
+                    err = invoke_frame_identify(cap, &id);
+                    if (err_is_fail(err)) {
+                        USER_PANIC_ERR(err, "frame identify failed.");
+                    }
                     bar->paddr = id.base;
                     bar->bits = log2ceil(id.bytes);
                     bar->bytes = id.bytes * ncaps;
@@ -205,6 +209,7 @@ errval_t pci_register_driver_movable_irq(pci_driver_init_fn init_func, uint32_t
     }
 
     // initialize the device. We have all the caps now
+    PCI_CLIENT_DEBUG("Succesfully done with pci init.\n");
     init_func(bars, nbars);
 
     err = SYS_ERR_OK;
index ffa08e9..e22b48a 100644 (file)
@@ -378,7 +378,9 @@ let bin_rcce_lu = [ "/sbin/" ++ f | f <- [
                     Out "root" image,
                     NoDep BuildTree "root" "/",
                     Str physBase ] ++
-                    [ (Dep BuildTree "armv7" m) | m <- modules ]),
+                    [ (Dep BuildTree "armv7" m) | m <- modules ] ++ 
+                    [ (Dep BuildTree "" m) | m <- modules_generic ] ),
+
             Rule ([ Str Config.arm_objcopy,
                     Str "-O binary",
                     In BuildTree "root" image,
index 773bbe7..3368623 100644 (file)
@@ -125,12 +125,16 @@ def default_bootmodules(build, machine):
     m.add_module("%s/sbin/skb" % a, ["boot"])
     m.add_module("%s/sbin/spawnd" % a, ["boot"])
     m.add_module("%s/sbin/startd" % a, ["boot"])
+    m.add_module("/eclipseclp_ramfs.cpio.gz", ["nospawn"])
+    m.add_module("/skb_ramfs.cpio.gz", ["nospawn"])
+
+    # armv8
+    if a == "armv8" :
+        m.add_module("%s/sbin/acpi" % a, ["boot"])
 
     # SKB and PCI are x86-only for the moment
     if a == "x86_64" or a == "x86_32":
         m.add_module("%s/sbin/acpi" % a, ["boot"])
-        m.add_module("/eclipseclp_ramfs.cpio.gz", ["nospawn"])
-        m.add_module("/skb_ramfs.cpio.gz", ["nospawn"])
         m.add_module("%s/sbin/routing_setup" %a, ["boot"])
         m.add_module("%s/sbin/corectrl" % a, ["auto"])
 
@@ -140,7 +144,8 @@ def default_bootmodules(build, machine):
 
         if machine.name == "sbrinz1" or machine.name == "sbrinz2" \
         or machine.name == "tomme1" or machine.name == "tomme2" \
-        or machine.name == "appenzeller" or is_babybel == 1 :
+        or machine.name == "tilsiter1" or machine.name == "appenzeller" \
+        or is_babybel == 1:
             # PCI allocation broken, use BIOS plan
             m.add_module("%s/sbin/pci" % a, ["auto",
                                              "skb_bridge_program=bridge_bios"] + machine.get_pci_args())
index deeb5dd..7502503 100755 (executable)
@@ -129,7 +129,7 @@ def process_results(test, path):
         except NotImplementedError:
             passed = None
         if passed is False:
-            debug.log('Test %s FAILED' % test.name)
+            debug.log('Test %s FAILED %s' % (test.name, '(' + result.reason() + ')') )
             retval = False
         elif passed:
             debug.verbose('Test %s PASSED' % test.name)
index bc2090c..873c7e6 100644 (file)
@@ -165,6 +165,15 @@ machines = dict({
                 'xphi_tickrate'   : 1140,
                 'xphi_ram_gb'     : 6},
 
+   'tilsiter1': {'ncores'          : 2,
+                 'machine_name'    : 'tilsiter1',
+                 'bootarch'        : 'x86_64',
+                 'buildarchs'      : ['x86_64'],
+                 'cores_per_socket': 2,
+                 'perfcount_type'  : 'intel',
+                 'tickrate'        : 2500,
+                 'boot_timeout'    : 120},
+
     'nos4-32'   : {'ncores'      : 4,
                    'machine_name' : 'nos4',
                    'bootarch' : 'x86_32',
@@ -261,7 +270,7 @@ machines = dict({
                     'perfcount_type': 'intel',
                     'tickrate'    : 1870,
                     'boot_timeout': 360},
-    
+
     'vacherin-32': {'ncores'      : 4,
                 'machine_name' : 'vacherin',
                 'bootarch' : 'x86_32',
@@ -296,7 +305,6 @@ machines = dict({
                    'perfcount_type'  : 'intel',
                    'tickrate'        : 2500,
                    'boot_timeout'    : 360},
-
     'babybel4-32': {'ncores'          : 20,
                    'machine_name'    : 'babybel4',
                    'bootarch'        : 'x86_32',
@@ -315,7 +323,7 @@ machines = dict({
                    'perfcount_type'  : 'intel',
                    'tickrate'        : 1140,
                    'host_tickrate'   : 2500,
-                   'boot_timeout'    : 360}, 
+                   'boot_timeout'    : 360},
     'xeon_phi_2': {'ncores'          : 64,
                    'nphi'            : 2,
                    'host_ncores'     : 20,
@@ -349,9 +357,9 @@ machines = dict({
                    'tickrate'        : 1140,
                    'host_tickrate'   : 2500,
                    'boot_timeout'    : 360},
-                   
+
     # SK: For Python 2.7
-    # }.items() + { 
+    # }.items() + {
     #     'brie%s' % b: {
     #         'ncores' : 4,
     #         'machine_name' : ('brie%s' % b),
index 3299619..b71c97d 100755 (executable)
@@ -30,7 +30,7 @@ def parse_args():
 
     debug.current_level = options.debuglevel
     return dirs
-            
+
 
 def main(dirs):
     for dirname in dirs:
@@ -60,6 +60,5 @@ def main(dirs):
         debug.verbose('reprocess results')
         harness.process_results(test, dirname)
 
-
 if __name__ == "__main__":
     main(parse_args())
index 015dd03..4a19c21 100644 (file)
 from stats import Stats
 
 class ResultsBase(object):
-    def __init__(self, name=None):
+    def __init__(self, name=None, reason=""):
         self.name = name
+        self.fail_reason = reason
+
+    def reason(self):
+        return self.fail_reason
 
     def passed(self):
         """Returns true iff the test is considered to have passed."""
@@ -24,8 +28,8 @@ class ResultsBase(object):
 
 class PassFailResult(ResultsBase):
     """Stores results of test that is purely pass/fail."""
-    def __init__(self, passed):
-        super(PassFailResult, self).__init__()
+    def __init__(self, passed, reason=""):
+        super(PassFailResult, self).__init__(reason=reason)
         self.passfail = passed
 
     def passed(self):
@@ -37,6 +41,9 @@ class PassFailMultiResult(ResultsBase):
         self.errors = errors
         self.name = name
 
+    def reason(self):
+        return str(errors)
+
     def passed(self):
         return len(self.errors) == 0
 
@@ -66,9 +73,10 @@ class RowResults(ResultsBase):
         for r in self.rows:
             fh.write('\t'.join(map(str, r)) + '\n')
 
-    def mark_failed(self):
+    def mark_failed(self, reason):
         """Mark this test as having failed."""
         self.failed = True
+        self.fail_reason = reason
 
     def add_row(self, row):
         assert(len(row) == len(self.colnames))
diff --git a/tools/harness/tests/blk_tests.py b/tools/harness/tests/blk_tests.py
new file mode 100644 (file)
index 0000000..cff9aac
--- /dev/null
@@ -0,0 +1,334 @@
+##########################################################################
+# Copyright (c) 2016, 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.
+##########################################################################
+
+import re, datetime
+import debug, tests
+from common import TestCommon, TimeoutError
+from results import RowResults, PassFailResult
+
+BLK_TEST_TIMEOUT = datetime.timedelta(minutes=8) # XXX: tilsiter1 needs a bit longer (slow write speeds?)
+
+bandwidth = {
+    'tilsiter1': {
+        'read': {
+            512: 32.67,
+            1024: 50.08,
+            2048: 90.15,
+            4096: 154.21,
+            8192: 236.92,
+            16384: 318.05,
+            32768: 379.68,
+            65536: 416.99,
+            131072: 428.64,
+            262144: 439.88,
+            524288: 495.27,
+            1048576: 528.16,
+            2097152: 546.71
+        },
+        'write': {
+            512: 5.41,
+            1024: 1.70,
+            2048: 3.32,
+            4096: 6.68,
+            8192: 26.50,
+            16384: 49.92,
+            32768: 88.74,
+            65536: 143.63,
+            131072: 212.54,
+            262144: 281.08,
+            524288: 377.55,
+            1048576: 436.48,
+            2097152: 49.25,
+        },
+    },
+
+    'vacherin': {
+        'read': {
+            512: 15.24,
+            1024: 15.35,
+            2048: 30.32,
+            4096: 57.29,
+            8192: 102.01,
+            16384: 167.28,
+            32768: 237.24,
+            65536: 316.74,
+            131072: 361.41,
+            262144: 405.19,
+            524288: 490.97,
+            1048576: 415.05,
+            2097152: 424.57
+        },
+        'write': {
+            512: 15.20,
+            1024: 12.55,
+            2048: 26.87,
+            4096: 51.89,
+            8192: 93.21,
+            16384: 152.43,
+            32768: 213.55,
+            65536: 296.29,
+            131072: 365.72,
+            262144: 412.98,
+            524288: 440.78,
+            1048576: 454.21,
+            2097152: 462.02,
+        }
+    },
+
+    'babybel1': {
+        'read': {
+            512: 43.42,
+            1024: 25.56,
+            2048: 31.16,
+            4096: 55.63,
+            8192: 85.02,
+            16384: 114.35,
+            32768: 105.40,
+            65536: 147.15,
+            131072: 414.57,
+            262144: 482.58,
+            524288: 515.73,
+            1048576: 534.20,
+            2097152: 544.49,
+            4194304: 549.79,
+        },
+        'write': {
+            512: 42.52,
+            1024: 38.18,
+            2048: 41.29,
+            4096: 75.26,
+            8192: 221.12,
+            16384: 267.90,
+            32768: 426.09,
+            65536: 494.36,
+            131072: 516.22,
+            262144: 526.34,
+            524288: 533.67,
+            1048576: 533.67,
+            2097152: 522.25,
+            4194304: 523.27
+        },
+    },
+
+    'babybel2': {
+        'read': {
+            512: 43.32,
+            1024: 14.08,
+            2048: 31.10,
+            4096: 55.14,
+            8192: 83.53,
+            16384: 108.78,
+            32768: 95.90,
+            65536: 115.02,
+            131072: 159.26,
+            262144: 427.62,
+            524288: 514.74,
+            1048576: 533.14,
+            2097152: 503.16
+        },
+        'write': {
+            512: 43.09,
+            1024: 22.52,
+            2048: 41.00,
+            4096: 75.28,
+            8192: 220.75,
+            16384: 268.17,
+            32768: 416.18,
+            65536: 497.10,
+            131072: 519.22,
+            262144: 529.46,
+            524288: 534.73,
+            1048576: 537.95,
+            2097152: 518.22,
+        },
+    },
+
+    'babybel3': {
+        'read': {
+            512: 43.53,
+            1024: 25.71,
+            2048: 31.09,
+            4096: 55.30,
+            8192: 83.35,
+            16384: 107.88,
+            32768: 95.66,
+            65536: 115.43,
+            131072: 161.73,
+            262144: 428.30,
+            524288: 514.24,
+            1048576: 532.87,
+            2097152: 504.82,
+        },
+        'write': {
+            512: 42.86,
+            1024: 38.40,
+            2048: 41.43,
+            4096: 75.83,
+            8192: 225.01,
+            16384: 265.78,
+            32768: 428.13,
+            65536: 495.27,
+            131072: 513.26,
+            262144: 528.42,
+            524288: 532.61,
+            1048576: 532.61,
+            2097152: 525.31,
+        }
+    },
+
+    'babybel4': {
+        'read': {
+            512: 43.46,
+            1024: 20.47,
+            2048: 23.44,
+            4096: 42.33,
+            8192: 64.98,
+            16384: 76.50,
+            32768: 64.45,
+            65536: 77.69,
+            131072: 111.00,
+            262144: 381.98,
+            524288: 492.54,
+            1048576: 512.53,
+            2097152: 451.34
+        },
+        'write': {
+            512: 42.49,
+            1024: 38.40,
+            2048: 41.47,
+            4096: 76.96,
+            8192: 225.20,
+            16384: 265.51,
+            32768: 430.19,
+            65536: 496.18,
+            131072: 517.22,
+            262144: 529.46,
+            524288: 534.73,
+            1048576: 534.73,
+            2097152: 524.29
+        }
+    }
+}
+
+class BlkTests(TestCommon):
+
+    def __init__(self, options):
+        super(BlkTests, self).__init__(options)
+
+    def get_module_name(self):
+        return "ahci_test"
+
+    def boot(self, *args):
+        super(BlkTests, self).boot(*args)
+        self.set_timeout(BLK_TEST_TIMEOUT)
+
+    def get_modules(self, build, machine):
+        self.machine = machine.name
+        vendor_device = "0:0"
+        if self.machine == "tilsiter1":
+            vendor_device = "8086:a102"
+        if self.machine == "vacherin":
+            vendor_device = "8086:8c02"
+        elif self.machine.startswith("babybel"):
+            vendor_device = "8086:1d02"
+
+        modules = super(BlkTests, self).get_modules(build, machine)
+        modules.add_module(self.get_module_name(), ["manual", vendor_device, self.OP])
+
+        return modules
+
+    def is_finished(self, line):
+        return line.startswith("AHCI testing completed.")
+
+    def process_data(self, testdir, rawiter):
+        self.regex = re.compile(self.REGEX)
+        result = RowResults(['op', 'buffer', 'block', 'bandwidth'])
+        if not bandwidth.has_key(self.machine):
+            result.mark_failed('No data about this disk, please set the initial performance values.')
+            return result
+
+        matches = 0
+        for line in rawiter:
+            match = self.regex.match(line)
+            if match:
+                matches += 1
+
+                buffer_size, bs, bw = match.groups()
+                buffer_size = int(buffer_size)
+                bs = int(bs)
+                bw = float(bw)
+                operation = self.OP.lower()
+                if not bandwidth[self.machine].has_key(operation):
+                    result.mark_failed('No data about this benchmark, please set the initial performance values.')
+                    return result
+                if not bandwidth[self.machine][operation].has_key(bs):
+                    result.mark_failed('No data for {} with bs {}.'.format(operation, bs))
+                    return result
+
+                lower_bound = bandwidth[self.machine][operation][bs] * (1 - 0.15)
+                upper_bound = bandwidth[self.machine][operation][bs] * (1 + 0.20)
+
+                result.add_row((operation, buffer_size, bs, bw))
+                if bw <= lower_bound:
+                    error = "{} for {} bytes blocks not within expected range (was {}, should be >= {}).".format(operation, bs, bw, lower_bound)
+                    debug.log(error)
+                    result.mark_failed(reason=error)
+                elif bw >= upper_bound:
+                    error = "Achieved {} bandwidth for {} bytes blocks was better ({}) than expected ({}).".format(operation, bs, bw, upper_bound)
+                    debug.log(error)
+                    debug.log("This is good, if you can explain it! Adjust the bandwidth numbers in blk_tests.py and re-run the test.")
+                    result.mark_failed(reason=error)
+                else:
+                    pass
+
+            if line.startswith("AHCI testing completed.") and matches > 0:
+                return result
+
+        result.mark_failed('Did not see end of test or got no bandwidth numbers.')
+        return result
+
+@tests.add_test
+class BlkAhciWriteBWTest(BlkTests):
+    ''' AHCI Driver Write Bandwidth Test'''
+    name = "blk_read_test"
+    OP = "read"
+    REGEX = r"\[ahci_perf_sequential\] Read sequential size (\d+) bs (\d+): (\d+\.\d+) \[MB/s\]"
+
+@tests.add_test
+class BlkAhciReadBWTest(BlkTests):
+    ''' AHCI Driver Read Bandwidth Test'''
+    name = "blk_write_test"
+    OP = "write"
+    REGEX = r"\[ahci_perf_sequential\] Write sequential size (\d+) bs (\d+): (\d+\.\d+) \[MB/s\]"
+
+@tests.add_test
+class BlkAhciVerifyTest(BlkTests):
+    ''' AHCI Driver Correctness test '''
+    name = "blk_verify_test"
+    OP = "verify"
+    REGEX = r"\[ahci_verify_sequential\] SUCCESS \((\d+) (\d+)\)"
+    TESTS = 14
+
+    def process_data(self, testdir, rawiter):
+        self.regex = re.compile(self.REGEX)
+
+        matches = 0
+        for line in rawiter:
+            match = self.regex.match(line)
+            if match:
+                matches += 1
+
+        if matches == self.TESTS:
+            return PassFailResult(True)
+        elif matches < self.TESTS:
+            return PassFailResult(False, "Some block/buffer size checks did not report back with SUCCESS.")
+        elif matches > self.TESTS:
+            return PassFailResult(False, "Got more SUCCESS lines than expected. If you changed the test you may need to increase self.TESTS.")
+        else:
+            assert "Should not come here"
index 3ae69bb..e2119fb 100644 (file)
 /* we only support 38.4M here */
 
 /* #define CONFIG_MPU_1000 1 */
+/* #define CONFIG_MPU_800 1 */
+#define CONFIG_MPU_600 1
 
 struct dpll_param mpu_dpll_param = {
 #ifdef CONFIG_MPU_600
        0x7d, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+#elif CONFIG_MPU_800 /* 796.8MHz */
+       0xa6, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
 #elif CONFIG_MPU_1000
        0x69, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-#else /* 400MHz */
+#else /* 332.8MHz */
        0x1a, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 
 #endif
 };
index 9c245a2..6a5aacd 100644 (file)
@@ -15,9 +15,8 @@ let commonCFiles = [
         "acpi.c",
         "acpica_osglue.c",
         "video.c",
-        "buttons.c",
-        "acpi_service.c",
         "interrupts.c",
+        "acpi_service.c",
         "ioapic.c" ]
 
     archCFiles arch = case arch of
@@ -25,20 +24,23 @@ let commonCFiles = [
         "x86_64" -> [
             "intel_vtd.c",
             "acpi_ec.c",
+            "buttons.c",
             "arch/x86/acpica_osglue_arch.c",
             "arch/x86/acpi_service_arch.c",
+            "arch/x86/acpi_interrupts_arch.c",
             "arch/x86/acpi_arch.c",
             "arch/x86/acpi_main.c" ]
         "armv8" -> [
             "arch/armv8/acpica_osglue_arch.c",
             "arch/armv8/acpi_service_arch.c",
+            "arch/armv8/acpi_interrupts_arch.c",
             "arch/armv8/acpi_arch.c",
             "arch/armv8/acpi_main.c" ]
 
     commonDevices = [ "lpc_ioapic" ]
 
     archDevices arch = case arch of
-        "x86_32" -> archCFiles "x86_64"
+        "x86_32" -> archDevices "x86_64"
         "x86_64" -> [
             "acpi_ec",
             "vtd",
index 05665f7..1284a15 100644 (file)
@@ -541,7 +541,10 @@ static ACPI_STATUS add_pci_device(ACPI_HANDLE handle, UINT32 level,
     ACPI_INTEGER addr;
     as = acpi_eval_integer(handle, "_ADR", &addr);
     if (ACPI_FAILURE(as)) {
-        return as;
+        if (as != AE_NOT_FOUND) {
+            debug_printf("add_pci_device: cannot evaluate _ADR: status=%x \n", as);
+        }
+        return AE_OK;
     }
 
     struct pci_address bridgeaddr;
@@ -642,8 +645,8 @@ static int acpi_init(void)
         return -1;
     }
 
-    ACPI_DEBUG("Scanning local and I/O APICs...\n");
-    int r = init_all_apics();
+    ACPI_DEBUG("Scanning interrupt sources...\n");
+    int r = init_all_interrupt_sources();
     assert(r == 0);
 
 #ifdef USE_KALUGA_DVM
@@ -726,8 +729,6 @@ static void process_srat(ACPI_TABLE_SRAT *srat)
                 } else {
                     ACPI_DEBUG("CPU affinity table disabled!\n");
                 }
-
-                pos += sizeof(ACPI_SRAT_CPU_AFFINITY);
             }
             break;
 
@@ -760,19 +761,24 @@ static void process_srat(ACPI_TABLE_SRAT *srat)
                 } else {
                     ACPI_DEBUG("Memory affinity table disabled!\n");
                 }
-
-                pos += sizeof(ACPI_SRAT_MEM_AFFINITY);
             }
             break;
 
         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
             ACPI_DEBUG("Ignoring unsupported x2APIC CPU affinity table.\n");
+
+            break;
+
+        case ACPI_SRAT_TYPE_GICC_AFFINITY:
+            ACPI_DEBUG("Ignoring unsupported GIC CPU affinity table.\n");
+
             break;
 
         default:
             ACPI_DEBUG("Ignoring unknown SRAT subtable ID %d.\n", shead->Type);
             break;
         }
+        pos += shead->Length;
     }
 
     ACPI_DEBUG("done processing srat...\n");
index 8322a30..da39dc3 100644 (file)
@@ -256,12 +256,62 @@ static void sleep_handler(struct acpi_binding *b, uint32_t state)
     }
 }
 
+static void get_handle_handler(struct acpi_binding *b, char *dev_id)
+{
+    errval_t err = SYS_ERR_OK;;
+
+    debug_printf("Looking up handle for device '%s'\n", dev_id);
+
+    ACPI_STATUS s;
+    ACPI_HANDLE handle;
+    s = AcpiGetHandle (NULL,dev_id,&handle);
+    if (ACPI_FAILURE(s)) {
+        if (s == AE_BAD_PATHNAME) {
+            err = ACPI_ERR_INVALID_PATH_NAME;
+        } else {
+            err = ACPI_ERR_INVALID_HANDLE;
+        }
+    }
+
+    //out uint64 handle, out errval err
+    err = b->tx_vtbl.get_handle_response(b, NOP_CONT, (uint64_t)handle, err);
+    assert(err_is_ok(err));
+
+    free(dev_id);
+}
+
+static void eval_integer_handler(struct acpi_binding *b,
+                                 uint64_t handle, char *path)
+{
+    errval_t err = SYS_ERR_OK;
+
+    ACPI_STATUS s;
+    ACPI_INTEGER val = 0;
+    s = acpi_eval_integer((ACPI_HANDLE)handle, path, &val);
+    if (ACPI_FAILURE(s)) {
+        if (s == AE_BAD_PATHNAME) {
+            err = ACPI_ERR_INVALID_PATH_NAME;
+        } else {
+            err = ACPI_ERR_INVALID_HANDLE;
+        }
+        val = 0;
+    }
+
+    debug_printf("eval_integer_handler\n");
+    err = b->tx_vtbl.eval_integer_response(b, NOP_CONT, val, err);
+    free(path);
+}
+
+
 struct acpi_rx_vtbl acpi_rx_vtbl = {
     .get_pcie_confspace_call = get_pcie_confspace,
     .read_irq_table_call = read_irq_table,
     .set_device_irq_call = set_device_irq,
     .enable_and_route_interrupt_call = enable_interrupt_handler,
 
+    .get_handle_call = get_handle_handler,
+    .eval_integer_call = eval_integer_handler,
+
     .mm_alloc_range_proxy_call = mm_alloc_range_proxy_handler,
     .mm_realloc_range_proxy_call = mm_realloc_range_proxy_handler,
     .mm_free_proxy_call = mm_free_proxy_handler,
index 206ffba..1cfbbeb 100644 (file)
 extern struct capref my_devframes_cnode;
 extern struct mm pci_mm_physaddr;
 
+extern uintptr_t my_hw_id;
+
 errval_t find_all_apics(void);
 
+int init_all_interrupt_sources(void);
+
 int init_acpi(void);
 int acpi_arch_init(void);
 ACPI_STATUS acpi_eval_integer(ACPI_HANDLE handle, char *name, ACPI_INTEGER *ret);
index 991d61e..3a0db92 100644 (file)
@@ -202,7 +202,7 @@ AcpiOsGetRootPointer (
     if (acpi_root_pointer != 0) {
         return acpi_root_pointer;
     }
-    ACPI_SIZE physaddr;
+    ACPI_PHYSICAL_ADDRESS physaddr;
     ACPI_STATUS as = AcpiFindRootPointer(&physaddr);
     if (as == AE_OK) {
         return physaddr;
@@ -1326,7 +1326,7 @@ AcpiOsWriteMemory (
 ACPI_THREAD_ID
 AcpiOsGetThreadId(void)
 {
-    return (ACPI_THREAD_ID)thread_self();
+    return (ACPI_THREAD_ID)(uintptr_t)thread_self();
 }
 
 
diff --git a/usr/acpi/arch/armv8/acpi_interrupts_arch.c b/usr/acpi/arch/armv8/acpi_interrupts_arch.c
new file mode 100644 (file)
index 0000000..28bf50f
--- /dev/null
@@ -0,0 +1,258 @@
+/**
+ * \file
+ * \brief Interrupt management (Local and IOAPICs) and routing
+ */
+
+/*
+ * Copyright (c) 2007, 2008, 2009, 2011, 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 <arch/aarch64/hw_records_arch.h>
+#include <stdio.h>
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/cpu_arch.h>
+#include <acpi.h>
+#include <mm/mm.h>
+
+#include <skb/skb.h>
+#include <octopus/getset.h>
+#include <trace/trace.h>
+
+#include "ioapic.h"
+#include "acpi_debug.h"
+#include "acpi_shared.h"
+
+
+int init_all_interrupt_sources(void)
+{
+    ACPI_STATUS         as;
+    ACPI_TABLE_MADT     *madt;
+    ACPI_TABLE_HEADER   *ath;
+
+    static coreid_t barrelfish_id_counter = 1;
+
+    // Get the ACPI APIC table (the MADT)
+    as = AcpiGetTable("APIC", 1, (ACPI_TABLE_HEADER **)&ath);
+
+    if(ACPI_FAILURE(as)) {
+        ACPI_DEBUG("No MADT found in ACPI! Cannot initialize I/O APICs.\n");
+        return -1;
+    }
+    else {
+        madt = (ACPI_TABLE_MADT*)ath;
+    }
+
+    // Walk all subtables (after the main table entries)
+    void *p = (void *)madt + sizeof(ACPI_TABLE_MADT);
+    while(p < (void *)madt + madt->Header.Length) {
+        ACPI_SUBTABLE_HEADER *sh = (ACPI_SUBTABLE_HEADER *)p;
+
+        switch(sh->Type) {
+        case ACPI_MADT_TYPE_LOCAL_APIC:
+            {
+                debug_printf("WARNING LOCAL APIC found on non x86\n");
+            }
+            break;
+
+        case ACPI_MADT_TYPE_IO_APIC:
+            {
+                debug_printf("WARNING IO APIC found on non x86\n");
+            }
+            break;
+
+        case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
+            {
+                debug_printf("WARNING INTERRUPT_OVERRIDE found on non x86\n");
+            }
+            break;
+
+        case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
+            debug_printf("WARNING LOCAL_APIC_NMI found on non x86\n");
+            break;
+        case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
+            {
+            ACPI_MADT_GENERIC_INTERRUPT *gi = (ACPI_MADT_GENERIC_INTERRUPT *)sh;
+
+            /*
+             * ACPI Spec 6.1 - 5.2.12.14 GIC CPU Interface (GICC) Structure
+             *
+             * CPU Interface Number
+             * GIC's CPU Interface Number. In GICv1/v2 implementations, this
+             * value matches the bit index of the associated processor in the GIC
+             * distributor's GICD_ITARGETSR register.
+             * For GICv3/4 implementations this field must be provided by the
+             * platform, if compatibility mode is supported.
+             * If it is not supported by the implementation, then this field must be
+             * zero
+             *
+             * UID
+             * The OS associates this GICC Structure with a processor device
+             * object in the namespace when the _UID child object of the
+             * processor device evaluates to a numeric value that matches the
+             * numeric value in this field.
+             *
+             * Parking Address
+             * The 64-bit physical address of the processor's Parking Protocol
+             * mailbox
+             *
+             * ParkingVersion
+             * Version of the ARM-Processor Parking Protocol implemented. See
+             * http://uefi.org/acpi. The document link is listed under
+             * "Multiprocessor Startup for ARM Platforms"
+             * For systems that support PSCI exclusively and do not support the
+             * parking protocol, this field must be set to 0
+             *
+             * BaseAddress
+             * On GICv1/v2 systems and GICv3/4 systems in GICv2 compatibility
+             * mode, this field holds the 64-bit physical address at which the
+             * processor can access this GIC CPU Interface. If provided here, the
+             * "Local Interrupt Controller Address" field in the MADT must be
+             * ignored by the OSPM.
+             *
+             * GICV
+             * Address of the GIC virtual CPU interface registers. If the platform
+             * is not presenting a GICv2 with virtualization extensions this field
+             * can be 0.
+             *
+             * GICH
+             * Address of the GIC virtual interface control block registers. If the
+             * platform is not presenting a GICv2 with virtualization extensions
+             * this field can be 0.
+             *
+             * On systems supporting GICv3 and above, this field holds the 64-bit
+             * physical address of the associated Redistributor. If all of the GIC
+             * Redistributors are in the always-on power domain, GICR structures
+             * should be used to describe the Redistributors instead, and this field
+             * must be set to 0.
+             *
+             * MPIDR
+             * This fields follows the MPIDR formatting of ARM architecture.
+             * If the implements ARMv7 architecure then the format must be:
+             *  Bits [63:24] Must be zero
+             *  Bits [23:16] Aff2 : Match Aff2 of target processor MPIDR
+             *  Bits [15:8] Aff1 : Match Aff1 of target processor MPIDR
+             *  Bits [7:0] Aff0 : Match Aff0 of target processor MPIDR
+             *
+             * For platforms implementing ARMv8 the format must be:
+             *  Bits [63:40] Must be zero
+             *  Bits [39:32] Aff3 : Match Aff3 of target processor MPIDR
+             *  Bits [31:24] Must be zero
+             *  Bits [23:16] Aff2 : Match Aff2 of target processor MPIDR
+             *  Bits [15:8] Aff1 : Match Aff1 of target processor MPIDR
+             *  Bits [7:0] Aff0 : Match Aff0 of target processor MPIDR
+             */
+
+            printf("#### ParkedAddress = %lx\n", gi->ParkedAddress);
+
+            debug_printf("Found local APIC GENERIC_INTERRUPT: BaseAddress=0x%016"
+                       PRIx64
+                       ", ParkedAddress=0x%016" PRIx64
+                       ", GicvBaseAddress=0x%016" PRIx64
+                       ", GichBaseAddress=0x%016" PRIx64
+                       ", GicrBaseAddress=0x%016" PRIx64
+                       ", CpuInterfaceNumber=%" PRIu32 ", Uid=%" PRIu32
+                       ", ArmMpidr =%" PRIx64 "\n",
+                       gi->BaseAddress, gi->ParkedAddress, gi->GicvBaseAddress, gi->GichBaseAddress,
+                       gi->GicrBaseAddress, gi->CpuInterfaceNumber, gi->Uid, gi->ArmMpidr);
+
+            coreid_t barrelfish_id;
+            if (my_hw_id == gi->Uid) {
+                barrelfish_id = 0; // BSP core is 0
+            }
+            else {
+                barrelfish_id = barrelfish_id_counter++;
+            }
+
+            /* TODO: figure out which facts you need */
+            skb_add_fact("generic_interrupt(%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%d,%d).",
+                         gi->BaseAddress, gi->GicvBaseAddress, gi->GichBaseAddress,
+                         gi->ParkedAddress, gi->CpuInterfaceNumber, gi->Uid);
+
+            errval_t err = oct_set(HW_PROCESSOR_ARMV8_RECORD_FORMAT,
+                                   barrelfish_id, gi->Flags & ACPI_MADT_ENABLED,
+                                   barrelfish_id, gi->Uid, CURRENT_CPU_TYPE,
+                                   gi->CpuInterfaceNumber, gi->Uid,
+                                   gi->ParkedAddress, gi->ParkingVersion,
+                                   gi->ArmMpidr);
+            if (err_is_fail(err)) {
+                USER_PANIC_ERR(err, "failed to set record");
+            }
+            assert(err_is_ok(err));
+            }
+            break;
+        case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
+            {
+            ACPI_MADT_GENERIC_DISTRIBUTOR *gd = (ACPI_MADT_GENERIC_DISTRIBUTOR *)sh;
+            debug_printf("Found GENERIC DISTRIBUTOR: BaseAddress=0x%016"
+                                   PRIx64 ", GicId=%" PRIu32 ", Version=%" PRIu8
+                                   ", GlobalIrqBase=%" PRIu32 "\n", gd->BaseAddress,
+                                   gd->GicId , gd->Version, gd->GlobalIrqBase);
+            skb_add_fact("generic_distributor(%"PRIu64",%d,%d,%d).",
+                         gd->BaseAddress, gd->GicId, gd->GlobalIrqBase, gd->Version);
+            }
+
+
+
+            break;
+        case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
+            {
+            ACPI_MADT_GENERIC_MSI_FRAME *msi = (ACPI_MADT_GENERIC_MSI_FRAME *)sh;
+            ACPI_DEBUG("Found local APIC GENERIC MSI FRAME: BaseAddress=0x%016"
+                       PRIx64 ", MsiFrameId=%" PRIu32 "\n", msi->BaseAddress,
+                       msi->MsiFrameId);
+            skb_add_fact("generic_msi_frame(%"PRIu64",%d,%d,%d,%d).",
+                         msi->BaseAddress, msi->MsiFrameId, msi->SpiBase,
+                         msi->SpiBase, msi->Flags);
+            }
+            break;
+        case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
+        {
+            ACPI_MADT_GENERIC_REDISTRIBUTOR *grd = (ACPI_MADT_GENERIC_REDISTRIBUTOR *)sh;
+            debug_printf("Found GENERIC REDISTRIBUTOR: BaseAddress=0x%016"
+                        PRIx64 ", Length=%" PRIu32 "\n", grd->BaseAddress,
+                        grd->Length);
+            skb_add_fact("generic_redistributor(%"PRIu64",%d).",
+                         grd->BaseAddress, grd->Length);
+        }
+            break;
+        case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
+        {
+            ACPI_MADT_GENERIC_TRANSLATOR *gt = (ACPI_MADT_GENERIC_TRANSLATOR *)sh;
+            ACPI_DEBUG("Found local APIC GENERIC TRANSLATOR: TranslationId=%"
+                        PRIu32 ", BaseAddress=0x%016" PRIx64 "\n", gt->TranslationId,
+                        gt->BaseAddress);
+            skb_add_fact("generic_translator(%"PRIu64",%d).",
+                         gt->BaseAddress, gt->TranslationId);
+        }
+            break;
+        default:
+            ACPI_DEBUG("Unknown subtable type %d\n", sh->Type);
+            break;
+        }
+
+        p += sh->Length;
+    }
+
+
+#if 0
+    /* XXX: Quirk hack for QEMU
+     * There is no override for the timer interrupt, although it appears as IRQ2.
+     */
+    if (strncmp(madt->Header.OemId, "QEMU", 4) == 0
+        && interrupt_overrides[0] == 0) {
+
+    }
+#endif
+    return 0;
+}
+
+errval_t enable_and_route_interrupt(int gsi, coreid_t dest, int vector)
+{
+    USER_PANIC("NYI!");
+    return SYS_ERR_OK;
+}
index bf33faf..3e069fe 100644 (file)
@@ -32,7 +32,7 @@
  */
 #define PCI_CNODE_SLOTS 2048
 
-uintptr_t my_apic_id;
+uintptr_t my_hw_id;
 
 // Memory allocator instance for physical address regions and platform memory
 struct mm pci_mm_physaddr;
@@ -186,7 +186,7 @@ int main(int argc, char *argv[])
     // Parse CMD Arguments
     bool got_apic_id = false;
     for (int i = 1; i < argc; i++) {
-        if(sscanf(argv[i], "apicid=%" PRIuPTR, &my_apic_id) == 1) {
+        if(sscanf(argv[i], "apicid=%" PRIuPTR, &my_hw_id) == 1) {
             got_apic_id = true;
         } else {
             debug_printf("unkown argument: '%s'\n", argv[i]);
diff --git a/usr/acpi/arch/x86/acpi_interrupts_arch.c b/usr/acpi/arch/x86/acpi_interrupts_arch.c
new file mode 100644 (file)
index 0000000..7391baf
--- /dev/null
@@ -0,0 +1,432 @@
+/**
+ * \file
+ * \brief Interrupt management (Local and IOAPICs) and routing
+ */
+
+/*
+ * Copyright (c) 2007, 2008, 2009, 2011, 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 <arch/aarch64/hw_records_arch.h>
+#include <stdio.h>
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/cpu_arch.h>
+#include <acpi.h>
+#include <mm/mm.h>
+
+#include <skb/skb.h>
+#include <octopus/getset.h>
+#include <trace/trace.h>
+
+#include <hw_records_arch.h>
+
+#include "ioapic.h"
+#include "acpi_debug.h"
+#include "acpi_shared.h"
+
+//from documentation
+#define APIC_BITS 11
+
+/// Assume size of the I/O APIC is one page
+#define IOAPIC_PAGE_BITS        BASE_PAGE_BITS
+#define IOAPIC_PAGE_SIZE        (1<<IOAPIC_PAGE_BITS)
+
+/// Maximum number of supported I/O APICs
+#define IOAPIC_MAX      5
+
+/// Room for all supported I/O APICs
+static struct ioapic ioapics[IOAPIC_MAX];
+
+/// Interrupt override table (maps ISA interrupts to GSIs)
+#define N_ISA_INTERRUPTS 16
+static int interrupt_overrides[N_ISA_INTERRUPTS];
+
+/// I/O APIC redirection table entry template for ISA bus
+static lpc_ioapic_redir_tbl_t ioapic_redir_tmpl_isa = {
+    .mode = lpc_ioapic_fixed,
+    .destmode = lpc_ioapic_physical,
+    .polarity = lpc_ioapic_active_high,
+    .trigger = lpc_ioapic_edge,
+    .mask = 1
+};
+
+/// I/O APIC redirection table entry template for PCI bus
+static lpc_ioapic_redir_tbl_t ioapic_redir_tmpl_pci = {
+    .mode = lpc_ioapic_fixed,
+    .destmode = lpc_ioapic_physical,
+    .polarity = lpc_ioapic_active_low,
+    .trigger = lpc_ioapic_edge, // XXX: Barrelfish cannot handle level
+                                // triggered interrupts
+    .mask = 1
+};
+
+static struct ioapic *find_ioapic(uint32_t gsi)
+{
+    for(int i = 0; i < IOAPIC_MAX; i++) {
+        struct ioapic *a = &ioapics[i];
+
+        if(a->irqbase <= gsi && gsi < a->irqbase + a->nintis) {
+            return a;
+        }
+    }
+
+    return NULL;
+}
+
+static errval_t init_one_ioapic(ACPI_MADT_IO_APIC *s)
+{
+    errval_t            err;
+    struct capref       devmem, devframe;
+    lvaddr_t            vaddr;
+    static int          ioapic_nr = 0;
+
+    assert(ioapic_nr < IOAPIC_MAX);
+
+    // allocate memory backing IOAPIC
+    err = mm_realloc_range(&pci_mm_physaddr, IOAPIC_PAGE_BITS,
+                           s->Address, &devmem);
+    if (err_is_fail(err)) {
+        DEBUG_ERR(err, "Failed to allocate I/O APIC register page at 0x%x\n",
+                  s->Address);
+        return err_push(err, MM_ERR_REALLOC_RANGE);
+    }
+
+    /*
+    err = devframe_type(&devframe, devmem, BASE_PAGE_BITS);
+    if (err_is_fail(err)) {
+        return err_push(err, LIB_ERR_DEVFRAME_TYPE);
+    }*/
+
+    devframe = devmem;
+
+    // Map registers
+    err = vspace_map_one_frame_attr((void**)&vaddr, IOAPIC_PAGE_SIZE, devframe,
+                                    VREGION_FLAGS_READ_WRITE_NOCACHE,
+                                    NULL, NULL);
+    if (err_is_fail(err)) {
+        return err_push(err, LIB_ERR_VSPACE_MAP);
+    }
+
+    // Initialize driver
+    struct ioapic *ioapic = &ioapics[ioapic_nr++];
+
+    err = ioapic_init(ioapic, vaddr, s->Id, s->GlobalIrqBase);
+    if (err_is_fail(err)) {
+        ACPI_DEBUG("I/O APIC init failed!\n");
+        return err_push(err, PCI_ERR_IOAPIC_INIT);
+    }
+
+    // Set redirection table entry defaults for managed buses
+    for(int i = 0; i < ioapic->nintis; i++) {
+        if(s->GlobalIrqBase + i < N_ISA_INTERRUPTS) {
+            // ISA interrupts go to GSIs 0 .. 15
+            ioapic_setup_inti(ioapic, i, ioapic_redir_tmpl_isa);
+        } else {
+            // Assume the rest is PCI
+            ioapic_setup_inti(ioapic, i, ioapic_redir_tmpl_pci);
+        }
+    }
+
+    return SYS_ERR_OK;
+}
+
+static int init_one_local_apic(ACPI_MADT_LOCAL_APIC *s, lpaddr_t base)
+{
+    // TODO: Bring up other cores here! But I think we need chips for
+    // better integration with other domains booted from init.
+    return 0;
+}
+
+int init_all_interrupt_sources(void)
+{
+    ACPI_STATUS         as;
+    ACPI_TABLE_MADT     *madt;
+    ACPI_TABLE_HEADER   *ath;
+    int                 r;
+
+    static coreid_t barrelfish_id_counter = 1;
+
+    // default overrides
+    for (int i = 0; i < N_ISA_INTERRUPTS; i++) {
+        interrupt_overrides[i] = i;
+    }
+
+    // Get the ACPI APIC table (the MADT)
+    as = AcpiGetTable("APIC", 1, (ACPI_TABLE_HEADER **)&ath);
+
+    if(ACPI_FAILURE(as)) {
+        ACPI_DEBUG("No MADT found in ACPI! Cannot initialize I/O APICs.\n");
+        return -1;
+    }
+    else {
+        madt = (ACPI_TABLE_MADT*)ath;
+    }
+
+    // Parse main table entries
+    ACPI_DEBUG("Local APIC is at 0x%"PRIx32"\n", madt->Address);
+    skb_add_fact("memory_region(%" PRIu32 ",%u,%zu, %u,%u).",
+                 madt->Address,
+                 APIC_BITS, //from documentation
+                 ((size_t)1) << APIC_BITS, //from documentation
+                 RegionType_LocalAPIC,
+                 0);
+
+    if((madt->Flags & ACPI_MADT_PCAT_COMPAT) == ACPI_MADT_MULTIPLE_APIC) {
+        ACPI_DEBUG("This system also has dual-8259As.\n");
+    }
+
+    // Walk all subtables (after the main table entries)
+    void *p = (void *)madt + sizeof(ACPI_TABLE_MADT);
+    while(p < (void *)madt + madt->Header.Length) {
+        ACPI_SUBTABLE_HEADER *sh = (ACPI_SUBTABLE_HEADER *)p;
+
+        switch(sh->Type) {
+        case ACPI_MADT_TYPE_LOCAL_APIC:
+            {
+                ACPI_MADT_LOCAL_APIC *s = (ACPI_MADT_LOCAL_APIC *)sh;
+
+                ACPI_DEBUG("Found local APIC: CPU = %d, ID = %d, usable = %d\n",
+                       s->ProcessorId, s->Id,
+                       s->LapicFlags & ACPI_MADT_ENABLED);
+                trace_event(TRACE_SUBSYS_ACPI, TRACE_EVENT_ACPI_APIC_ADDED, s->ProcessorId);
+
+
+                coreid_t barrelfish_id;
+                if (my_hw_id == s->Id) {
+                    barrelfish_id = 0; // BSP core is 0
+                }
+                else {
+                    barrelfish_id = barrelfish_id_counter++;
+                }
+                errval_t err = oct_set(HW_PROCESSOR_X86_RECORD_FORMAT,
+                                       barrelfish_id, s->LapicFlags & ACPI_MADT_ENABLED,
+                                       barrelfish_id, s->Id, CURRENT_CPU_TYPE,
+                                       s->ProcessorId, s->Id);
+                assert(err_is_ok(err));
+
+                skb_add_fact("apic(%d,%d,%"PRIu32").",
+                       s->ProcessorId, s->Id,
+                       s->LapicFlags & ACPI_MADT_ENABLED);
+
+                if(s->LapicFlags & ACPI_MADT_ENABLED) {
+                    r = init_one_local_apic(s, madt->Address);
+                    assert(r == 0);
+                }
+            }
+            break;
+
+        case ACPI_MADT_TYPE_IO_APIC:
+            {
+                ACPI_MADT_IO_APIC *s = (ACPI_MADT_IO_APIC *)sh;
+                errval_t err;
+
+                ACPI_DEBUG("Found I/O APIC: ID = %d, mem base = 0x%"PRIx32", "
+                       "INTI base = %"PRIu32"\n", s->Id, s->Address, s->GlobalIrqBase);
+
+                skb_add_fact("ioapic(%d,%"PRIu32",%"PRIu32").", s->Id, s->Address, s->GlobalIrqBase);
+                skb_add_fact("memory_region(%"PRIu32",%u,%zu, %u,%u).",
+                             s->Address,
+                             BASE_PAGE_BITS, //as used elswhere in acpi.c
+                             ((size_t)1) << BASE_PAGE_BITS, //as used elswhere in acpi.c
+                             RegionType_IOAPIC,
+                             0);
+
+                err = init_one_ioapic(s);
+                if(err_is_fail(err)) {
+                    DEBUG_ERR(err, "Unable to initialize I/O APIC (ID = %d)",
+                              s->Id);
+                    abort();
+                }
+            }
+            break;
+
+        case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
+            {
+                ACPI_MADT_INTERRUPT_OVERRIDE *s =
+                    (ACPI_MADT_INTERRUPT_OVERRIDE *)sh;
+
+                ACPI_DEBUG("Found interrupt override: bus = %d, bus_irq = %d, "
+                       "GSI = %"PRIu32", flags = %x\n", s->Bus, s->SourceIrq,
+                       s->GlobalIrq, s->IntiFlags);
+
+                skb_add_fact("interrupt_override(%d,%d,%"PRIu32",%d).",
+                            s->Bus, s->SourceIrq, s->GlobalIrq, s->IntiFlags);
+
+                // ACPI spec says these are only for ISA interrupts
+                assert(s->SourceIrq < N_ISA_INTERRUPTS);
+
+                interrupt_overrides[s->SourceIrq] = s->GlobalIrq;
+
+                if (s->IntiFlags == 0) {
+                    break;
+                }
+
+                lpc_ioapic_redir_tbl_t entry = ioapic_redir_tmpl_isa;
+                struct ioapic *a = find_ioapic(s->GlobalIrq);
+                if (a == NULL) {
+                    ACPI_DEBUG("Warning: unknown IOAPIC for GSI %"PRIu32", ignored"
+                              " interrupt override flags.\n", s->GlobalIrq);
+                    break;
+                }
+
+                // Set polarity
+                assert((s->IntiFlags & ACPI_MADT_POLARITY_MASK)
+                       != ACPI_MADT_POLARITY_RESERVED);
+
+                switch(s->IntiFlags & ACPI_MADT_POLARITY_MASK) {
+                case ACPI_MADT_POLARITY_ACTIVE_HIGH:
+                    entry.polarity = lpc_ioapic_active_high;
+                    break;
+
+                case ACPI_MADT_POLARITY_ACTIVE_LOW:
+                    entry.polarity = lpc_ioapic_active_low;
+                    break;
+                }
+
+                // Set trigger mode
+                assert((s->IntiFlags & ACPI_MADT_TRIGGER_MASK)
+                       != ACPI_MADT_TRIGGER_RESERVED);
+
+                switch(s->IntiFlags & ACPI_MADT_TRIGGER_MASK) {
+                case ACPI_MADT_TRIGGER_EDGE:
+                    entry.trigger = lpc_ioapic_edge;
+                    break;
+
+                case ACPI_MADT_TRIGGER_LEVEL:
+                    // XXX: should be lpc_ioapic_level
+                    entry.trigger = lpc_ioapic_edge;
+                    break;
+                }
+
+                ioapic_setup_inti(a, s->GlobalIrq - a->irqbase, entry);
+            }
+            break;
+
+        case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
+            {
+                ACPI_MADT_LOCAL_APIC_NMI *s = (ACPI_MADT_LOCAL_APIC_NMI *)sh;
+
+                ACPI_DEBUG("Found local APIC NMI: CPU ID = %d, flags = %x, "
+                       "LINT = %d\n", s->ProcessorId, s->IntiFlags, s->Lint);
+
+                skb_add_fact("apic_nmi(%d,%d,%d).",s->ProcessorId, s->IntiFlags,
+                                                   s->Lint);
+
+                ACPI_DEBUG("Ignoring for now.\n");
+            }
+            break;
+        case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
+        {
+            debug_printf("WARNING GENERIC INTERRUPT found on x86\n");
+        }
+            break;
+        case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
+        {
+            debug_printf("WARNING GENERIC DISTRIBUTOR found on x86\n");
+        }
+            break;
+        case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
+        {
+            debug_printf("WARNING GENERIC MSI FRAME found on x86\n");
+        }
+            break;
+        case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
+        {
+            debug_printf("WARNING GENERIC REDISTRIBUTOR found on x86\n");
+        }
+            break;
+        case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
+        {
+            debug_printf("WARNING GENERIC TRANSLATOR found on x86\n");
+        }
+            break;
+        default:
+            ACPI_DEBUG("Unknown subtable type %d\n", sh->Type);
+            break;
+        }
+
+        p += sh->Length;
+    }
+
+
+    /* XXX: Quirk hack for QEMU
+     * There is no override for the timer interrupt, although it appears as IRQ2.
+     */
+    if (strncmp(madt->Header.OemId, "QEMU", 4) == 0
+        && interrupt_overrides[0] == 0) {
+        interrupt_overrides[0] = 2;
+        printf("added missing override from GSI 0 to INTI 2 on QEMU\n");
+    }
+
+    return 0;
+}
+
+
+errval_t enable_and_route_interrupt(int gsi, coreid_t dest, int vector)
+{
+    /* sanity-check vector */
+    // XXX: this check matches the use of vectors in the kernel's irq.c
+    if (vector < 0 || vector >= (250 - 32)) {
+        return PCI_ERR_INVALID_VECTOR;
+    }
+
+    /* convert to CPU vector */
+    vector += 32;
+
+    /* lookup override table */
+    int gsi_mapped;
+    if (gsi < N_ISA_INTERRUPTS) {
+        gsi_mapped = interrupt_overrides[gsi];
+    } else {
+        gsi_mapped = gsi;
+    }
+
+    /* find the correct IOAPIC */
+    struct ioapic *i = find_ioapic(gsi_mapped);
+    if (i == NULL) {
+        return PCI_ERR_UNKNOWN_GSI;
+    }
+
+    // Resolve destination core ID to APIC ID
+    char *result = NULL, *str_error = NULL, query[256];
+    int32_t int_error = 0;
+    int r = snprintf(query, 256, "corename(%d, _, apic(A)), write(A).", dest);
+    assert(r >= 0 && r < 256);
+    errval_t err = skb_evaluate(query, &result, &str_error, &int_error);
+    assert(err_is_ok(err));
+    assert(result != NULL);
+    free(str_error);
+
+    // If SKB didn't have an answer, we assume we're not done setting up
+    // mappings yet. In this case, we can only resolve our own core ID.
+    uint8_t dest_apicid;
+    if(*result == '\0') {
+        if(dest != disp_get_core_id()) {
+            USER_PANIC("SKB couldn't resolve core ID and it's not this core's "
+                       "ID, giving up.");
+        }
+
+        dest_apicid = my_hw_id;
+    } else {
+        dest_apicid = strtol(result, &str_error, 10);
+        assert(*str_error == '\0');
+    }
+    free(result);
+
+    /* route to the given core */
+    int inti = gsi_mapped - i->irqbase;
+    ioapic_route_inti(i, inti, vector, dest_apicid);
+
+    printf("routing GSI %d -> %d -> INTI %d -> APIC %d (coreid %d) "
+              "vector %d\n", gsi, gsi_mapped, inti, dest_apicid, dest, vector);
+
+    /* enable */
+    ioapic_toggle_inti(i, inti, true);
+
+    return SYS_ERR_OK;
+}
index 82d899c..c5f4425 100644 (file)
@@ -32,7 +32,7 @@
  */
 #define PCI_CNODE_SLOTS 2048
 
-uintptr_t my_apic_id;
+uintptr_t my_hw_id;
 
 bool vtd_force_off;
 
@@ -164,7 +164,7 @@ static errval_t init_allocators(void)
                          mrp->mrmod_data);
         }
         else {
-            skb_add_fact("memory_region(16'%" PRIxGENPADDR ",%u,%zu,%u,%tu).",
+            skb_add_fact("memory_region(16'%" PRIxGENPADDR ",%u,%" PRIuGENSIZE ",%u,%tu).",
                         mrp->mr_base, 0, mrp->mr_bytes, mrp->mr_type,
                         mrp->mrmod_data);
         }
@@ -226,9 +226,9 @@ int main(int argc, char *argv[])
     // Parse CMD Arguments
     bool got_apic_id = false;
     bool do_video_init = false;
-    vtd_force_off = false;
+    vtd_force_off = true;
     for (int i = 1; i < argc; i++) {
-        if(sscanf(argv[i], "apicid=%" PRIuPTR, &my_apic_id) == 1) {
+        if(sscanf(argv[i], "apicid=%" PRIuPTR, &my_hw_id) == 1) {
             got_apic_id = true;
         }
 
index af7dde5..d320f76 100644 (file)
@@ -12,6 +12,7 @@
  * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
  */
 
+#include <arch/aarch64/hw_records_arch.h>
 #include <stdio.h>
 #include <barrelfish/barrelfish.h>
 #include <barrelfish/cpu_arch.h>
 #include <octopus/getset.h>
 #include <trace/trace.h>
 
-#include "ioapic.h"
-#include "acpi_debug.h"
-#include "acpi_shared.h"
-
-//from documentation
-#define APIC_BITS 11
-
-/// Assume size of the I/O APIC is one page
-#define IOAPIC_PAGE_BITS        BASE_PAGE_BITS
-#define IOAPIC_PAGE_SIZE        (1<<IOAPIC_PAGE_BITS)
-
-/// Maximum number of supported I/O APICs
-#define IOAPIC_MAX      5
-
-/// Room for all supported I/O APICs
-static struct ioapic ioapics[IOAPIC_MAX];
-
-/// Interrupt override table (maps ISA interrupts to GSIs)
-#define N_ISA_INTERRUPTS 16
-static int interrupt_overrides[N_ISA_INTERRUPTS];
-
-/// I/O APIC redirection table entry template for ISA bus
-static lpc_ioapic_redir_tbl_t ioapic_redir_tmpl_isa = {
-    .mode = lpc_ioapic_fixed,
-    .destmode = lpc_ioapic_physical,
-    .polarity = lpc_ioapic_active_high,
-    .trigger = lpc_ioapic_edge,
-    .mask = 1
-};
-
-/// I/O APIC redirection table entry template for PCI bus
-static lpc_ioapic_redir_tbl_t ioapic_redir_tmpl_pci = {
-    .mode = lpc_ioapic_fixed,
-    .destmode = lpc_ioapic_physical,
-    .polarity = lpc_ioapic_active_low,
-    .trigger = lpc_ioapic_edge, // XXX: Barrelfish cannot handle level
-                                // triggered interrupts
-    .mask = 1
-};
-
-static struct ioapic *find_ioapic(uint32_t gsi)
-{
-    for(int i = 0; i < IOAPIC_MAX; i++) {
-        struct ioapic *a = &ioapics[i];
-
-        if(a->irqbase <= gsi && gsi < a->irqbase + a->nintis) {
-            return a;
-        }
-    }
-
-    return NULL;
-}
-
-static errval_t init_one_ioapic(ACPI_MADT_IO_APIC *s)
-{
-    errval_t            err;
-    struct capref       devmem, devframe;
-    lvaddr_t            vaddr;
-    static int          ioapic_nr = 0;
-
-    assert(ioapic_nr < IOAPIC_MAX);
-
-    // allocate memory backing IOAPIC
-    err = mm_realloc_range(&pci_mm_physaddr, IOAPIC_PAGE_BITS,
-                           s->Address, &devmem);
-    if (err_is_fail(err)) {
-        DEBUG_ERR(err, "Failed to allocate I/O APIC register page at 0x%x\n",
-                  s->Address);
-        return err_push(err, MM_ERR_REALLOC_RANGE);
-    }
-
-    /*
-    err = devframe_type(&devframe, devmem, BASE_PAGE_BITS);
-    if (err_is_fail(err)) {
-        return err_push(err, LIB_ERR_DEVFRAME_TYPE);
-    }*/
-
-    devframe = devmem;
-
-    // Map registers
-    err = vspace_map_one_frame_attr((void**)&vaddr, IOAPIC_PAGE_SIZE, devframe,
-                                    VREGION_FLAGS_READ_WRITE_NOCACHE,
-                                    NULL, NULL);
-    if (err_is_fail(err)) {
-        return err_push(err, LIB_ERR_VSPACE_MAP);
-    }
-
-    // Initialize driver
-    struct ioapic *ioapic = &ioapics[ioapic_nr++];
-
-    err = ioapic_init(ioapic, vaddr, s->Id, s->GlobalIrqBase);
-    if (err_is_fail(err)) {
-        ACPI_DEBUG("I/O APIC init failed!\n");
-        return err_push(err, PCI_ERR_IOAPIC_INIT);
-    }
-
-    // Set redirection table entry defaults for managed buses
-    for(int i = 0; i < ioapic->nintis; i++) {
-        if(s->GlobalIrqBase + i < N_ISA_INTERRUPTS) {
-            // ISA interrupts go to GSIs 0 .. 15
-            ioapic_setup_inti(ioapic, i, ioapic_redir_tmpl_isa);
-        } else {
-            // Assume the rest is PCI
-            ioapic_setup_inti(ioapic, i, ioapic_redir_tmpl_pci);
-        }
-    }
-
-    return SYS_ERR_OK;
-}
-
-static int init_one_local_apic(ACPI_MADT_LOCAL_APIC *s, lpaddr_t base)
-{
-    // TODO: Bring up other cores here! But I think we need chips for
-    // better integration with other domains booted from init.
-    return 0;
-}
-
-int init_all_apics(void)
-{
-    ACPI_STATUS         as;
-    ACPI_TABLE_MADT     *madt;
-    ACPI_TABLE_HEADER   *ath;
-    int                 r;
-
-    static coreid_t barrelfish_id_counter = 1;
-
-    // default overrides
-    for (int i = 0; i < N_ISA_INTERRUPTS; i++) {
-        interrupt_overrides[i] = i;
-    }
-
-    // Get the ACPI APIC table (the MADT)
-    as = AcpiGetTable("APIC", 1, (ACPI_TABLE_HEADER **)&ath);
-
-    if(ACPI_FAILURE(as)) {
-        ACPI_DEBUG("No MADT found in ACPI! Cannot initialize I/O APICs.\n");
-        return -1;
-    }
-    else {
-        madt = (ACPI_TABLE_MADT*)ath;
-    }
-
-    // Parse main table entries
-    ACPI_DEBUG("Local APIC is at 0x%"PRIx32"\n", madt->Address);
-    skb_add_fact("memory_region(%" PRIu32 ",%u,%zu, %u,%u).",
-                 madt->Address,
-                 APIC_BITS, //from documentation
-                 ((size_t)1) << APIC_BITS, //from documentation
-                 RegionType_LocalAPIC,
-                 0);
-
-    if((madt->Flags & ACPI_MADT_PCAT_COMPAT) == ACPI_MADT_MULTIPLE_APIC) {
-        ACPI_DEBUG("This system also has dual-8259As.\n");
-    }
-
-    // Walk all subtables (after the main table entries)
-    void *p = (void *)madt + sizeof(ACPI_TABLE_MADT);
-    while(p < (void *)madt + madt->Header.Length) {
-        ACPI_SUBTABLE_HEADER *sh = (ACPI_SUBTABLE_HEADER *)p;
-
-        switch(sh->Type) {
-        case ACPI_MADT_TYPE_LOCAL_APIC:
-            {
-                ACPI_MADT_LOCAL_APIC *s = (ACPI_MADT_LOCAL_APIC *)sh;
-
-                ACPI_DEBUG("Found local APIC: CPU = %d, ID = %d, usable = %d\n",
-                       s->ProcessorId, s->Id,
-                       s->LapicFlags & ACPI_MADT_ENABLED);
-                trace_event(TRACE_SUBSYS_ACPI, TRACE_EVENT_ACPI_APIC_ADDED, s->ProcessorId);
-
-
-                coreid_t barrelfish_id;
-                if (my_apic_id == s->Id) {
-                    barrelfish_id = 0; // BSP core is 0
-                }
-                else {
-                    barrelfish_id = barrelfish_id_counter++;
-                }
-                errval_t err = oct_set("hw.processor.%d { processor_id: %d, apic_id: %d, enabled: %d, barrelfish_id: %d, type: %d }",
-                                         barrelfish_id, s->ProcessorId, s->Id,
-                                         s->LapicFlags & ACPI_MADT_ENABLED,
-                                         barrelfish_id, CURRENT_CPU_TYPE);
-                assert(err_is_ok(err));
-
-                skb_add_fact("apic(%d,%d,%"PRIu32").",
-                       s->ProcessorId, s->Id,
-                       s->LapicFlags & ACPI_MADT_ENABLED);
-
-                if(s->LapicFlags & ACPI_MADT_ENABLED) {
-                    r = init_one_local_apic(s, madt->Address);
-                    assert(r == 0);
-                }
-            }
-            break;
-
-        case ACPI_MADT_TYPE_IO_APIC:
-            {
-                ACPI_MADT_IO_APIC *s = (ACPI_MADT_IO_APIC *)sh;
-                errval_t err;
-
-                ACPI_DEBUG("Found I/O APIC: ID = %d, mem base = 0x%"PRIx32", "
-                       "INTI base = %"PRIu32"\n", s->Id, s->Address, s->GlobalIrqBase);
-
-                skb_add_fact("ioapic(%d,%"PRIu32",%"PRIu32").", s->Id, s->Address, s->GlobalIrqBase);
-                skb_add_fact("memory_region(%"PRIu32",%u,%zu, %u,%u).",
-                             s->Address,
-                             BASE_PAGE_BITS, //as used elswhere in acpi.c
-                             ((size_t)1) << BASE_PAGE_BITS, //as used elswhere in acpi.c
-                             RegionType_IOAPIC,
-                             0);
-
-                err = init_one_ioapic(s);
-                if(err_is_fail(err)) {
-                    DEBUG_ERR(err, "Unable to initialize I/O APIC (ID = %d)",
-                              s->Id);
-                    abort();
-                }
-            }
-            break;
-
-        case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
-            {
-                ACPI_MADT_INTERRUPT_OVERRIDE *s =
-                    (ACPI_MADT_INTERRUPT_OVERRIDE *)sh;
-
-                ACPI_DEBUG("Found interrupt override: bus = %d, bus_irq = %d, "
-                       "GSI = %"PRIu32", flags = %x\n", s->Bus, s->SourceIrq,
-                       s->GlobalIrq, s->IntiFlags);
-
-                skb_add_fact("interrupt_override(%d,%d,%"PRIu32",%d).",
-                            s->Bus, s->SourceIrq, s->GlobalIrq, s->IntiFlags);
-
-                // ACPI spec says these are only for ISA interrupts
-                assert(s->SourceIrq < N_ISA_INTERRUPTS);
-
-                interrupt_overrides[s->SourceIrq] = s->GlobalIrq;
-
-                if (s->IntiFlags == 0) {
-                    break;
-                }
-
-                lpc_ioapic_redir_tbl_t entry = ioapic_redir_tmpl_isa;
-                struct ioapic *a = find_ioapic(s->GlobalIrq);
-                if (a == NULL) {
-                    ACPI_DEBUG("Warning: unknown IOAPIC for GSI %"PRIu32", ignored"
-                              " interrupt override flags.\n", s->GlobalIrq);
-                    break;
-                }
-
-                // Set polarity
-                assert((s->IntiFlags & ACPI_MADT_POLARITY_MASK)
-                       != ACPI_MADT_POLARITY_RESERVED);
-
-                switch(s->IntiFlags & ACPI_MADT_POLARITY_MASK) {
-                case ACPI_MADT_POLARITY_ACTIVE_HIGH:
-                    entry.polarity = lpc_ioapic_active_high;
-                    break;
-
-                case ACPI_MADT_POLARITY_ACTIVE_LOW:
-                    entry.polarity = lpc_ioapic_active_low;
-                    break;
-                }
-
-                // Set trigger mode
-                assert((s->IntiFlags & ACPI_MADT_TRIGGER_MASK)
-                       != ACPI_MADT_TRIGGER_RESERVED);
-
-                switch(s->IntiFlags & ACPI_MADT_TRIGGER_MASK) {
-                case ACPI_MADT_TRIGGER_EDGE:
-                    entry.trigger = lpc_ioapic_edge;
-                    break;
-
-                case ACPI_MADT_TRIGGER_LEVEL:
-                    // XXX: should be lpc_ioapic_level
-                    entry.trigger = lpc_ioapic_edge;
-                    break;
-                }
-
-                ioapic_setup_inti(a, s->GlobalIrq - a->irqbase, entry);
-            }
-            break;
-
-        case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
-            {
-                ACPI_MADT_LOCAL_APIC_NMI *s = (ACPI_MADT_LOCAL_APIC_NMI *)sh;
-
-                ACPI_DEBUG("Found local APIC NMI: CPU ID = %d, flags = %x, "
-                       "LINT = %d\n", s->ProcessorId, s->IntiFlags, s->Lint);
-
-                skb_add_fact("apic_nmi(%d,%d,%d).",s->ProcessorId, s->IntiFlags,
-                                                   s->Lint);
-
-                ACPI_DEBUG("Ignoring for now.\n");
-            }
-            break;
-        case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
-            {
-            ACPI_MADT_GENERIC_INTERRUPT *gi = (ACPI_MADT_GENERIC_INTERRUPT *)sh;
-
-            ACPI_DEBUG("Found local APIC GENERIC_INTERRUPT: BaseAddress=0x%016"
-                       PRIx64 ", GicvBaseAddress=0x%016" PRIx64
-                       ", GichBaseAddress=0x%016" PRIx64
-                       ", GicrBaseAddress=0x%016" PRIx64
-                       ", CpuInterfaceNumber=%" PRIu32 ", Uid=%" PRIu32 "\n",
-                       gi->BaseAddress, gi->GicvBaseAddress, gi->GichBaseAddress,
-                       gi->GicrBaseAddress, gi->CpuInterfaceNumber, gi->Uid);
-
-            coreid_t barrelfish_id;
-            if (my_apic_id == gi->CpuInterfaceNumber) {
-                barrelfish_id = 0; // BSP core is 0
-            }
-            else {
-                barrelfish_id = barrelfish_id_counter++;
-            }
-
-            /* TODO: figure out which facts you need */
-            skb_add_fact("generic_interrupt(%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%d).",
-                    gi->BaseAddress, gi->GicvBaseAddress, gi->GichBaseAddress,
-                    gi->GicrBaseAddress, gi->CpuInterfaceNumber);
-
-
-            errval_t err = oct_set("hw.processor.%d { processor_id: %d, apic_id: %d, enabled: "
-                                   "%d, barrelfish_id: %d, type: %d }",
-                                   barrelfish_id, gi->CpuInterfaceNumber, gi->Uid,
-                                   gi->Flags & ACPI_MADT_ENABLED,
-                                   barrelfish_id, CURRENT_CPU_TYPE);
-            assert(err_is_ok(err));
-/*
-            TODO: represent it as apic ? probably not ?
-            skb_add_fact("apic(%d,%d,%"PRIu32").",
-                          gi->CpuInterfaceNumber, gi->CpuInterfaceNumber,
-                          gi->Flags & ACPI_MADT_ENABLED);
-*/
-            }
-
-            break;
-        case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
-            {
-            ACPI_MADT_GENERIC_DISTRIBUTOR *gd = (ACPI_MADT_GENERIC_DISTRIBUTOR *)sh;
-            ACPI_DEBUG("Found local APIC GENERIC DISTRIBUTOR: BaseAddress=0x%016"
-                                   PRIx64 ", GicId=%" PRIu32 ", Version=%" PRIu8
-                                   ", GlobalIrqBase=%" PRIu32 "\n", gd->BaseAddress,
-                                   gd->GicId , gd->Version, gd->GlobalIrqBase);
-            skb_add_fact("generic_distributor(%"PRIu64",%d,%d,%d).",
-                         gd->BaseAddress, gd->GicId, gd->GlobalIrqBase, gd->Version);
-            }
-            break;
-        case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
-            {
-            ACPI_MADT_GENERIC_MSI_FRAME *msi = (ACPI_MADT_GENERIC_MSI_FRAME *)sh;
-            ACPI_DEBUG("Found local APIC GENERIC MSI FRAME: BaseAddress=0x%016"
-                       PRIx64 ", MsiFrameId=%" PRIu32 "\n", msi->BaseAddress,
-                       msi->MsiFrameId);
-            skb_add_fact("generic_msi_frame(%"PRIu64",%d,%d,%d,%d).",
-                         msi->BaseAddress, msi->MsiFrameId, msi->SpiBase,
-                         msi->SpiBase, msi->Flags);
-            }
-            break;
-        case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
-        {
-            ACPI_MADT_GENERIC_REDISTRIBUTOR *grd = (ACPI_MADT_GENERIC_REDISTRIBUTOR *)sh;
-            ACPI_DEBUG("Found local APIC GENERIC REDISTRIBUTOR: BaseAddress=0x%016"
-                        PRIx64 ", Length=%" PRIu32 "\n", grd->BaseAddress,
-                        grd->Length);
-            skb_add_fact("generic_redistributor(%"PRIu64",%d).",
-                         grd->BaseAddress, grd->Length);
-        }
-            break;
-        case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
-        {
-            ACPI_MADT_GENERIC_TRANSLATOR *gt = (ACPI_MADT_GENERIC_TRANSLATOR *)sh;
-            ACPI_DEBUG("Found local APIC GENERIC TRANSLATOR: TranslationId=%"
-                        PRIu32 ", BaseAddress=0x%016" PRIx64 "\n", gt->TranslationId,
-                        gt->BaseAddress);
-            skb_add_fact("generic_translator(%"PRIu64",%d).",
-                         gt->BaseAddress, gt->TranslationId);
-        }
-            break;
-        default:
-            ACPI_DEBUG("Unknown subtable type %d\n", sh->Type);
-            break;
-        }
-
-        p += sh->Length;
-    }
-
-
-    /* XXX: Quirk hack for QEMU
-     * There is no override for the timer interrupt, although it appears as IRQ2.
-     */
-    if (strncmp(madt->Header.OemId, "QEMU", 4) == 0
-        && interrupt_overrides[0] == 0) {
-        interrupt_overrides[0] = 2;
-        printf("added missing override from GSI 0 to INTI 2 on QEMU\n");
-    }
-
-    return 0;
-}
-
-errval_t enable_and_route_interrupt(int gsi, coreid_t dest, int vector)
-{
-    /* sanity-check vector */
-    // XXX: this check matches the use of vectors in the kernel's irq.c
-    if (vector < 0 || vector >= (250 - 32)) {
-        return PCI_ERR_INVALID_VECTOR;
-    }
-
-    /* convert to CPU vector */
-    vector += 32;
-
-    /* lookup override table */
-    int gsi_mapped;
-    if (gsi < N_ISA_INTERRUPTS) {
-        gsi_mapped = interrupt_overrides[gsi];
-    } else {
-        gsi_mapped = gsi;
-    }
-
-    /* find the correct IOAPIC */
-    struct ioapic *i = find_ioapic(gsi_mapped);
-    if (i == NULL) {
-        return PCI_ERR_UNKNOWN_GSI;
-    }
-
-    // Resolve destination core ID to APIC ID
-    char *result = NULL, *str_error = NULL, query[256];
-    int32_t int_error = 0;
-    int r = snprintf(query, 256, "corename(%d, _, apic(A)), write(A).", dest);
-    assert(r >= 0 && r < 256);
-    errval_t err = skb_evaluate(query, &result, &str_error, &int_error);
-    assert(err_is_ok(err));
-    assert(result != NULL);
-    free(str_error);
-
-    // If SKB didn't have an answer, we assume we're not done setting up
-    // mappings yet. In this case, we can only resolve our own core ID.
-    uint8_t dest_apicid;
-    if(*result == '\0') {
-        if(dest != disp_get_core_id()) {
-            USER_PANIC("SKB couldn't resolve core ID and it's not this core's "
-                       "ID, giving up.");
-        }
-
-        dest_apicid = my_apic_id;
-    } else {
-        dest_apicid = strtol(result, &str_error, 10);
-        assert(*str_error == '\0');
-    }
-    free(result);
-
-    /* route to the given core */
-    int inti = gsi_mapped - i->irqbase;
-    ioapic_route_inti(i, inti, vector, dest_apicid);
-
-    printf("routing GSI %d -> %d -> INTI %d -> APIC %d (coreid %d) "
-              "vector %d\n", gsi, gsi_mapped, inti, dest_apicid, dest, vector);
-
-    /* enable */
-    ioapic_toggle_inti(i, inti, true);
-
-    return SYS_ERR_OK;
-}
index 2bc94c4..71e75ca 100644 (file)
@@ -24,8 +24,6 @@ struct ioapic {
     uint32_t            irqbase;
 };
 
-extern uintptr_t my_apic_id;
-
 errval_t ioapic_init(struct ioapic *a, lvaddr_t base, uint8_t id,
                      uint32_t irqbase);
 void ioapic_toggle_inti(struct ioapic *a, int inti, bool enable);
@@ -34,6 +32,6 @@ void ioapic_setup_inti(struct ioapic *a, int inti,
 void ioapic_route_inti(struct ioapic *a, int inti, uint8_t vector,
                        uint8_t dest);
 errval_t enable_and_route_interrupt(int gsi, coreid_t dest, int vector);
-int init_all_apics(void);
+
 
 #endif
diff --git a/usr/ahcid/Hakefile b/usr/ahcid/Hakefile
deleted file mode 100644 (file)
index f954974..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
---------------------------------------------------------------------------
--- Copyright (c) 2007-2011, 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, Universitaetsstr. 6, CH-8092 Zurich. Attn: Systems Group.
---
--- Hakefile for /usr/drivers/ahci
--- 
---------------------------------------------------------------------------
-
-[ build application { target = "ahcid",
-                      cFiles = [ "ahcid.c", "ahcid_hwinit.c" ],
-                      flounderBindings = [ "ahci_mgmt" ],
-                      mackerelDevices = [ "ahci_hba", "ahci_port", "ata_identify" ],
-                      addLibraries = [ "pci", "skb", "ahci" ]
-                    }
-]
-
diff --git a/usr/ahcid/ahcid.c b/usr/ahcid/ahcid.c
deleted file mode 100644 (file)
index bde74e7..0000000
+++ /dev/null
@@ -1,643 +0,0 @@
-/*
- * Copyright (c) 2011 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 <stdio.h>
-#include <string.h>
-#include "ahcid.h"
-#include <barrelfish/waitset.h>
-#include <barrelfish/syscalls.h>
-#include <barrelfish/nameservice_client.h>
-#include <pci/pci.h>
-#include <if/ahci_mgmt_defs.h>
-#include <skb/skb.h>
-#include <ahci/sata_fis.h>
-#include <ahci/ahci_dma_pool.h>
-#include <dev/ahci_hba_dev.h>
-#include <dev/ata_identify_dev.h>
-#include "ahcid_debug.h"
-
-#define PCI_DEVICE_ICH9R_82801IR 0x2922
-#define PCI_DEVICE_ICH10_82801JI 0x3a22
-#define PCI_DEVICE_SB7x0 0x4390 // also SB8x0 SB9x0
-
-static ahci_hba_t controller;
-static uint8_t num_ports = -1;
-static struct ahcid_port_info **ports;
-
-static struct ahci_mgmt_binding **port_bindings;
-
-static char *my_service_name = "ahcid";
-
-static struct device_mem hbabar;
-
-#if defined(AHCI_SERVICE_DEBUG) || defined(GLOBAL_DEBUG)
-    static bool initialized = false;
-#endif
-
-struct device_id {
-    uint32_t vendor;
-    uint32_t device;
-};
-
-static void rx_list_call(struct ahci_mgmt_binding *b)
-{
-    AHCID_DEBUG("got list call\n");
-    uint8_t port;
-    uint8_t current_num_ports = (num_ports == (uint8_t)-1 ? 0 : num_ports);
-    uint8_t next_port = 0;
-    uint8_t *port_ids = malloc(current_num_ports);
-    for (port = 0; port < current_num_ports; port++) {
-        if (ports[port] && ports[port]->status == AHCID_PORT_STATUS_IDLE) {
-            port_ids[next_port++] = port;
-        }
-        else if (ports[port]) {
-            AHCID_DEBUG("skipping port %u with status %d\n",
-                    (unsigned int)port, (int)ports[port]->status);
-        }
-    }
-    AHCID_DEBUG("responding to list call with %u port_ids\n", (unsigned int)next_port);
-    ahci_mgmt_list_response__tx(b, MKCLOSURE(free, port_ids), port_ids, next_port);
-}
-
-static void rx_identify_call(struct ahci_mgmt_binding *b, uint8_t port_id)
-{
-    AHCID_DEBUG("got identify call\n");
-    if (ports[port_id] && ports[port_id]->status == AHCID_PORT_STATUS_IDLE) {
-        AHCID_DEBUG("responding...\n");
-        ahci_mgmt_identify_response__tx(b, NOP_CONT,
-                (uint8_t*)ports[port_id]->identify_data, 512);
-    }
-    else {
-        AHCID_DEBUG("not responding...\n");
-    }
-}
-
-static void rx_open_call(struct ahci_mgmt_binding *b, uint8_t port_id)
-{
-    AHCID_DEBUG("got open call\n");
-    if (ports[port_id] == NULL) {
-        ahci_mgmt_open_response__tx(b, NOP_CONT, AHCI_ERR_PORT_INVALID,
-                NULL_CAP, 0, 0);
-        return;
-    }
-    if (ports[port_id]->binding != NULL) {
-        ahci_mgmt_open_response__tx(b, NOP_CONT, AHCI_ERR_PORT_BUSY,
-                NULL_CAP, 0, 0);
-        return;
-    }
-    ports[port_id]->binding = b;
-    // find correct frame cap for port. should be a single cap as long as FRAME_SIZE > 0x80b.
-    uint32_t cap_size = hbabar.bytes / hbabar.nr_caps;
-    uint32_t offset = ahcid_port_offset(port_id);
-    int cap_index = 0;
-    while (offset >= cap_size) { cap_index++; offset -= cap_size; }
-
-    ahci_mgmt_open_response__tx(b, NOP_CONT, SYS_ERR_OK,
-            hbabar.frame_cap[cap_index], offset, ahci_hba_cap_rd(&controller));
-}
-
-static void rx_close_call(struct ahci_mgmt_binding *b, uint8_t port_id)
-{
-    AHCID_DEBUG("got close call\n");
-    if (ports[port_id] == NULL) {
-        ahci_mgmt_close_response__tx(b, NOP_CONT, AHCI_ERR_PORT_INVALID);
-        return;
-    }
-    errval_t retval = AHCI_ERR_PORT_MISMATCH;
-    if (ports[port_id]->binding == b) {
-        ports[port_id]->binding = NULL;
-        retval = SYS_ERR_OK;
-    }
-    ahci_mgmt_close_response__tx(b, NOP_CONT, retval);
-    return;
-}
-
-static struct ahci_mgmt_rx_vtbl rx_vtbl = {
-    .list_call = rx_list_call,
-    .list_response = NULL,
-    .identify_call = rx_identify_call,
-    .identify_response = NULL,
-    .open_call = rx_open_call,
-    .open_response = NULL,
-    .close_call = rx_close_call,
-    .close_response = NULL,
-    .command_completed = NULL,
-};
-
-static void export_cb(void *st, errval_t err, iref_t iref)
-{
-    if (err_is_fail(err)) {
-        USER_PANIC_ERR(err, "export failed");
-    }
-
-    AHCID_DEBUG("service exported at iref %u\n", iref);
-
-    // register this iref with the name service
-    err = nameservice_register(my_service_name, iref);
-    if (err_is_fail(err)) {
-        USER_PANIC_ERR(err, "nameservice_register failed");
-    }
-}
-
-static errval_t connect_cb(void *st, struct ahci_mgmt_binding *b)
-{
-    AHCID_DEBUG("got a connection!\n");
-
-    // copy my message receive handler vtable to the binding
-    b->rx_vtbl = rx_vtbl;
-
-    // accept the connection (we could return an error to refuse it)
-    return SYS_ERR_OK;
-}
-
-static void do_identify(struct ahcid_port_info *port)
-{
-    errval_t r;
-
-    // allocate frame for command table
-    struct ahci_dma_region *command_table;
-    r = ahci_dma_region_alloc(0x90, &command_table);
-    assert(err_is_ok(r));
-
-    // write command into command list
-    ahci_port_chdr_t commandlist = (ahci_port_chdr_t)port->command_list->vaddr;
-    memset(commandlist, 0, ahci_port_chdr_size);
-
-#if defined(AHCI_SERVICE_DEBUG) || defined(GLOBAL_DEBUG)
-    char buf[4096];
-    ahci_port_chdr_prtval(buf, 4096, commandlist);
-    AHCID_DEBUG("Command Header: \n");
-    puts(buf);
-#endif
-
-    // allocate dma region for identify result
-    struct ahci_dma_region **prd = calloc(1, sizeof(struct ahci_dma_region*));
-    r = ahci_dma_region_alloc(512, prd);
-    assert(err_is_ok(r));
-
-    memset((*prd)->vaddr, 0, 512);
-    port->prdts = prd;
-    port->prdt_count = 1;
-
-    ahci_port_chdr_w_insert(commandlist, 0); // dma on receive
-    ahci_port_chdr_a_insert(commandlist, 0);
-    ahci_port_chdr_cfl_insert(commandlist, 5);
-
-    // set dma region for identify result
-    ahci_port_chdr_prdtl_insert(commandlist, 1); // we use 1 PRD
-    ahci_port_chdr_ctba_insert(commandlist, (uint32_t)command_table->paddr);
-    ahci_port_chdr_ctbau_insert(commandlist, (uint32_t)(command_table->paddr>>32));
-
-
-    //char buf[4096];
-#if defined(AHCI_SERVICE_DEBUG) || defined(GLOBAL_DEBUG)
-    ahci_port_chdr_prtval(buf, 4096, commandlist);
-    AHCID_DEBUG("Command Header: \n");
-    puts(buf);
-#endif
-
-    // fill command table
-    memset(command_table->vaddr, 0, 0x90);
-
-    // FIS
-    struct sata_fis_reg_h2d *fis = command_table->vaddr;
-    fis->type = SATA_FIS_TYPE_H2D;
-    fis->command = 0xEC /* ATA_CMD_IDENTIFY */;
-    fis->device = 0;
-    fis->specialstuff = 0x80 /* command */;
-
-    // place PRD into PRDT which is at offset 0x80
-    uint32_t *prdt_entry = command_table->vaddr + 0x80;
-    prdt_entry[0] = (*prd)->paddr;
-    prdt_entry[3] = 511; // again this +1 thingy
-
-    // ensure command processing is on
-    ahci_port_cmd_t cmd = ahci_port_cmd_rd(&port->port);
-    assert(ahci_port_cmd_cr_extract(cmd) == 1);
-
-    // issue command in slot 0
-    ahci_port_ci_wr(&port->port, 1);
-
-    AHCID_DEBUG("Issued IDENTIFY command\n");
-
-    port->status = AHCID_PORT_STATUS_IDENTIFY_PENDING;
-}
-
-
-static void ahci_init(struct device_mem *bar_info, int nr_allocated_bars)
-{
-    // re-usable vars
-    int i;
-    char buf[4096];
-    errval_t r;
-
-    // registers
-    ahci_hba_ghc_t ghc;
-
-    // find BAR and map device data
-    AHCID_DEBUG("nr_allocated_bars = %d\n", nr_allocated_bars);
-    assert(nr_allocated_bars >= 1);
-    // Although the AHCI specification requires the AHCI memory region to be in
-    // BAR 5 (BAR 0 to 4 are used for legacy IDE mode) the QEMU AHCI emulation
-    // incorrectly uses BAR 0.  Because of this, ahcid consults both BAR 0 and
-    // BAR 5 to find the HBA's memory mapped I/O region.
-    if (nr_allocated_bars == 1) { // handle QEMU
-        memcpy(&hbabar, &bar_info[0], sizeof(struct device_mem));
-    } else if (nr_allocated_bars == 6) { // handle HW (AHCI in BAR 5)
-        memcpy(&hbabar, &bar_info[5], sizeof(struct device_mem));
-    } else {
-        AHCID_DEBUG("strange device... not supported\n");
-        abort();
-    }
-
-    map_device(&hbabar);
-    ahci_hba_initialize(&controller, (void *)(hbabar.vaddr));
-    AHCID_DEBUG("accessing conf regs starting at %p\n",
-            (void *)(hbabar.vaddr));
-    AHCID_DEBUG("physical address of conf regs: %p\n",
-            (void *)(hbabar.paddr));
-
-    // first of all, reset the device for fun and profit
-    ghc = ahci_hba_ghc_rd(&controller);
-    ghc = ahci_hba_ghc_hr_insert(ghc, 1);
-    AHCID_DEBUG("Resetting HBA (setting ghc = %x)...\n", ghc);
-    ahci_hba_ghc_wr(&controller, ghc);
-
-    // spec: "the device shall reset this bit to '0' " so we will wait
-    while (1) {
-        ghc = ahci_hba_ghc_rd(&controller);
-        if (ahci_hba_ghc_hr_extract(ghc) == 0) {
-            AHCID_DEBUG("reset done\n");
-            break;
-        }
-        sys_yield(CPTR_NULL);
-    }
-
-    // set HBA into AHCI mode
-    AHCID_DEBUG("Setting controller into AHCI mode\n");
-    ghc = ahci_hba_ghc_rd(&controller);
-    ghc = ahci_hba_ghc_ae_insert(ghc, 1);
-    ahci_hba_ghc_wr(&controller, ghc);
-
-    // disable interrupts for the moment during setup
-    ghc = ahci_hba_ghc_rd(&controller);
-    if (ahci_hba_ghc_ie_extract(ghc) == 1) {
-        AHCID_DEBUG("Interrupts are enabled. Disabling them during setup\n");
-        ghc = ahci_hba_ghc_ie_insert(ghc, 1);
-        ahci_hba_ghc_wr(&controller, ghc);
-    } else {
-        AHCID_DEBUG("Interrupts are disabled (as expected after a reset)\n");
-    }
-
-    // get number of ports the HBA supports
-    // AHCI spec 1.3, section 3.1.1; bits 0-4 specify number of ports, 0 being 1 port
-    num_ports = ahci_hba_cap_np_extract(ahci_hba_cap_rd(&controller)) + 1;
-    AHCID_DEBUG("HBA supports %d ports\n", num_ports);
-
-    ports = calloc(num_ports, sizeof(struct ahcid_port_info*));
-    port_bindings = calloc(num_ports, sizeof(struct ahci_mgmt_binding*));
-
-    // enable interrupts again
-    ghc = ahci_hba_ghc_rd(&controller);
-    ghc = ahci_hba_ghc_ie_insert(ghc, 1);
-    AHCID_DEBUG("Enabling HBA Interrupts\n");
-    ahci_hba_ghc_wr(&controller, ghc);
-
-    // init dma pool
-    r = ahci_dma_pool_init(1024 * 1024);
-
-    // initialize ports
-    r = ahcid_ports_init(ports, num_ports, ahci_hba_pi_rd(&controller),
-            (void *)(hbabar.vaddr));
-
-    for (i = 0; i < num_ports; i++) {
-        if (ports[i] != NULL) {
-            // read port state
-            ahci_port_ssts_t ssts = ahci_port_ssts_rd(&ports[i]->port);
-            if (ahci_port_ssts_det_extract(ssts) == ahci_port_detect) {
-                // we have a device
-                ahci_port_speed_prtval(buf, 4096, ahci_port_ssts_spd_extract(ssts));
-                AHCID_DEBUG("Device detected! Port: %d Type: %s\n", i, buf);
-
-                // enable all interrupts of this port
-                ahci_port_ie_wr(&ports[i]->port, -1);
-
-                // Clear PxSERR
-                ahci_port_serr_wr(&ports[i]->port, -1);
-
-                // wait until device is ready
-                ahci_port_tfd_pr(buf, 4096, &ports[i]->port);
-                AHCID_DEBUG("TFD: \n%s\n", buf);
-                AHCID_DEBUG("Waiting for device to become ready\n");
-                uint32_t taskfile;
-                while (1) {
-                    taskfile = ahci_port_tfd_rd(&ports[i]->port);
-                    // 7: BSY, 3: DRQ, 0: ERR
-                    if ((ahci_port_tfd_sts_extract(taskfile) & 0x89) == 0) {
-                        AHCID_DEBUG("Device ready\n");
-                        break;
-                    }
-                }
-
-                // start running commands
-                ahci_port_cmd_t cmd = ahci_port_cmd_rd(&ports[i]->port);
-                cmd = ahci_port_cmd_st_insert(cmd, 1);
-                ahci_port_cmd_wr(&ports[i]->port, cmd);
-
-                // send identify command to device
-                do_identify(ports[i]);
-            }
-        }
-    }
-
-    // export ahci management interface
-    ahci_mgmt_export(NULL /* state pointer for connect/export callbacks */,
-            export_cb, connect_cb, get_default_waitset(),
-            IDC_EXPORT_FLAGS_DEFAULT);
-
-#if defined(AHCI_SERVICE_DEBUG) || defined(GLOBAL_DEBUG)
-    initialized = true;
-#endif
-
-}
-
-static void ahci_interrupt_handler(void *arg)
-{
-    uint32_t hba_irq_state = ahci_hba_is_rd(&controller);
-
-    if (hba_irq_state == 0) {
-#ifdef AHCI_SERVICE_DEBUG
-        static uint32_t verb_count = 0;
-        verb_count++;
-        if (verb_count % 1 == 0) {
-            AHCID_DEBUG("Ignoring foreign interrupt\n");
-            AHCID_DEBUG("Port 0 Interrupt State: %"PRIu32"\n",
-                    ahci_port_is_rd(&ports[0]->port));
-            AHCID_DEBUG("Port 0 Command Issue state: %"PRIu32"\n",
-                    ahci_port_ci_rd(&ports[0]->port));
-        }
-#endif
-        // just ignore foreign interrupts
-        return;
-    }
-
-    bool interrupted_ports[32] = {false};
-    ahci_port_is_t interrupt_state[32] = {0};
-
-    int i = 0;
-    for (; i < 32; i++) { // check which ports have irq flag set
-        if ((hba_irq_state & (1 << i)) && ports[i]) {
-            AHCID_DEBUG("Interrupt for port %d\n", i);
-
-            ahci_port_is_t port_state = ahci_port_is_rd(&ports[i]->port);
-
-            // clear interrupts for port asap. (this is what FreeBSD also does)
-            ahci_port_is_wr(&ports[i]->port, port_state);
-
-            // process IDENTIFY response: QEMU sends D2H Register FIS, Spec.
-            // says device should send a PIO Setup FIS. We handle both for now :)
-            if ((ahci_port_is_dhrs_extract(port_state) == 1 ||
-                        ahci_port_is_pss_extract(port_state)) &&
-                    ports[i]->status == AHCID_PORT_STATUS_IDENTIFY_PENDING) {
-                // we got a d2h register or pio setup fis
-                uint8_t *d2hr_fis = ports[i]->receive_fis->vaddr +
-                    0x40 /* D2H Register FIS offset in rFIS */;
-                uint8_t *pss_fis = ports[i]->receive_fis->vaddr +
-                    0x20 /* D2H Register FIS offset in rFIS */;
-                uint8_t *fis;
-                if (ahci_port_is_dhrs_extract(port_state)) {
-                    // QEMU case: QEMU sends a D2H Register FIS as answer to
-                    // IDENTIFY Device (0xEC).
-                    // This is *NOT* according to AT Attachement 8, Sect. 7.16
-                    // IDENTIFY DEVICE which specifies PIO Data-in.
-                    // This does not change anything in handling the actual
-                    // IDENTIFY data, which is still stored in the indicated
-                    // DMA region.
-                    fis = d2hr_fis;
-                    if (fis[0] != SATA_FIS_TYPE_D2H) {
-                        AHCID_DEBUG("Interrupt signalled D2H Reg FIS but the"
-                                " FIS has another type (0x%02x)\n", fis[0]);
-                        continue; // handle next port
-                    }
-                }
-                else if (ahci_port_is_pss_extract(port_state)) {
-                    // ATA-8 compliant case. Real hardware seems to do this.
-                    // PIO Setup FIS should mean that we need to receive data
-                    // afterwards.
-                    // However the AHCI HBA handles that for us and copies the
-                    // received data into the DMA region specified in the
-                    // IDENTIFY command.
-                    fis = pss_fis;
-                    if (fis[0] != SATA_FIS_TYPE_PIO) {
-                        AHCID_DEBUG("Interrupt signalled PIO Setup FIS but the"
-                                " FIS has another type (0x%02x)\n", fis[0]);
-                        continue; // handle next port
-                    }
-                }
-
-                int identify_received = 1;
-                if (ports[i]->prdts != NULL && ports[i]->prdt_count == 1) {
-                    AHCID_DEBUG("coping data from IDENTIFY result on %d\n", i);
-                    memcpy(ports[i]->identify_data, ports[i]->prdts[0]->vaddr, 512);
-                    ata_identify_t identify;
-                    ata_identify_initialize(&identify,
-                            (char *)ports[i]->identify_data);
-#ifdef AHCI_SERVICE_DEBUG
-                    char buf[32768];
-                    ata_identify_pr(buf, 32768, &identify);
-                    puts(buf);
-#endif
-                }
-                else {
-                    AHCID_DEBUG("PRDTL structures not set up for port %d while"
-                            " processing IDENTIFY response.\n", i);
-                    identify_received = 0;
-                }
-
-                // uninitialize port
-                //  clear interrupts
-                ahci_port_is_wr(&ports[i]->port, -1);
-                //  disable all interrupts of this port
-                AHCID_DEBUG("disabling interrupts for %d\n", i);
-                ahci_port_ie_wr(&ports[i]->port, 0);
-                //  stop running commands
-                AHCID_DEBUG("stopping %d\n", i);
-                ahci_port_cmd_t cmd = ahci_port_cmd_rd(&ports[i]->port);
-                cmd = ahci_port_cmd_st_insert(cmd, 0);
-                ahci_port_cmd_wr(&ports[i]->port, cmd);
-                // free CL, rFIS
-                AHCID_DEBUG("clearing clb and fb for %d\n", i);
-                ahci_port_clb_wr(&ports[i]->port, 0);
-                ahci_port_fb_wr(&ports[i]->port, 0);
-                AHCID_DEBUG("freeing memory for %d\n", i);
-                ahci_dma_region_free(ports[i]->command_list);
-                ahci_dma_region_free(ports[i]->receive_fis);
-                ahci_dma_region_free(ports[i]->prdts[0]);
-                free(ports[i]->prdts);
-                // add port to skb
-                // TODO: true unique port_ids, more info?
-                if (identify_received) {
-                    skb_add_fact("ahci_device(%d).", i);
-                    ports[i]->status = AHCID_PORT_STATUS_IDLE;
-                    AHCID_DEBUG("Processing IDENTIFY from port %d complete\n", i);
-                }
-                else {
-                    ports[i]->status = AHCID_PORT_STATUS_UNINITIALIZED;
-                }
-                continue;
-            }
-#if defined(AHCI_SERVICE_DEBUG) || defined(GLOBAL_DEBUG)
-            else if (ports[i]->status == AHCID_PORT_STATUS_IDENTIFY_PENDING) {
-                AHCID_DEBUG("received unknown interrupt while waiting for"
-                        " IDENTIFY D2H Reg FIS\n");
-                char buf[2048];
-                ahci_port_is_prtval(buf, 2048, port_state);
-                AHCID_DEBUG("Port Status:\n");
-                puts(buf);
-            }
-#endif
-            if (ports[i]->binding != NULL) {
-                interrupted_ports[i] = true;
-                interrupt_state[i] = port_state;
-            } else {
-                AHCID_DEBUG("no client registered for port %d\n", i);
-            }
-        }
-    }
-
-    // clear interrupts for host controller
-    ahci_hba_is_wr(&controller, (uint32_t)-1);
-
-    // deliver messages to clients
-    for (i = 0; i < 32; i++) {
-        if (!interrupted_ports[i]) continue;
-
-        AHCID_DEBUG("Port %d Interrupt State: 0x%"PRIx32"\n",
-                i, interrupt_state[i]);
-        AHCID_DEBUG("Port %d Command Issue state: 0x%"PRIx32"\n",
-                i, ahci_port_ci_rd(&ports[i]->port));
-
-        ahci_mgmt_command_completed__tx(ports[i]->binding, NOP_CONT,
-                i, interrupt_state[i]);
-    }
-}
-
-static void ahci_reregister_handler(void *arg)
-{
-    errval_t err;
-    struct device_id *dev_id = arg;
-    err = pci_reregister_irq_for_device(PCI_CLASS_MASS_STORAGE, PCI_SUB_SATA,
-            PCI_DONT_CARE, dev_id->vendor, dev_id->device, PCI_DONT_CARE, PCI_DONT_CARE,
-            PCI_DONT_CARE, ahci_interrupt_handler, NULL,
-            ahci_reregister_handler, dev_id);
-    if (err_is_fail(err)) {
-        DEBUG_ERR(err, "pci_reregister_irq_for_device");
-    }
-
-    return;
-}
-
-static void polling_loop(void)
-{
-    errval_t err;
-    struct waitset *ws = get_default_waitset();
-    while (1) {
-#if defined(AHCI_SERVICE_DEBUG) || defined(GLOBAL_DEBUG)
-        if (controller.b != NULL) {
-            ahci_interrupt_handler(0);
-        }
-#endif
-        err = event_dispatch(ws);
-        if (err_is_fail(err)) {
-            DEBUG_ERR(err, "in event_dispatch");
-            break;
-        }
-    }
-}
-
-int main(int argc, char **argv)
-{
-    int r;
-
-    AHCID_DEBUG("starting\n");
-
-    //connect to the SKB
-    AHCID_DEBUG("connecting to the SKB...\n");
-    skb_client_connect();
-    AHCID_DEBUG("connected.\n");
-
-    r = pci_client_connect();
-    assert(err_is_ok(r));
-    AHCID_DEBUG("connected to pci\n");
-
-    if (argc >= 3) {
-        AHCID_DEBUG("got %s as vendor_id:device_id\n", argv[2]);
-        uint64_t vendor_id, device_id;
-        vendor_id = strtol(argv[2], NULL, 16);
-        device_id = strtol(argv[2]+5, NULL, 16);
-        struct device_id *dev_id = malloc(sizeof(*dev_id));
-        dev_id->vendor = vendor_id;
-        dev_id->device = device_id;
-        r = pci_register_driver_movable_irq(ahci_init, PCI_CLASS_MASS_STORAGE,
-                PCI_SUB_SATA, PCI_DONT_CARE, vendor_id,
-                device_id,
-                PCI_DONT_CARE, PCI_DONT_CARE, PCI_DONT_CARE,
-                ahci_interrupt_handler, NULL,
-                ahci_reregister_handler, dev_id);
-        if (err_is_fail(r)) {
-            printf("couldn't register device %04"PRIx64":%04"PRIx64": %s\n", vendor_id,
-                    device_id, err_getstring(r));
-            return 1;
-        }
-        printf("ahcid: registered device %04"PRIx64":%04"PRIx64"\n", vendor_id, device_id);
-    } else {
-        // fall-back: try some known AHCI devices
-        r = pci_register_driver_irq(ahci_init, PCI_CLASS_MASS_STORAGE,
-                PCI_SUB_SATA, PCI_DONT_CARE, PCI_VENDOR_INTEL,
-                PCI_DEVICE_ICH9R_82801IR /* QEMU ICH9R AHCI Controller */,
-                PCI_DONT_CARE, PCI_DONT_CARE, PCI_DONT_CARE,
-                ahci_interrupt_handler, NULL);
-        if (err_is_ok(r)) {
-            printf("ahcid: found QEMU ICH9R controller\n");
-            goto finish;
-        }
-        printf("ahcid: did not find QEMU ICH9R controller\n");
-
-        r = pci_register_driver_irq(ahci_init, PCI_CLASS_MASS_STORAGE,
-                PCI_SUB_SATA, PCI_DONT_CARE,
-                PCI_VENDOR_INTEL,
-                PCI_DEVICE_ICH10_82801JI /* 82801JI (ICH10 Family) AHCI Controller */,
-                PCI_DONT_CARE, PCI_DONT_CARE, PCI_DONT_CARE,
-                ahci_interrupt_handler, NULL);
-        if (err_is_ok(r)) {
-            printf("ahcid: found Sun Microsystems ICH10 Family controller\n");
-            goto finish;
-        }
-        printf("ahcid: did not find Sun Microsystems ICH10 Family controller\n");
-
-        r = pci_register_driver_irq(ahci_init, PCI_CLASS_MASS_STORAGE,
-                PCI_SUB_SATA, PCI_DONT_CARE,
-                PCI_VENDOR_ATI,
-                PCI_DEVICE_SB7x0 /* ATI SB7x0/SB8x0/SB9x0 SATA controller (IDE mode) */,
-                PCI_DONT_CARE, PCI_DONT_CARE, PCI_DONT_CARE,
-                ahci_interrupt_handler, NULL);
-        if (err_is_ok(r)) {
-            printf("ahcid: found ATI Technologies Inc. SB7x0/8x0/9x0 controller\n");
-            goto finish;
-        }
-        printf("ahcid: did not find ATI Technologies Inc. SB7x0/8x0/9x0 controller\n");
-        printf("ahcid: \ndid not find any supported AHCI controller\naborting...");
-        return 1;
-    }
-
-finish:
-    AHCID_DEBUG("registered driver: retval=%d\n", r);
-
-    polling_loop();
-}
diff --git a/usr/ahcid/ahcid.h b/usr/ahcid/ahcid.h
deleted file mode 100644 (file)
index 8a73c0c..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2011 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.
- */
-
-#ifndef AHCID_H_
-#define AHCID_H_
-#include <barrelfish/barrelfish.h>
-#include <dev/ahci_port_dev.h>
-#include <ahci/ahci_dma_pool.h>
-
-enum ahcid_port_status {
-    AHCID_PORT_STATUS_UNINITIALIZED = 0,
-    AHCID_PORT_STATUS_IDLE = 1,
-    AHCID_PORT_STATUS_IDENTIFY_PENDING,
-};
-
-struct ahcid_port_info {
-    ahci_port_t port;
-    struct ahci_dma_region *command_list;
-    struct ahci_dma_region *receive_fis;
-    enum ahcid_port_status status;
-    // XXX: use data in ahci_port_t?
-    struct ahci_dma_region **prdts;
-    size_t prdt_count;
-    uint16_t identify_data[256];
-    struct ahci_mgmt_binding *binding;
-};
-
-uint32_t ahcid_port_offset(uint32_t port);
-errval_t ahcid_ports_init(struct ahcid_port_info **ports, size_t num_ports,
-               uint32_t active_ports_bf, void* base_address);
-
-#endif //AHCID_H_
diff --git a/usr/ahcid/ahcid_debug.h b/usr/ahcid/ahcid_debug.h
deleted file mode 100644 (file)
index 187c151..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2011 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.
- */
-
-#ifndef AHCID_DEBUG_H_
-#define AHCID_DEBUG_H_
-
-
-/*****************************************************************
- * Debug printer:
- *****************************************************************/
-
-#if defined(AHCI_SERVICE_DEBUG) || defined(GLOBAL_DEBUG)
-#define AHCID_DEBUG(x...) printf("ahcid: " x)
-#else
-#define AHCID_DEBUG(x...) ((void)0)
-#endif
-
-#endif // AHCI_DEBUG_H_
diff --git a/usr/ahcid/ahcid_hwinit.c b/usr/ahcid/ahcid_hwinit.c
deleted file mode 100644 (file)
index 9976ee0..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2011 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 "ahcid.h"
-#include <ahci/ahci_dma_pool.h>
-#include <ahci/ahci_util.h>
-
-uint32_t ahcid_port_offset(uint32_t port)
-{
-    return 0x100 + port * 0x80;
-}
-
-errval_t ahcid_ports_init(struct ahcid_port_info **ports, size_t num_ports,
-        uint32_t active_ports_bf, void* base_address)
-{
-    errval_t r;
-    int i;
-    for (i = 0; i < num_ports; i++) {
-        if ((active_ports_bf >> i)&0x1) {
-            // only initialize implemented ports
-            ports[i] = calloc(1, sizeof(struct ahcid_port_info));
-            if (ports[i] == NULL) {
-                return LIB_ERR_MALLOC_FAIL;
-            }
-
-            ahci_port_initialize(&ports[i]->port, base_address + ahcid_port_offset(i));
-
-            // setup dma regions for command list and receive FIS area
-            r = ahci_port_alloc_dma_structs(&ports[i]->port,
-                           &ports[i]->command_list, &ports[i]->receive_fis);
-            assert(err_is_ok(r));
-
-            // enable rFIS area
-            ahci_port_cmd_t cmd = ahci_port_cmd_rd(&ports[i]->port);
-            cmd = ahci_port_cmd_fre_insert(cmd, 1);
-            ahci_port_cmd_wr(&ports[i]->port, cmd);
-        } else {
-            ports[i] = NULL;
-        }
-    }
-    return 0;
-}
-
diff --git a/usr/drivers/ahcid/Hakefile b/usr/drivers/ahcid/Hakefile
new file mode 100644 (file)
index 0000000..fe2070b
--- /dev/null
@@ -0,0 +1,29 @@
+--------------------------------------------------------------------------
+-- Copyright (c) 2007-2011, 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, Universitaetsstr. 6, CH-8092 Zurich. Attn: Systems Group.
+--
+-- Hakefile for /usr/drivers/ahci
+--
+--------------------------------------------------------------------------
+
+[
+    build application {
+        target = "ahcid",
+        mackerelDevices = [ "ata_identify", "ahci_port", "ahci_hba" ],
+        cFiles = [ "ahcid.c", "test.c" ],
+        addCFlags = ["-Wno-unused-variable", "-Wno-unused-function"],
+        addLibraries = [ "blk", "pci", "skb", "bench" ]
+    },
+
+    build application {
+        target = "ahci_test",
+        mackerelDevices = [ "ata_identify", "ahci_port", "ahci_hba" ],
+        cFiles = [ "ahcid.c", "test.c" ],
+        addCFlags = ["-DTESTING"],
+        addLibraries = [ "blk", "pci", "skb", "bench" ]
+    }
+]
diff --git a/usr/drivers/ahcid/ahcid.c b/usr/drivers/ahcid/ahcid.c
new file mode 100644 (file)
index 0000000..e698915
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2016 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 "ahcid.h"
+#include "test.h"
+
+void* dq = NULL;
+struct waitset disk_ws;
+
+static struct ahci_disk* ad;
+static volatile bool driver_initialized = false;
+static struct device_mem hbabar;
+static struct waitset_chanstate *chan = NULL;
+
+
+struct device_id {
+    uint16_t vendor;
+    uint16_t device;
+};
+
+static void ahci_interrupt_handler(void *arg)
+{
+    void devq_interrupt_handler(void*);
+    devq_interrupt_handler(dq);
+
+#ifdef DISABLE_INTERRUPTS
+    assert(chan != NULL);
+    assert(dq != NULL);
+    errval_t err = waitset_chan_register(&disk_ws, chan, MKCLOSURE(ahci_interrupt_handler, dq));
+    if (err_is_fail(err) && err_no(err) == LIB_ERR_CHAN_ALREADY_REGISTERED) {
+        printf("Got actual interrupt?\n");
+    }
+    else if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "Can't register our dummy channel.");
+    }
+    err = waitset_chan_trigger(chan);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "trigger failed.");
+    }
+#endif
+}
+
+static void do_ahci_init(struct device_mem* bar_info, int nr_allocated_bars)
+{
+    // Although the AHCI specification requires the AHCI memory region to be in
+    // BAR 5 (BAR 0 to 4 are used for legacy IDE mode) the QEMU AHCI emulation
+    // incorrectly uses BAR 0.  Because of this, ahcid consults both BAR 0 and
+    // BAR 5 to find the HBA's memory mapped I/O region.
+    // Since two BARs between 0-5 are I/O ports they are not passed to use by PCI.
+
+    if (nr_allocated_bars == 1) {
+        memcpy(&hbabar, &bar_info[0], sizeof(struct device_mem));
+    } else if (nr_allocated_bars == 3) {
+        memcpy(&hbabar, &bar_info[2], sizeof(struct device_mem));
+    } else {
+        printf("Strange device... not supported\n");
+        abort();
+    }
+
+    errval_t err = blk_ahci_init(&hbabar, &ad);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "AHCI HBA init failed.");
+    }
+
+    err = devq_create(ad, "", 0, &dq);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "devq create failed.");
+    }
+
+#if DISABLE_INTERRUPTS
+    waitset_init(&disk_ws);
+
+    // Hack: Why don't interrupts work?
+    chan = malloc(sizeof(struct waitset_chanstate));
+    waitset_chanstate_init(chan, CHANTYPE_AHCI);
+
+    err = waitset_chan_register(&disk_ws, chan, MKCLOSURE(ahci_interrupt_handler, dq));
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "waitset_chan_regster failed.");
+    }
+    err = waitset_chan_trigger(chan);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "trigger failed.");
+    }
+#endif
+
+    driver_initialized = true;
+}
+
+static void ahci_reregister_handler(void *arg)
+{
+    errval_t err;
+    struct device_id *dev_id = arg;
+    err = pci_reregister_irq_for_device(PCI_CLASS_MASS_STORAGE, PCI_SUB_SATA,
+            PCI_DONT_CARE, dev_id->vendor, dev_id->device, PCI_DONT_CARE, PCI_DONT_CARE,
+            PCI_DONT_CARE, ahci_interrupt_handler, NULL,
+            ahci_reregister_handler, dev_id);
+    if (err_is_fail(err)) {
+        DEBUG_ERR(err, "pci_reregister_irq_for_device");
+    }
+
+    return;
+}
+
+int main(int argc, char **argv)
+{
+    int r;
+    r = skb_client_connect();
+    assert(err_is_ok(r));
+    r = pci_client_connect();
+    assert(err_is_ok(r));
+
+    if (argc >= 3) {
+        printf("Got %s as vendor_id:device_id\n", argv[2]);
+        uint64_t vendor_id, device_id;
+        vendor_id = strtol(argv[2], NULL, 16);
+        device_id = strtol(argv[2]+5, NULL, 16);
+
+        struct device_id *dev_id = malloc(sizeof(*dev_id));
+        dev_id->vendor = vendor_id;
+        dev_id->device = device_id;
+
+        r = pci_register_driver_movable_irq(do_ahci_init, PCI_CLASS_MASS_STORAGE,
+                PCI_SUB_SATA, PCI_DONT_CARE, vendor_id, device_id,
+                PCI_DONT_CARE, PCI_DONT_CARE, PCI_DONT_CARE,
+                ahci_interrupt_handler, NULL,
+                ahci_reregister_handler, dev_id);
+        if (err_is_fail(r)) {
+            printf("Couldn't register device %04"PRIx64":%04"PRIx64": %s\n", vendor_id,
+                    device_id, err_getstring(r));
+            return 1;
+        }
+        printf("AHCID: registered device %04"PRIx64":%04"PRIx64"\n", vendor_id, device_id);
+    }
+    else {
+        printf("usage: ahcid <vendor id>:<device id>\n");
+        exit(1);
+    }
+    assert(driver_initialized);
+
+#ifdef TESTING
+    printf("Initialized driver, running tests:\n");
+    if (argc < 4) {
+        return 1;
+    }
+    if (strcmp(argv[3], "read|write") == 0) {
+        test_runner(2, AhciTest_READ, AhciTest_WRITE);
+    }
+    if (strcmp(argv[3], "read") == 0) {
+        test_runner(1, AhciTest_READ);
+    }
+    if (strcmp(argv[3], "write") == 0) {
+        test_runner(1, AhciTest_WRITE);
+    }
+    if (strcmp(argv[3], "verify") == 0) {
+        test_runner(1, AhciTest_VERIFY);
+    }
+#endif
+}
diff --git a/usr/drivers/ahcid/ahcid.h b/usr/drivers/ahcid/ahcid.h
new file mode 100644 (file)
index 0000000..041dfce
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016, 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef _AHCID_
+#define _AHCID_
+
+#include <stdio.h>
+#include <string.h>
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/waitset.h>
+#include <barrelfish/waitset_chan.h>
+#include <barrelfish/syscalls.h>
+#include <barrelfish/nameservice_client.h>
+#include <pci/pci.h>
+#include <skb/skb.h>
+#include <blk/ahci.h>
+#include <devif/queue.h>
+
+#define DISABLE_INTERRUPTS 1
+
+extern void* dq;
+extern struct waitset disk_ws;
+
+#endif // _AHCID_
diff --git a/usr/drivers/ahcid/test.c b/usr/drivers/ahcid/test.c
new file mode 100644 (file)
index 0000000..c540c09
--- /dev/null
@@ -0,0 +1,355 @@
+#include "ahcid.h"
+#include "test.h"
+
+#include <stdarg.h>
+#include <bench/bench.h>
+
+struct dma_mem {
+    lvaddr_t vaddr;         ///< virtual address of the mapped region
+    lpaddr_t paddr;         ///< physical address of the underlying frame
+    uint64_t bytes;         ///< size of the region in bytes
+    uint64_t requested;     ///< requested size of the region in bytes (<= bytes)
+    struct capref frame;    ///< frame capability backing this region
+};
+
+void test_runner(int n, ...)
+{
+    va_list arguments;
+    va_start(arguments, n);
+
+    for (size_t i=0; i<n; i++) {
+        enum AhciTest test = va_arg(arguments, enum AhciTest);
+        switch (test) {
+            case AhciTest_READ:
+                ahci_perf_sequential(1024*1024*1024, 512, false);
+                ahci_perf_sequential(1024*1024*1024, 1024, false);
+                ahci_perf_sequential(1024*1024*1024, 2048, false);
+                ahci_perf_sequential(1024*1024*1024, 4096, false);
+                ahci_perf_sequential(1024*1024*1024, 8192, false);
+                ahci_perf_sequential(1024*1024*1024, 16384, false);
+                ahci_perf_sequential(1024*1024*1024, 32768, false);
+                ahci_perf_sequential(1024*1024*1024, 65536, false);
+                ahci_perf_sequential(1024*1024*1024, 131072, false);
+                ahci_perf_sequential(1024*1024*1024, 262144, false);
+                ahci_perf_sequential(1024*1024*1024, 524288, false);
+                ahci_perf_sequential(1024*1024*1024, 1048576, false);
+                ahci_perf_sequential(1024*1024*1024, 1048576*2, false);
+                //ahci_perf_sequential(1024*1024*1024, 1048576*4, false); // ERROR: tilsiter1 OOM
+            break;
+
+            case AhciTest_WRITE:
+                ahci_perf_sequential(1024*1024*256, 512, true);
+                ahci_perf_sequential(1024*1024*256, 1024, true);
+                ahci_perf_sequential(1024*1024*256, 2048, true);
+                ahci_perf_sequential(1024*1024*256, 4096, true);
+                ahci_perf_sequential(1024*1024*256, 8192, true);
+                ahci_perf_sequential(1024*1024*256, 16384, true);
+                ahci_perf_sequential(1024*1024*256, 32768, true);
+                ahci_perf_sequential(1024*1024*256, 65536, true);
+                ahci_perf_sequential(1024*1024*256, 131072, true);
+                ahci_perf_sequential(1024*1024*256, 262144, true);
+                ahci_perf_sequential(1024*1024*256, 524288, true);
+                ahci_perf_sequential(1024*1024*256, 1048576, true);
+                ahci_perf_sequential(1024*1024*256, 1048576*2, true);
+                //ahci_perf_sequential(1024*1024*256, 1048576*4, true); // ERROR: tilsiter1 OOM
+            break;
+
+            case AhciTest_VERIFY:
+                ahci_verify_sequential(1024*1024*256, 512);
+                ahci_verify_sequential(1024*1024*256, 1024);
+                ahci_verify_sequential(1024*1024*256, 2048);
+                ahci_verify_sequential(1024*1024*256, 4096);
+                ahci_verify_sequential(1024*1024*256, 8192);
+                ahci_verify_sequential(1024*1024*256, 16384);
+                ahci_verify_sequential(1024*1024*256, 32768);
+                ahci_verify_sequential(1024*1024*256, 65536);
+                ahci_verify_sequential(1024*1024*256, 131072);
+                ahci_verify_sequential(1024*1024*256, 262144);
+                ahci_verify_sequential(1024*1024*256, 524288);
+                ahci_verify_sequential(1024*1024*256, 1048576);
+                ahci_verify_sequential(1024*1024*256, 1048576*2);
+                ahci_verify_sequential(1024*1024*256, 1048576*4);
+            break;
+
+            case AhciTest_BASIC:
+                ahci_simple_test();
+            break;
+
+            default:
+                USER_PANIC("Unknown test?");
+            break;
+        }
+    }
+
+    // Harness line
+    printf("AHCI testing completed.\n");
+}
+
+static void frame_alloc_identify(size_t size, struct capref *frame, struct frame_identity *id)
+{
+    errval_t err;
+    size_t retbytes;
+
+    err = frame_alloc(frame, size, &retbytes);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "frame_alloc");
+    }
+
+    err = invoke_frame_identify(*frame, id);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "invoke_frame_identify");
+    }
+}
+
+static void wait_for_interrupt(void)
+{
+    errval_t err = event_dispatch(&disk_ws);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "error in event_dispatch for wait_for_interrupt");
+    }
+}
+
+void ahci_simple_test(void)
+{
+    errval_t err;
+    regionid_t region_id = 0;
+    lpaddr_t base = 0;
+    size_t length = 0;
+    bufferid_t buffer_id = 0;
+
+    // Allocate a buffer:
+    struct dma_mem mem;
+    err = frame_alloc(&mem.frame, 4096, &mem.bytes);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "frame_alloc");
+    }
+    struct frame_identity id;
+    err = invoke_frame_identify(mem.frame, &id);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "invoke_frame_identify");
+    }
+
+    err = devq_register(dq, mem.frame, &region_id);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "devq register");
+    }
+
+    uint64_t flags = 0x0;
+    devq_enqueue(dq, region_id, id.base, 512, 0x123, flags);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "devq enqueue");
+    }
+
+    do {
+        err = devq_dequeue(dq, &region_id, &base, &length, &buffer_id);
+        if (err_is_ok(err)) {
+            break;
+        }
+        if (err_is_fail(err) && err_no(err) != DEV_ERR_QUEUE_EMPTY) {
+            USER_PANIC_ERR(err, "devq dequeue");
+        }
+        wait_for_interrupt();
+    } while (err_no(err) == DEV_ERR_QUEUE_EMPTY);
+
+    assert (buffer_id == 0x123);
+    assert (base == id.base);
+    assert (length == 512);
+
+    err = devq_remove(dq, region_id);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "devq_remove failed.");
+    }
+
+    printf("[%s]: DONE\n", __FUNCTION__);
+}
+
+static void blocking_dequeue(void* q, regionid_t* region_id, lpaddr_t* base, size_t* length, bufferid_t* buffer_id)
+{
+    errval_t err;
+    do {
+        err = devq_dequeue(q, region_id, base, length, buffer_id);
+        if (err_is_ok(err)) {
+            break;
+        }
+        if (err_is_fail(err) && err_no(err) != DEV_ERR_QUEUE_EMPTY) {
+            USER_PANIC_ERR(err, "devq dequeue");
+        }
+
+        assert(err_no(err) == DEV_ERR_QUEUE_EMPTY);
+        wait_for_interrupt();
+    } while (err_no(err) == DEV_ERR_QUEUE_EMPTY);
+}
+
+static void receive_block(void)
+{
+    regionid_t rid = 0;
+    lpaddr_t base = 0;
+    size_t len = 0;
+    bufferid_t bid = 0;
+    blocking_dequeue(dq, &rid, &base, &len, &bid);
+
+    bool* status = (bool*) bid;
+    assert (*status == false); // Only write region once
+    *status = true;
+}
+
+void ahci_perf_sequential(size_t buffer_size, size_t block_size, bool write)
+{
+    bench_init();
+    errval_t err;
+    assert(buffer_size % block_size == 0);
+
+    size_t read_requests = buffer_size / block_size;
+    regionid_t region_id = 0;
+
+    static struct capref frame;
+    struct frame_identity id;
+    frame_alloc_identify(buffer_size, &frame, &id);
+
+    err = devq_register(dq, frame, &region_id);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "devq register");
+    }
+
+    uint64_t write_flag = (write) ? (1ULL << 63) : 0;
+    volatile bool *received = calloc(1, sizeof(bool) * read_requests);
+    cycles_t t1 = bench_tsc();
+    for (size_t i=0; i < read_requests; i++) {
+        uint64_t disk_block = write_flag | i;
+        do {
+            err = devq_enqueue(dq, region_id, id.base + (i*block_size), block_size, (bufferid_t)&received[i], disk_block);
+            if (err_is_ok(err)) {
+                break;
+            }
+            else if (err_no(err) == DEV_ERR_QUEUE_FULL) {
+                receive_block();
+            }
+            else {
+                USER_PANIC_ERR(err, "Can't receive block.");
+            }
+        } while (true);
+    }
+    // Make sure we have all requests:
+    for (size_t i=0; i<read_requests; i++) {
+        while (!received[i]) {
+            receive_block();
+        }
+    }
+    cycles_t t2 = bench_tsc();
+    cycles_t result = (t2 - t1 - bench_tscoverhead());
+
+    double result_ms = (double)bench_tsc_to_ms(result);
+    double bw = buffer_size / result_ms / 1000; // 1e3 to sec, 10e6 to MB
+    char* cmd = write ? "Write" : "Read";
+    printf("[%s] %s sequential size %zu bs %zu: %.2f [MB/s]\n", __FUNCTION__, cmd, buffer_size, block_size, bw);
+
+    err = devq_remove(dq, region_id);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "devq_remove failed.");
+    }
+
+    cap_destroy(frame);
+}
+
+void ahci_verify_sequential(size_t buffer_size, size_t block_size)
+{
+    bench_init();
+    errval_t err;
+    assert(buffer_size % block_size == 0);
+
+    size_t requests = buffer_size / block_size;
+    regionid_t region_id = 0;
+
+    struct capref frame;
+    struct frame_identity id;
+    frame_alloc_identify(buffer_size, &frame, &id);
+    err = devq_register(dq, frame, &region_id);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "devq register");
+    }
+
+    struct capref fcopy;
+    err = slot_alloc(&fcopy);
+    assert(err_is_ok(err));
+    err = cap_copy(fcopy, frame);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "copy failed.");
+    }
+    void* retaddr;
+    err = vspace_map_one_frame(&retaddr, id.bytes, fcopy, NULL, NULL);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "map copy failed.");
+    }
+
+    uint8_t rbyte = (uint8_t) rdtsc();
+    if (rbyte == 0) rbyte++;
+    memset(retaddr, rbyte, buffer_size);
+
+    uint64_t write_flag = (1ULL << 63);
+    bool *received = calloc(1, sizeof(bool) * requests);
+    for (size_t i=0; i < requests; i++) {
+        uint64_t disk_block = write_flag | i;
+        do {
+            err = devq_enqueue(dq, region_id, id.base + (i*block_size), block_size, (bufferid_t)&received[i], disk_block);
+            if (err_is_ok(err)) {
+                break;
+            }
+            else if (err_no(err) == DEV_ERR_QUEUE_FULL) {
+                receive_block();
+            }
+            else {
+                USER_PANIC_ERR(err, "Can't receive block.");
+            }
+        } while (true);
+    }
+    // Make sure we have all requests:
+    for (size_t i=0; i<requests; i++) {
+        //printf("%s:%s:%d: i: %zu requests: %zu\n", __FILE__, __FUNCTION__, __LINE__, i, requests);
+        while (!received[i]) {
+            receive_block();
+        }
+    }
+
+    memset(retaddr, 0x00, id.bytes);
+    memset((void*)received, 0x0, sizeof(bool)*requests);
+
+    for (size_t i=0; i < requests; i++) {
+        //printf("%s:%s:%d: i: %zu requests: %zu\n", __FILE__, __FUNCTION__, __LINE__, i, requests);
+        uint64_t disk_block = i;
+        do {
+            err = devq_enqueue(dq, region_id, id.base + (i*block_size), block_size, (bufferid_t)&received[i], disk_block);
+            if (err_is_ok(err)) {
+                break;
+            }
+            else if (err_no(err) == DEV_ERR_QUEUE_FULL) {
+                receive_block();
+            }
+            else {
+                USER_PANIC_ERR(err, "Can't receive block.");
+            }
+        } while (true);
+    }
+    // Make sure we have all requests:
+    for (size_t i=0; i<requests; i++) {
+        while (!received[i]) {
+            //printf("%s:%s:%d: i: %zu requests: %zu\n", __FILE__, __FUNCTION__, __LINE__, i, requests);
+            receive_block();
+        }
+    }
+
+    for (size_t i=0; i < buffer_size; i++) {
+        uint8_t* carr = retaddr;
+        if (carr[i] != rbyte) {
+            printf("%s:%s:%d: carr[%zu]=%d != rbyte=%d\n", __FILE__, __FUNCTION__, __LINE__, i, carr[i], rbyte);
+        }
+        assert(carr[i] == rbyte);
+    }
+
+    printf("[%s] SUCCESS (%zu %zu)\n", __FUNCTION__, buffer_size, block_size);
+    cap_destroy(fcopy);
+
+    err = devq_remove(dq, region_id);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "devq_remove failed.");
+    }
+}
diff --git a/usr/drivers/ahcid/test.h b/usr/drivers/ahcid/test.h
new file mode 100644 (file)
index 0000000..582af74
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016, 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef AHCI_TEST
+#define AHCI_TEST
+
+#include <stdlib.h>
+#include <stdbool.h>
+
+enum AhciTest {
+    AhciTest_READ,
+    AhciTest_WRITE,
+    AhciTest_BASIC,
+    AhciTest_VERIFY,
+};
+
+void test_runner(int n, ...);
+
+void ahci_simple_test(void);
+void ahci_perf_sequential(size_t buffer_size, size_t block_size, bool write);
+void ahci_verify_sequential(size_t buffer_size, size_t block_size);
+
+
+#endif // AHCI_TEST
index e52bb62..92ccf5d 100644 (file)
 --
 --------------------------------------------------------------------------
 
-let template = application {
-        target = "corectrl",
-        addIncludes = [
-            "../../../kernel/include/arch/x86_64/", 
-            "../../../kernel/include" 
-        ],
-        flounderDefs = ["monitor_blocking", "monitor", "octopus" , "acpi"],
-        flounderExtraDefs = [("monitor_blocking", ["rpcclient"]), ("acpi", ["rpcclient"])],
-        flounderBindings = ["intermon"]
-    }
-in [
-    build template {
-        addLibraries = libDeps ["vfs", "spawndomain", "elf", "acpi_client", "octopus", "bench"],
-        cFiles = ["common.c", "main.c", "x86boot.c"],
-        assemblyFiles = ["init_ap_x86_64.S", "init_ap_x86_32.S"],
-        architectures = ["x86_32", "x86_64"]
-    },
-    build template {
-        addLibraries = libDeps ["vfs_noblockdev", "spawndomain", "elf", "octopus", "bench"],
-        cFiles = ["common.c", "main.c", "x86boot.c"],
-        assemblyFiles = ["init_ap_x86_64.S", "init_ap_x86_32.S"],
-        architectures = ["k1om"]
-    },
-    build template {
-        addLibraries = libDeps ["vfs_ramfs", "spawndomain", "elf", "octopus", "bench"],
-        cFiles = ["common.c", "main.c", "armboot.c"],
-        architectures = ["armv7","armv8"]
-    }
-]
+let commonCFiles = [ "common.c", "main.c" ]
+
+    archCFiles arch = case arch of
+        "x86_32" -> [ "x86boot.c" ]
+        "x86_64" -> [ "x86boot.c" ]
+        "k1om"   -> [ "x86boot.c" ]
+        "armv7"  -> [ "armboot.c" ]
+        "armv8"  -> [ "armboot.c" ]
+
+    --- incluldes ---
+
+    commonInclude = [ "../../../kernel/include" ]
+
+    archIncludes arch = case arch of
+        "x86_64" -> [ "../../../kernel/include/arch/x86_64/"]
+        "x86_32" -> [ "../../../kernel/include/arch/x86_32/"]
+        "k1om"   -> [ "../../../kernel/include/arch/x86_64/"]
+        "armv7"  -> [ "../../../kernel/include/arch/armv7/"]
+        "armv8"  -> [ "../../../kernel/include/arch/armv8/"]
+
+    --- flounder defs ---
+
+    commonFlounderDefs = [ "monitor_blocking", "monitor", "octopus" ]
+
+    archFlounderDefs arch = case arch of
+        "x86_64" -> [ "acpi" ]
+        "x86_32" -> [ "acpi" ]
+        "k1om"   -> []
+        "armv7"  -> []
+        "armv8"  -> [ "acpi" ]
+
+    archFlounderExtraDefs arch =  case arch of
+        "x86_64" -> [ ("monitor_blocking", ["rpcclient"]), ("acpi", ["rpcclient"]) ]
+        "x86_32" -> [ ("monitor_blocking", ["rpcclient"]), ("acpi", ["rpcclient"]) ]
+        "k1om"   -> [ ("monitor_blocking", ["rpcclient"]) ]
+        "armv7"  -> [ ("monitor_blocking", ["rpcclient"]) ]
+        "armv8"  -> [ ("monitor_blocking", ["rpcclient"]), ("acpi", ["rpcclient"]) ]
+
+    --- libraries ---
+
+    commonLibraries = [ "spawndomain", "elf", "octopus", "bench" ]
+
+    archLibraries arch = case arch of 
+        "x86_64" -> [ "vfs", "acpi_client" ]
+        "x86_32" -> [ "vfs",  "acpi_client" ]
+        "k1om"   -> [ "vfs_noblockdev"  ]
+        "armv7"  -> [ "vfs_ramfs" ]
+        "armv8"  -> [ "vfs_ramfs", "acpi_client" ]
+
+    --- assembly files ---
+
+    archAssembyFiles arch =  case arch of
+        "x86_64" -> ["init_ap_x86_64.S", "init_ap_x86_32.S"]
+        "x86_32" -> ["init_ap_x86_64.S", "init_ap_x86_32.S"]
+        "k1om"   -> ["init_ap_x86_64.S", "init_ap_x86_32.S"]
+        _        -> []
+
+    in
+      [
+        build application {
+            target = "corectrl",
+            cFiles = commonCFiles ++ (archCFiles arch),
+            addIncludes = commonInclude ++ (archIncludes arch),
+            assemblyFiles = archAssembyFiles arch,
+            addLibraries = libDeps (commonLibraries ++ (archLibraries arch)),
+            flounderDefs = commonFlounderDefs ++ (archFlounderDefs arch),
+            flounderExtraDefs = archFlounderExtraDefs arch, 
+            flounderBindings = ["intermon"],
+            architectures = [ arch ] 
+        } | arch <- allArchitectures
+
+      ]
index 152bf5e..23d3ed5 100644 (file)
@@ -34,6 +34,7 @@
 
 #if defined(__x86__) && !defined(__k1om__)
 #include <acpi_client/acpi_client.h>
+#include <if/acpi_rpcclient_defs.h>
 #endif
 
 #define DEBUG_CPUBOOT 0
index a494ab0..85a7f1b 100644 (file)
@@ -13,6 +13,8 @@
 
 #include <getopt.h>
 #include "coreboot.h"
+#include <hw_records.h>
+
 
 coreid_t my_arch_id;
 struct capref ipi_cap;
@@ -165,13 +167,13 @@ static int list_cpu(int argc, char **argv) {
         err = oct_get(&record, names[i]);
         assert(err_is_ok(err));
 
-        uint64_t barrelfish_id, apic_id, processor_id, enabled;
-        err = oct_read(record, "_ { barrelfish_id: %d, apic_id: %d, processor_id: %d, enabled: %d }",
-                       &barrelfish_id, &apic_id, &processor_id, &enabled);
+        uint64_t barrelfish_id, hw_id, enabled, type;
+        err = oct_read(record, "_ { " HW_PROCESSOR_GENERIC_FIELDS "}",
+                       &enabled, &barrelfish_id, &hw_id, &type);
         assert(err_is_ok(err));
 
-        printf("CPU %"PRIu64": APIC_ID=%"PRIu64" APIC_PROCESSOR_ID=%"PRIu64" ENABLED=%"PRIu64"\n",
-               barrelfish_id, apic_id, processor_id, enabled);
+        printf("CPU %"PRIu64": HW_ID=%"PRIu64" TYPE=%s ENABLED=%"PRIu64"\n",
+               barrelfish_id, hw_id, cpu_type_to_archstr(type), enabled);
     }
     if (len == 0) {
         DEBUG("%s:%s:%d: No cpus found?\n",
index 478e820..ad01c29 100644 (file)
@@ -514,7 +514,7 @@ errval_t spawn_xcore_monitor(coreid_t coreid, int hwid,
     // compute size of frame needed and allocate it
     DEBUG("%s:%s:%d: urpc_frame_id.base=%"PRIxGENPADDR"\n",
            __FILE__, __FUNCTION__, __LINE__, urpc_frame_id.base);
-    DEBUG("%s:%s:%d: urpc_frame_id.size=0x%zx\n",
+    DEBUG("%s:%s:%d: urpc_frame_id.size=0x%" PRIuGENSIZE "\n",
            __FILE__, __FUNCTION__, __LINE__, urpc_frame_id.bytes);
 
     if (benchmark_flag) {
index 52be313..2d44ab9 100644 (file)
@@ -40,6 +40,9 @@
 #include "fd.h"
 #include "error.h"
 
+#if defined(BARRELFISH) && defined(__ARM_ARCH_7A__) && defined(false)
+#undef false
+#endif
 
 #define Assert(ex)     {if (!(ex)){(void) p_fprintf(current_err_, "Elipsys FD internal error: file \"%s\":%d\n", __FILE__, __LINE__); p_reset();}}
 
diff --git a/usr/eclipseclp/README_BARRELFISH b/usr/eclipseclp/README_BARRELFISH
new file mode 100644 (file)
index 0000000..5b4d378
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016, 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+To compile ECLIPSE CLP on Barrelfish ARMv7 the following files had to be changed:
+
+
+eclipseclp/Kernel/src/elipsys_fd.c:43
+
+add the following after the includes: 
+
+#if defined(BARRELFISH) && defined(__ARM_ARCH_7A__) && defined(false)
+#undef false
+#endif
+
+
+eclipseclp/icparc_solvers/ic.c:69
+
+add the following after the includes
+
+#if defined(BARRELFISH) && defined(__ARM_ARCH_7A__) && defined(bool)
+#undef bool
+#endif
\ No newline at end of file
index c75a509..d14c487 100644 (file)
@@ -66,6 +66,9 @@
 #include <math.h>
 #include <string.h>
 
+#if defined(BARRELFISH) && defined(__ARM_ARCH_7A__) && defined(bool)
+#undef bool
+#endif
 
 /*----------------------------------------------------------------------
 **
index 47c16ce..5e56e7c 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <stdlib.h>
+#include <barrelfish/barrelfish.h>
 #include <acpi_client/acpi_client.h>
 
 #include "fish.h"
@@ -36,4 +37,4 @@ int poweroff(int argc, char *argv[])
         acpi_connected = true;
     }
     return acpi_sleep(4);
-}
\ No newline at end of file
+}
index 927db36..2cb7799 100644 (file)
@@ -113,6 +113,7 @@ errval_t initialize_monitor(struct spawninfo *si)
         return err_push(err, INIT_ERR_COPY_IRQ_CAP);
     }
 
+#if !defined(__ARM_ARCH_8A__)
     /* Give monitor IO */
     dest.cnode = si->taskcn;
     dest.slot  = TASKCN_SLOT_IO;
@@ -122,6 +123,7 @@ errval_t initialize_monitor(struct spawninfo *si)
     if (err_is_fail(err)) {
         return err_push(err, INIT_ERR_COPY_IO_CAP);
     }
+#endif
 
 #ifdef __k1om__
     /* Give monitor system memory cap */
index 8dea8a6..b499da2 100644 (file)
@@ -81,6 +81,29 @@ struct module_info* find_module(char *binary)
     return (found) ? si : NULL;
 }
 
+/**
+ * @brief finds corectrl driver module for a given CPU type.
+ *
+ * @param cpu_type  the CPU type
+ *
+ * @return pointer to the corectrl module, or NULL if not existing
+ */
+struct module_info* find_corectrl_for_cpu_type(enum cpu_type cpu_type)
+{
+    switch(cpu_type) {
+    case CPU_K1OM:
+    case CPU_X86_64:
+    case CPU_X86_32:
+    case CPU_ARM7:
+    case CPU_ARM8:
+        return find_module("corectrl");
+        break;
+    default:
+        return NULL;
+        break;
+    }
+}
+
 static void parse_module(char* line, struct module_info* si)
 {
     si->complete_line = strdup(line);
index 5f47695..edca014 100644 (file)
@@ -31,6 +31,7 @@ struct module_info {
 void init_environ(void);
 errval_t init_boot_modules(void);
 struct module_info* find_module(char*);
+struct module_info* find_corectrl_for_cpu_type(enum cpu_type cpu_type);
 
 bool is_started(struct module_info*);
 bool can_start(struct module_info*);
index 755daf9..063d33f 100644 (file)
 #include <trace/trace.h>
 #include <barrelfish/spawn_client.h>
 
+#include <hw_records.h>
+
 #include "kaluga.h"
 
+static const char *processor_regex = HW_PROCESSOR_GENERIC_REGEX;
+
 static void cpu_change_event(octopus_mode_t mode, char* record, void* state)
 {
     if (mode & OCT_ON_SET) {
         KALUGA_DEBUG("CPU found: %s\n", record);
-        assert(my_core_id == 0); // TODO(gz): why?
 
-        uint64_t barrelfish_id, arch_id, enabled = 0;
-        errval_t err = oct_read(record, "_ { barrelfish_id: %d, apic_id: %d, enabled: %d }",
-                &barrelfish_id, &arch_id, &enabled);
+        /* try to extract basic information from the record */
+        uint64_t barrelfish_id, type, hw_id, enabled = 0;
+        errval_t err = oct_read(record, "_ { " HW_PROCESSOR_GENERIC_FIELDS " }",
+                                &enabled, &barrelfish_id, &hw_id, &type);
         if (err_is_fail(err)) {
             DEBUG_ERR(err, "Cannot read record.");
-            assert(!"Illformed core record received");
+            printf("Malformed CPU record. Do not boot discovered CPU %"PRIu64".\n",
+                    barrelfish_id);
             goto out;
         }
 
-        struct module_info* mi = find_module("corectrl");
+        /* find the corectrl module for the given cpu type */
+        struct module_info* mi = find_corectrl_for_cpu_type((enum cpu_type)type);
         if (mi != NULL) {
             err = mi->start_function(0, mi, record);
             if (err_is_fail(err)) {
@@ -52,9 +58,7 @@ static void cpu_change_event(octopus_mode_t mode, char* record, void* state)
                        barrelfish_id);
                 goto out;
             }
-            assert(err_is_ok(err));
         }
-
     }
     if (mode & OCT_ON_DEL) {
         KALUGA_DEBUG("CPU removed: %s\n", record);
@@ -65,22 +69,18 @@ out:
     assert(!(mode & OCT_REMOVED));
 }
 
-static char* local_apics = "r'hw\\.processor\\.[0-9]+' { processor_id: _, "
-                           "                             enabled: 1, "
-                           "                             apic_id: _, "
-                           "                             barrelfish_id: _ }";
-
 errval_t watch_for_cores(void)
 {
     octopus_trigger_id_t tid;
-    return oct_trigger_existing_and_watch(local_apics, cpu_change_event, NULL, &tid);
+    return oct_trigger_existing_and_watch(processor_regex, cpu_change_event,
+                                          NULL, &tid);
 }
 
 errval_t start_boot_driver(coreid_t where, struct module_info* mi,
         char* record)
 {
     assert(mi != NULL);
-    errval_t err = SYS_ERR_OK;
+    errval_t err;
 
     if (!is_auto_driver(mi)) {
         return KALUGA_ERR_DRIVER_NOT_AUTO;
@@ -88,22 +88,33 @@ errval_t start_boot_driver(coreid_t where, struct module_info* mi,
 
     // Construct additional command line arguments containing pci-id.
     // We need one extra entry for the new argument.
-    uint64_t barrelfish_id, apic_id, cpu_type;
     char **argv = mi->argv;
     bool cleanup = false;
     char barrelfish_id_s[10];
     size_t argc = mi->argc;
 
     KALUGA_DEBUG("Starting corectrl for %s\n", record);
-    err = oct_read(record, "_ { apic_id: %d, barrelfish_id: %d, type: %d }",
-            &apic_id, &barrelfish_id, &cpu_type);
+    uint64_t barrelfish_id, cpu_type, hw_id, enabled = 0;
+    err = oct_read(record, "_ { " HW_PROCESSOR_GENERIC_FIELDS " }",
+                            &enabled, &barrelfish_id, &hw_id, &cpu_type);
     if (err_is_ok(err)) {
+        /*
+         * XXX: change this to a generic cpuhwid instead of apic!
+         */
         skb_add_fact("corename(%"PRIu64", %s, apic(%"PRIu64")).",
-                     barrelfish_id, cpu_type_to_archstr(cpu_type), apic_id);
+                     barrelfish_id, cpu_type_to_archstr(cpu_type), hw_id);
+
+        /* we are already running */
         if (barrelfish_id == my_core_id) {
             return SYS_ERR_OK;
         }
 
+        if (!enabled) {
+            printf("CPU %" PRIu64 " is not enabled. Skipping driver initialization\n",
+                    barrelfish_id);
+            return SYS_ERR_OK;
+        }
+
         argv = malloc((argc+5) * sizeof(char *));
         memcpy(argv, mi->argv, argc * sizeof(char *));
         snprintf(barrelfish_id_s, 10, "%"PRIu64"", barrelfish_id);
@@ -207,7 +218,7 @@ errval_t wait_for_all_spawnds(void)
     // spawnd's we have to expect (one per core)
     char** names;
     size_t count;
-    err = oct_get_names(&names, &count, local_apics);
+    err = oct_get_names(&names, &count, processor_regex);
     if (err_is_fail(err)) {
         return err_push(err, KALUGA_ERR_QUERY_LOCAL_APIC);
     }
index 521833c..926bcc4 100644 (file)
@@ -33,6 +33,8 @@
 #include <dev/ht_config_dev.h>
 #include "pci_debug.h"
 
+#include <if/acpi_rpcclient_defs.h>
+
 #define MIN(a,b)        ((a) < (b) ? (a) : (b))
 
 #define BAR_PROBE       0xffffffff
@@ -162,6 +164,7 @@ static errval_t alloc_device_bar(uint8_t idx,
 
     struct device_caps *c = &dev_caps[bus][dev][fun][idx];
     errval_t err;
+    size = ROUND_UP(size, BASE_PAGE_SIZE); // Some BARs are less than 4 KiB
 
     // first try with maximally-sized caps (we'll reduce this if it doesn't work)
     uint8_t bits = log2ceil(size);
index b0f4aab..94e450d 100644 (file)
@@ -22,6 +22,8 @@
 #include <barrelfish/sys_debug.h>
 
 #include <if/pci_defs.h>
+#include <if/acpi_rpcclient_defs.h>
+
 #include <acpi_client/acpi_client.h>
 #include <mm/mm.h>
 //#include "pci_confspace.h"
@@ -211,14 +213,20 @@ static void get_irq_cap_handler(struct pci_binding *b, uint16_t idx){
     // TODO: This should be part of the routing step
     int irq = pci_setup_interrupt(st->bus, st->dev, st->fun);
     PCI_DEBUG("pci: init_device_handler_irq: init interrupt.\n");
-    PCI_DEBUG("pci: irq = %u, core = %hhu, vector = %u\n", irq, coreid,
-                      vector);
 
     pci_enable_interrupt_for_device(st->bus, st->dev, st->fun, st->pcie);
 
+    PCI_DEBUG("pci: Interrupt enabled.\n");
 
     err = sys_debug_create_irq_src_cap(cap, irq);
-    b->tx_vtbl.get_irq_cap_response(b, NOP_CONT, err, cap);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "create irq src cap failed.");
+    }
+
+    err = b->tx_vtbl.get_irq_cap_response(b, NOP_CONT, err, cap);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "cap response failed.");
+    }
 }
 
 static void get_bar_cap_handler(struct pci_binding *b, uint32_t idx,
index 2f56181..da3b6b6 100644 (file)
@@ -19,6 +19,7 @@
 #include <pci/confspace/pci_confspace.h>
 #include <acpi_client/acpi_client.h>
 #include <skb/skb.h>
+#include <if/acpi_rpcclient_defs.h>
 
 #include "pci.h"
 #include "pci_debug.h"
index d35b1d3..d8b310c 100644 (file)
@@ -29,6 +29,7 @@
 #include "pci.h"
 #include "pci_debug.h"
 
+#if !defined(__ARM_ARCH_8A__)
 static errval_t init_io_ports(void)
 {
     errval_t err;
@@ -51,6 +52,7 @@ static errval_t init_io_ports(void)
 
     return SYS_ERR_OK;
 }
+#endif
 
 int main(int argc, char *argv[])
 {
@@ -82,10 +84,12 @@ int main(int argc, char *argv[])
         USER_PANIC_ERR(err, "ACPI Connection failed.");
     }
 
+#if !defined(__ARM_ARCH_8A__)
     err = init_io_ports();
     if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "Init memory allocator failed.");
     }
+#endif
 
     err = pcie_setup_confspace();
     if (err_is_fail(err)) {
index de7b7b9..e4f23b7 100644 (file)
@@ -25,14 +25,14 @@ let ramfs_files = find inDir "programs" ".pl"
                         flounderBindings = [ "skb", "octopus" ],
                         addIncludes = [ "/usr/eclipseclp/Kernel/src"],
                         addLibraries = libDeps [ "eclipse", "shm", "dummies",
-                                                 "icsolver", "vfs",
+                                                 "icsolver", "vfs_ramfs",
                                                  "posixcompat", "hashtable", "pcre", 
                                                  "octopus_server", "octopus_parser", "skb",
                                                  "bench", "dmalloc", "lwip", "gmp" ],
                        architectures = [ arch ]
                 }
 in
-  [ Rules [build (args arch) | arch <- [ "x86_64", "x86_32", "armv8" ]],
+  [ Rules [build (args arch) | arch <- [ "x86_64", "x86_32", "armv8", "armv7" ]],
     Rule ( [ Str "bash",
              In SrcTree "src" "skripts/mkcpio",
              NoDep SrcTree "src" "", Out "root" ramdisk]
index e056a08..58309d3 100644 (file)
@@ -18,6 +18,6 @@
         mackerelDevices = [ "acpi_ec", "lpc_ioapic" ],                      
         cFiles = [ "main.c", "octopus_stubs.c" ],
         addLibraries = [ "octopus_server", "octopus_parser", "pcre" ],
-        architectures = [ "armv7", "k1om" ]
+        architectures = [ "k1om" ]
    }
 ]