Commit SDMA driver changes.
authorGerd Zellweger <mail@gerdzellweger.com>
Tue, 27 Jun 2017 11:20:05 +0000 (13:20 +0200)
committerGerd Zellweger <mail@gerdzellweger.com>
Tue, 27 Jun 2017 11:20:26 +0000 (13:20 +0200)
Signed-off-by: Gerd Zellweger <mail@gerdzellweger.com>

usr/drivers/omap44xx/sdma/Hakefile
usr/drivers/omap44xx/sdma/main.c
usr/drivers/omap44xx/sdma/omap_sdma.c
usr/drivers/omap44xx/sdma/omap_sdma.h
usr/drivers/omap44xx/sdma/sdma.h
usr/drivers/omap44xx/sdma/sdma_domain.c [new file with mode: 0644]
usr/drivers/omap44xx/sdma/service.c

index 726a94e..7219f2d 100644 (file)
@@ -11,8 +11,8 @@
 --------------------------------------------------------------------------
 
 [
-    build application { target = "sdma",
-                    cFiles = (find withSuffices [".c"]),
+    build library { target = "sdma_module",
+                    cFiles = ["main.c", "omap_sdma.c", "service.c"],
                     mackerelDevices = [ "omap/omap44xx_sdma" ],
 
                     flounderDefs = [ "omap_sdma" ],
 
                     addLibraries = ["driverkit", "thc"],
                     architectures = ["armv7"]
-                  }
+    },
+
+    build application {
+        target = "sdma",
+        cFiles = [ "sdma_domain.c"],
+        addModules = ["sdma_module"],
+        addLinkFlags = ["-T" ++ Config.source_dir ++ "/lib/driverkit/bfdrivers.ld" ]
+    }
 ]
index 21f7019..f2e03c0 100644 (file)
 #include "sdma.h"
 #include "omap_sdma.h"
 
-// Channel State. Filled by the interrupt callback, read by the request task.
-static struct {
-    awe_t *request;
-    errval_t err;
-} channel_state[OMAP44XX_SDMA_NUM_CHANNEL];
-
 /**
  * \brief Interrupt callback which will be called when a channel interrupt
  * occurs.
@@ -36,10 +30,10 @@ static struct {
  * \param channel   Channel which triggered the interrupt
  * \param err       State of the channel, SYS_ERR_OK if transfer completed
  */
-static void sdma_irq_handler(omap_sdma_channel_t channel, errval_t err)
+static void sdma_irq_handler(struct sdma_driver_state* st, omap_sdma_channel_t channel, errval_t err)
 {
-    channel_state[channel].err = err;
-    THCSchedule(channel_state[channel].request);
+    st->channel_state[channel].err = err;
+    THCSchedule(st->channel_state[channel].request);
 }
 
 /**
@@ -48,25 +42,25 @@ static void sdma_irq_handler(omap_sdma_channel_t channel, errval_t err)
  *
  * \param conf   Pointer to valid & initialized channel configuration
  */
-static errval_t run_omap_sdma_transfer(struct omap_sdma_channel_conf *conf)
+static errval_t run_omap_sdma_transfer(struct sdma_driver_state* st, struct omap_sdma_channel_conf *conf)
 {
     errval_t err;
     omap_sdma_channel_t channel;
 
-    err = omap_sdma_allocate_channel(&channel);
+    err = omap_sdma_allocate_channel(st, &channel);
     if (err_is_fail(err)) return err;
 
     // configure and enable allocated channel
-    omap_sdma_set_channel_conf(channel, conf);
-    omap_sdma_enable_channel(channel, true);
+    omap_sdma_set_channel_conf(st, channel, conf);
+    omap_sdma_enable_channel(st, channel, true);
 
     // this task will be rescheduled by the IRQ handler
-    THCSuspend(&channel_state[channel].request);
+    THCSuspend(&st->channel_state[channel].request);
 
     // read status flag set by IRQ handler
-    err = channel_state[channel].err;
+    err = st->channel_state[channel].err;
 
-    omap_sdma_free_channel(channel);
+    omap_sdma_free_channel(st, channel);
 
     return err;
 }
@@ -311,7 +305,7 @@ static errval_t frame_address_2d(struct capref cap, omap_sdma_addr_2d_t *addr,
  * \brief Stub to perform simple frame-to-frame memory copy
  * \see   Flounder definition in if/omap_sdma.if
  */
-errval_t mem_copy(struct capref dst_cap, struct capref src_cap)
+errval_t mem_copy(struct sdma_driver_state* st, struct capref dst_cap, struct capref src_cap)
 {
     errval_t err;
     omap_sdma_count_2d_t count;
@@ -331,7 +325,7 @@ errval_t mem_copy(struct capref dst_cap, struct capref src_cap)
     struct omap_sdma_channel_conf conf;
     init_channel_conf(&conf, dst_id.base, src_id.base, 1, 1, 1, 1, count,
                          omap44xx_sdma_DISABLE_COLOR_MODE, 0);
-    err = run_omap_sdma_transfer(&conf);
+    err = run_omap_sdma_transfer(st, &conf);
 
     return err;
 }
@@ -340,7 +334,7 @@ errval_t mem_copy(struct capref dst_cap, struct capref src_cap)
  * \brief Stub to fill a memory frame with a constant value
  * \see   Flounder definition in if/omap_sdma.if
  */
-errval_t mem_fill(struct capref dst_cap, uint8_t color)
+errval_t mem_fill(struct sdma_driver_state* st, struct capref dst_cap, uint8_t color)
 {
     errval_t err;
     omap_sdma_count_2d_t count;
@@ -355,7 +349,7 @@ errval_t mem_fill(struct capref dst_cap, uint8_t color)
     struct omap_sdma_channel_conf conf;
     init_channel_conf(&conf, dst_id.base, 0, 1, 1, 1, 1, count,
                          omap44xx_sdma_CONSTANT_FILL, color);
-    err = run_omap_sdma_transfer(&conf);
+    err = run_omap_sdma_transfer(st, &conf);
 
     return err;
 }
@@ -364,8 +358,8 @@ errval_t mem_fill(struct capref dst_cap, uint8_t color)
  * \brief Stub to perform a two-dimensional memory copy
  * \see   Flounder definition in if/omap_sdma.if
  */
-errval_t mem_copy_2d(omap_sdma_addr_2d_t dst, omap_sdma_addr_2d_t src,
-                omap_sdma_count_2d_t count, bool transparent, uint32_t color)
+errval_t mem_copy_2d(struct sdma_driver_state* st, omap_sdma_addr_2d_t dst, omap_sdma_addr_2d_t src,
+                     omap_sdma_count_2d_t count, bool transparent, uint32_t color)
 {
     errval_t err;
     lpaddr_t src_start, dst_start;
@@ -388,7 +382,7 @@ errval_t mem_copy_2d(omap_sdma_addr_2d_t dst, omap_sdma_addr_2d_t src,
                          src.x_modify, src.y_modify,
                          count, color_mode, color);
 
-    err = run_omap_sdma_transfer(&conf);
+    err = run_omap_sdma_transfer(st, &conf);
     return err;
 }
 
@@ -396,7 +390,7 @@ errval_t mem_copy_2d(omap_sdma_addr_2d_t dst, omap_sdma_addr_2d_t src,
  * \brief Stub to fill parts of a frame using two-dimensional indeces
  * \see   Flounder definition in if/omap_sdma.if
  */
-errval_t mem_fill_2d(omap_sdma_addr_2d_t dst, omap_sdma_count_2d_t count, uint32_t color)
+errval_t mem_fill_2d(struct sdma_driver_state* st, omap_sdma_addr_2d_t dst, omap_sdma_count_2d_t count, uint32_t color)
 {
     errval_t err;
     lpaddr_t  dst_start;
@@ -409,24 +403,60 @@ errval_t mem_fill_2d(omap_sdma_addr_2d_t dst, omap_sdma_count_2d_t count, uint32
                          dst.x_modify, dst.y_modify, 0, 0,
                          count, omap44xx_sdma_CONSTANT_FILL, color);
 
-    err = run_omap_sdma_transfer(&conf);
+    err = run_omap_sdma_transfer(st, &conf);
     return err;
 }
 
-int main(int argc, char **argv)
-{
+
+static errval_t init(struct bfdriver_instance* bfi, const char* name, uint64_t flags,
+                     struct capref* caps, size_t caps_len, char** args, size_t args_len, iref_t* dev) {
+
+    bfi->dstate = malloc(sizeof(struct sdma_driver_state));
+    if (bfi->dstate == NULL) {
+        return LIB_ERR_MALLOC_FAIL;
+    }
+    assert(bfi->dstate != NULL);
+
+    // 1. Initialize the device:
     errval_t err;
     lvaddr_t dev_base;
-
-    err = map_device_register( OMAP44XX_MAP_L4_CFG_SDMA, 
-                              OMAP44XX_MAP_L4_CFG_SDMA_SIZE, 
-                              &dev_base);
+    err = map_device_cap(caps[0], &dev_base);
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "unable to map SDMA registers");
     }
+    omap_sdma_init(bfi->dstate, (mackerel_addr_t)dev_base, sdma_irq_handler);
+
+    // 2. Export service to talk to the device:
+    start_service(bfi->dstate);
+
+    // 3. Set iref of your exported service (this is reported back to Kaluga)
+    *dev = 0x00;
+
+    return SYS_ERR_OK;
+}
+
+static errval_t attach(struct bfdriver_instance* bfi) {
+    return SYS_ERR_OK;
+}
+
+static errval_t detach(struct bfdriver_instance* bfi) {
+    return SYS_ERR_OK;
+}
 
-    omap_sdma_init((mackerel_addr_t)dev_base, sdma_irq_handler);
-    start_service();
+static errval_t set_sleep_level(struct bfdriver_instance* bfi, uint32_t level) {
+    struct sdma_driver_state* uds = bfi->dstate;
+    uds->level = level;
+    return SYS_ERR_OK;
+}
 
-    return 0;
+static errval_t destroy(struct bfdriver_instance* bfi) {
+    struct sdma_driver_state* uds = bfi->dstate;
+    free(uds);
+    bfi->dstate = NULL;
+    // XXX: Tear-down the service
+    bfi->device = 0x0;
+    return SYS_ERR_OK;
 }
+
+
+DEFINE_MODULE(sdma, init, attach, detach, set_sleep_level, destroy);
index d5f6971..e970e5d 100644 (file)
 #include "omap_sdma.h"
 #include <maps/omap44xx_map.h>
 
-static omap44xx_sdma_t devsdma;
-static bool allocated_channel[OMAP44XX_SDMA_NUM_CHANNEL];
-
-static omap_sdma_irq_handler_t irq_callback;
-
 static inline errval_t omap_sdma_read_csr(omap44xx_sdma_dma4_csr_t csr)
 {
     if (omap44xx_sdma_dma4_csr_misaligned_adrs_err_extract(csr)) {
@@ -45,7 +40,8 @@ static inline errval_t omap_sdma_read_csr(omap44xx_sdma_dma4_csr_t csr)
 
 static void omap_sdma_irq_handler(void *arg)
 {
-    uint32_t irqstatus = omap44xx_sdma_dma4_irqstatus_line_rd(&devsdma, OMAP44XX_SDMA_IRQ_LINE);
+    struct sdma_driver_state* st = (struct sdma_driver_state*) arg;
+    uint32_t irqstatus = omap44xx_sdma_dma4_irqstatus_line_rd(&st->devsdma, OMAP44XX_SDMA_IRQ_LINE);
 
     for (omap_sdma_channel_t channel=0; channel<OMAP44XX_SDMA_NUM_CHANNEL; channel++) {
         bool active = (irqstatus >> channel) & 0x1;
@@ -54,7 +50,7 @@ static void omap_sdma_irq_handler(void *arg)
         SDMA_PRINT("interrupt on channel %u\n", channel);
 
         // read out status flags
-        omap44xx_sdma_dma4_csr_t csr = omap44xx_sdma_dma4_csr_rd(&devsdma, channel);
+        omap44xx_sdma_dma4_csr_t csr = omap44xx_sdma_dma4_csr_rd(&st->devsdma, channel);
 
         // check for errors
         errval_t err = omap_sdma_read_csr(csr);
@@ -62,27 +58,27 @@ static void omap_sdma_irq_handler(void *arg)
         if (err_is_ok(err)) {
             // no error found, check for "End of Block" event
             if(omap44xx_sdma_dma4_csr_block_extract(csr)) {
-                irq_callback(channel, err);
+                st->irq_callback(st, channel, err);
             }
         } else {
             // OMAP4460 Multimedia Device Silicon Errata, Revision A:
             // 1.7 sDMA Channel Is Not Disabled After A Transaction Error
             if (err_no(err) == OMAP_SDMA_ERR_TRANSACTION) {
                 // Workaround: disable channel by software
-                omap44xx_sdma_dma4_ccr_enable_wrf(&devsdma, channel, 0);
+                omap44xx_sdma_dma4_ccr_enable_wrf(&st->devsdma, channel, 0);
             }
 
-            irq_callback(channel, err);
+            st->irq_callback(st, channel, err);
         }
 
         // clear all read status flags
-        omap44xx_sdma_dma4_csr_wr(&devsdma, channel, csr);
+        omap44xx_sdma_dma4_csr_wr(&st->devsdma, channel, csr);
     }
 
     SDMA_PRINT("interrupt finished\n");
 
     // clear all set status bits
-    omap44xx_sdma_dma4_irqstatus_line_wr(&devsdma, OMAP44XX_SDMA_IRQ_LINE, irqstatus);
+    omap44xx_sdma_dma4_irqstatus_line_wr(&st->devsdma, OMAP44XX_SDMA_IRQ_LINE, irqstatus);
 }
 
 
@@ -103,9 +99,9 @@ static void omap_sdma_kernel_irq_handler(void)
 }
 #endif
 
-static void omap_sdma_irq_config(omap_sdma_channel_t channel)
+static void omap_sdma_irq_config(struct sdma_driver_state* st, omap_sdma_channel_t channel)
 {
-    omap44xx_sdma_dma4_cicr_t dma4_cicr = omap44xx_sdma_dma4_cicr_rd(&devsdma, channel);
+    omap44xx_sdma_dma4_cicr_t dma4_cicr = omap44xx_sdma_dma4_cicr_rd(&st->devsdma, channel);
 
     dma4_cicr = omap44xx_sdma_dma4_cicr_super_block_ie_insert(dma4_cicr, 0x0);
     dma4_cicr = omap44xx_sdma_dma4_cicr_drain_ie_insert(dma4_cicr, 0x0);
@@ -119,7 +115,7 @@ static void omap_sdma_irq_config(omap_sdma_channel_t channel)
     dma4_cicr = omap44xx_sdma_dma4_cicr_half_ie_insert(dma4_cicr, 0x0);
     dma4_cicr = omap44xx_sdma_dma4_cicr_drop_ie_insert(dma4_cicr, 0x0);
 
-    omap44xx_sdma_dma4_cicr_wr(&devsdma, channel, dma4_cicr);
+    omap44xx_sdma_dma4_cicr_wr(&st->devsdma, channel, dma4_cicr);
 }
 
 /**
@@ -307,7 +303,7 @@ static void inline omap_sdma_channel_conf_assert_transfer_conf(
  * but is it the callers responsibility to ensure that the configuration is
  * sane and valid.
  */
-void omap_sdma_set_channel_conf(omap_sdma_channel_t channel,
+void omap_sdma_set_channel_conf(struct sdma_driver_state* st, omap_sdma_channel_t channel,
                                 struct omap_sdma_channel_conf *conf)
 {
     // check transfer config and size parameters
@@ -321,48 +317,48 @@ void omap_sdma_set_channel_conf(omap_sdma_channel_t channel,
 
     // Channel Control Register
     omap44xx_sdma_dma4_ccr_t dma4_ccr;
-    dma4_ccr = omap44xx_sdma_dma4_ccr_rd(&devsdma, channel);
+    dma4_ccr = omap44xx_sdma_dma4_ccr_rd(&st->devsdma, channel);
     dma4_ccr = omap_sdma_channel_conf_ccr(dma4_ccr, conf);
-    omap44xx_sdma_dma4_ccr_wr(&devsdma, channel, dma4_ccr);
+    omap44xx_sdma_dma4_ccr_wr(&st->devsdma, channel, dma4_ccr);
 
     // Channel Color Register
     omap44xx_sdma_dma4_color_t dma4_color;
-    dma4_color = omap44xx_sdma_dma4_color_rd(&devsdma, channel);
+    dma4_color = omap44xx_sdma_dma4_color_rd(&st->devsdma, channel);
     dma4_color = omap_sdma_channel_conf_color(channel, conf);
-    omap44xx_sdma_dma4_color_wr(&devsdma, channel, dma4_color);
+    omap44xx_sdma_dma4_color_wr(&st->devsdma, channel, dma4_color);
 
     // Channel Link Control Register
     omap44xx_sdma_dma4_clnk_ctrl_t dma4_clnk_ctrl;
-    dma4_clnk_ctrl = omap44xx_sdma_dma4_clnk_ctrl_rd(&devsdma, channel);
+    dma4_clnk_ctrl = omap44xx_sdma_dma4_clnk_ctrl_rd(&st->devsdma, channel);
     dma4_clnk_ctrl = omap_sdma_channel_conf_clnk_ctrl(channel, conf);
-    omap44xx_sdma_dma4_clnk_ctrl_wr(&devsdma, channel, dma4_clnk_ctrl);
+    omap44xx_sdma_dma4_clnk_ctrl_wr(&st->devsdma, channel, dma4_clnk_ctrl);
 
     // Channel Source Destination Parameters
     omap44xx_sdma_dma4_csdp_t dma4_csdp;
-    dma4_csdp = omap44xx_sdma_dma4_csdp_rd(&devsdma, channel);
+    dma4_csdp = omap44xx_sdma_dma4_csdp_rd(&st->devsdma, channel);
     dma4_csdp = omap_sdma_channel_conf_csdp(channel, conf);
-    omap44xx_sdma_dma4_csdp_wr(&devsdma, channel, dma4_csdp);
+    omap44xx_sdma_dma4_csdp_wr(&st->devsdma, channel, dma4_csdp);
 
     // Channel Element Number
-    omap44xx_sdma_dma4_cen_wr(&devsdma, channel, conf->transfer_size.element_number);
+    omap44xx_sdma_dma4_cen_wr(&st->devsdma, channel, conf->transfer_size.element_number);
 
     // Channel Frame Number
-    omap44xx_sdma_dma4_cfn_wr(&devsdma, channel, conf->transfer_size.frame_number);
+    omap44xx_sdma_dma4_cfn_wr(&st->devsdma, channel, conf->transfer_size.frame_number);
 
     // Channel Source Element Index
-    omap44xx_sdma_dma4_csei_wr(&devsdma, channel, conf->src_conf.element_index);
+    omap44xx_sdma_dma4_csei_wr(&st->devsdma, channel, conf->src_conf.element_index);
     // Channel Source Frame Index
-    omap44xx_sdma_dma4_csfi_wr(&devsdma, channel, conf->src_conf.frame_index);
+    omap44xx_sdma_dma4_csfi_wr(&st->devsdma, channel, conf->src_conf.frame_index);
     // Channel Destination Element Index
-    omap44xx_sdma_dma4_cdei_wr(&devsdma, channel, conf->dst_conf.element_index);
+    omap44xx_sdma_dma4_cdei_wr(&st->devsdma, channel, conf->dst_conf.element_index);
     // Channel Destination Frame Index
-    omap44xx_sdma_dma4_cdfi_wr(&devsdma, channel, conf->dst_conf.frame_index);
+    omap44xx_sdma_dma4_cdfi_wr(&st->devsdma, channel, conf->dst_conf.frame_index);
 
     // Channel Source Start Address
-    omap44xx_sdma_dma4_cssa_wr(&devsdma, channel, conf->src_conf.start_address);
+    omap44xx_sdma_dma4_cssa_wr(&st->devsdma, channel, conf->src_conf.start_address);
 
     // Channel Source Destination Address
-    omap44xx_sdma_dma4_cdsa_wr(&devsdma, channel, conf->dst_conf.start_address);
+    omap44xx_sdma_dma4_cdsa_wr(&st->devsdma, channel, conf->dst_conf.start_address);
 }
 
 /**
@@ -374,42 +370,42 @@ void omap_sdma_set_channel_conf(omap_sdma_channel_t channel,
  * It is the callers responsibility to ensure that the channel was configured
  * properly before this function is called.
  */
-void omap_sdma_enable_channel(omap_sdma_channel_t channel, bool interrupt)
+void omap_sdma_enable_channel(struct sdma_driver_state* st, omap_sdma_channel_t channel, bool interrupt)
 {
     assert(channel < OMAP44XX_SDMA_NUM_CHANNEL);
 
     // clear all channel status flags
-    omap44xx_sdma_dma4_csr_wr(&devsdma, channel, 0xFFFFFFFF);
+    omap44xx_sdma_dma4_csr_wr(&st->devsdma, channel, 0xFFFFFFFF);
 
-    uint32_t irqenable = omap44xx_sdma_dma4_irqenable_rd(&devsdma, OMAP44XX_SDMA_IRQ_LINE);
+    uint32_t irqenable = omap44xx_sdma_dma4_irqenable_rd(&st->devsdma, OMAP44XX_SDMA_IRQ_LINE);
     if (interrupt) {
         // set channel
         irqenable |= 1 << channel;
         // reset irq status for this channel
-        omap44xx_sdma_dma4_irqstatus_line_wr(&devsdma, OMAP44XX_SDMA_IRQ_LINE, 1 << channel);
+        omap44xx_sdma_dma4_irqstatus_line_wr(&st->devsdma, OMAP44XX_SDMA_IRQ_LINE, 1 << channel);
     } else {
         // clear channel
         irqenable &= ~(1 << channel);
     }
-    omap44xx_sdma_dma4_irqenable_wr(&devsdma, OMAP44XX_SDMA_IRQ_LINE, irqenable);
+    omap44xx_sdma_dma4_irqenable_wr(&st->devsdma, OMAP44XX_SDMA_IRQ_LINE, irqenable);
 
-    omap44xx_sdma_dma4_ccr_enable_wrf(&devsdma, channel, 1);
+    omap44xx_sdma_dma4_ccr_enable_wrf(&st->devsdma, channel, 1);
 }
 
 /**
  * \brief Poll a enabled channel for completion of the transfer.
  */
-errval_t omap_sdma_poll_channel(omap_sdma_channel_t channel)
+errval_t omap_sdma_poll_channel(struct sdma_driver_state* st, omap_sdma_channel_t channel)
 {
     assert(channel < OMAP44XX_SDMA_NUM_CHANNEL);
 
     // interrupts should be disabled in polling mode
     assert((omap44xx_sdma_dma4_irqenable_rd(
-                &devsdma, OMAP44XX_SDMA_IRQ_LINE) & 1 << channel) == 0x0
+                &st->devsdma, OMAP44XX_SDMA_IRQ_LINE) & 1 << channel) == 0x0
     );
 
     for (;;) {
-        omap44xx_sdma_dma4_csr_t csr = omap44xx_sdma_dma4_csr_rd(&devsdma, channel);
+        omap44xx_sdma_dma4_csr_t csr = omap44xx_sdma_dma4_csr_rd(&st->devsdma, channel);
 
         errval_t err = omap_sdma_read_csr(csr);
 
@@ -425,13 +421,13 @@ errval_t omap_sdma_poll_channel(omap_sdma_channel_t channel)
  * \brief Allocate a SDMA channel. Will return an error if there are no channels
  * available.
  */
-errval_t omap_sdma_allocate_channel(omap_sdma_channel_t *channel)
+errval_t omap_sdma_allocate_channel(struct sdma_driver_state* st, omap_sdma_channel_t *channel)
 {
     assert(channel != NULL);
 
     for (omap_sdma_channel_t c = 0; c<OMAP44XX_SDMA_NUM_CHANNEL; c++) {
-        if (!allocated_channel[c]) {
-            allocated_channel[c] = true;
+        if (!st->allocated_channel[c]) {
+            st->allocated_channel[c] = true;
             *channel = c;
             return SYS_ERR_OK;
         }
@@ -442,10 +438,10 @@ errval_t omap_sdma_allocate_channel(omap_sdma_channel_t *channel)
 /**
  * \brief Frees a previously allocated SDMA channel.
  */
-void omap_sdma_free_channel(omap_sdma_channel_t channel)
+void omap_sdma_free_channel(struct sdma_driver_state* st, omap_sdma_channel_t channel)
 {
-    assert(allocated_channel[channel]);
-    allocated_channel[channel] = false;
+    assert(st->allocated_channel[channel]);
+    st->allocated_channel[channel] = false;
 }
 
 /**
@@ -459,19 +455,19 @@ void omap_sdma_free_channel(omap_sdma_channel_t channel)
  * an interrupt. The source channel and the the reason of the interrupt are
  * passed to the callback as an the argument.
  */
-errval_t omap_sdma_init(mackerel_addr_t dev_base, omap_sdma_irq_handler_t irq_cb)
+errval_t omap_sdma_init(struct sdma_driver_state* st, mackerel_addr_t dev_base, omap_sdma_irq_handler_t irq_cb)
 {
     // init global variables
     STATIC_ASSERT_SIZEOF(bool, 1);
-    memset(allocated_channel, false, OMAP44XX_SDMA_NUM_CHANNEL);
+    memset(st->allocated_channel, false, OMAP44XX_SDMA_NUM_CHANNEL);
 
-    omap44xx_sdma_initialize(&devsdma, dev_base);
+    omap44xx_sdma_initialize(&st->devsdma, dev_base);
 
     // check if we can read the revision
-    assert(omap44xx_sdma_dma4_revision_rd(&devsdma) == 0x10900);
+    assert(omap44xx_sdma_dma4_revision_rd(&st->devsdma) == 0x10900);
 
     assert(irq_cb != NULL);
-    irq_callback = irq_cb;
+    st->irq_callback = irq_cb;
 
     errval_t err = SYS_ERR_OK;
 #ifdef OMAP_SDMA_KERNELBENCH
@@ -489,18 +485,18 @@ errval_t omap_sdma_init(mackerel_addr_t dev_base, omap_sdma_irq_handler_t irq_cb
                             GIC_IRQ_EDGE_TRIGGERED, GIC_IRQ_N_TO_N);
 #else
     // in userspace, register normal interrupt handler
-    err = inthandler_setup_arm(omap_sdma_irq_handler, NULL, OMAP44XX_SDMA_IRQ);
+    err = inthandler_setup_arm(omap_sdma_irq_handler, st, OMAP44XX_SDMA_IRQ);
 #endif
 
     // set fifo depth to maximum burst size
-    omap44xx_sdma_dma4_gcr_max_channel_fifo_depth_wrf(&devsdma, 64);
+    omap44xx_sdma_dma4_gcr_max_channel_fifo_depth_wrf(&st->devsdma, 64);
 
     // configure error and interrupt handling of the device
     for(omap_sdma_channel_t channel = 0;
         channel < OMAP44XX_SDMA_NUM_CHANNEL;
         channel++)
     {
-        omap_sdma_irq_config(channel);
+        omap_sdma_irq_config(st, channel);
     }
 
     return err;
index fcb4600..f0ffb2e 100644 (file)
@@ -14,8 +14,9 @@
 #include <dev/omap/omap44xx_sdma_dev.h>
 
 typedef uint8_t omap_sdma_channel_t;
+struct sdma_driver_state;
 
-typedef void (*omap_sdma_irq_handler_t)(omap_sdma_channel_t, errval_t);
+typedef void (*omap_sdma_irq_handler_t)(struct sdma_driver_state*, omap_sdma_channel_t, errval_t);
 
 typedef uint8_t omap44xx_sdma_color_mode_t;
 #define omap44xx_sdma_DISABLE_COLOR_MODE ((omap44xx_sdma_color_mode_t)0x0)
@@ -38,6 +39,24 @@ typedef uint8_t omap44xx_sdma_color_mode_t;
 #define SDMA_PRINT(...) do{ } while ( false )
 #endif
 
+#include <thc/thc.h>
+
+/// Channel State. Filled by the interrupt callback, read by the request task.
+struct channel_state {
+    awe_t *request;
+    errval_t err;
+};
+
+struct sdma_driver_state {
+    omap44xx_sdma_t devsdma;
+
+    bool allocated_channel[OMAP44XX_SDMA_NUM_CHANNEL];
+    struct channel_state channel_state[OMAP44XX_SDMA_NUM_CHANNEL];
+    omap_sdma_irq_handler_t irq_callback;
+
+    uint32_t level;
+};
+
 struct omap_sdma_transfer_conf {
     lpaddr_t start_address;
     omap44xx_sdma_addr_mode_t addr_mode;
@@ -76,18 +95,18 @@ struct omap_sdma_channel_conf {
     omap_sdma_channel_t next_channel;
 };
 
-errval_t omap_sdma_init(mackerel_addr_t dev_base, omap_sdma_irq_handler_t);
+errval_t omap_sdma_init(struct sdma_driver_state*, mackerel_addr_t, omap_sdma_irq_handler_t);
 
-errval_t omap_sdma_allocate_channel(omap_sdma_channel_t *channel);
-void omap_sdma_free_channel(omap_sdma_channel_t channel);
+errval_t omap_sdma_allocate_channel(struct sdma_driver_state* st, omap_sdma_channel_t *channel);
+void omap_sdma_free_channel(struct sdma_driver_state* st, omap_sdma_channel_t channel);
 
 void omap_sdma_init_channel_conf(struct omap_sdma_channel_conf *conf);
 
-void omap_sdma_set_channel_conf(omap_sdma_channel_t channel,
+void omap_sdma_set_channel_conf(struct sdma_driver_state* st, omap_sdma_channel_t channel,
     struct omap_sdma_channel_conf *conf);
 
-void omap_sdma_enable_channel(omap_sdma_channel_t channel, bool interrupt);
+void omap_sdma_enable_channel(struct sdma_driver_state* st, omap_sdma_channel_t channel, bool interrupt);
 
-errval_t omap_sdma_poll_channel(omap_sdma_channel_t channel);
+errval_t omap_sdma_poll_channel(struct sdma_driver_state* st, omap_sdma_channel_t channel);
 
 #endif // OMAP44XX_SDMA_H_
index b5584ef..66dc21b 100644 (file)
 #include <if/omap_sdma_defs.h>
 #include <bitmacros.h>
 
-void start_service(void);
+struct sdma_driver_state;
+void start_service(struct sdma_driver_state* st);
 
-errval_t mem_copy(struct capref dst_cap, struct capref src_cap);
-errval_t mem_fill(struct capref dst_cap, uint8_t color);
+errval_t mem_copy(struct sdma_driver_state* st, struct capref dst_cap, struct capref src_cap);
+errval_t mem_fill(struct sdma_driver_state* st, struct capref dst_cap, uint8_t color);
 
-errval_t mem_copy_2d(omap_sdma_addr_2d_t dst, omap_sdma_addr_2d_t src,
+errval_t mem_copy_2d(struct sdma_driver_state* st, omap_sdma_addr_2d_t dst, omap_sdma_addr_2d_t src,
                 omap_sdma_count_2d_t count, bool transparent, uint32_t color);
-errval_t mem_fill_2d(omap_sdma_addr_2d_t dst, omap_sdma_count_2d_t count, uint32_t color);
+errval_t mem_fill_2d(struct sdma_driver_state* st, omap_sdma_addr_2d_t dst, omap_sdma_count_2d_t count, uint32_t color);
 #endif
diff --git a/usr/drivers/omap44xx/sdma/sdma_domain.c b/usr/drivers/omap44xx/sdma/sdma_domain.c
new file mode 100644 (file)
index 0000000..d04908b
--- /dev/null
@@ -0,0 +1,82 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <barrelfish/barrelfish.h>
+#include <driverkit/driverkit.h>
+#include <barrelfish/nameservice_client.h>
+
+#include <arch/arm/omap44xx/device_registers.h>
+#include <maps/omap44xx_map.h>
+
+/// XXX: TODO not needed once kaluga <-> driver domain communicate over dcontrol iface
+static errval_t find_cap_for(lpaddr_t address, size_t size, struct capref* out)
+{
+    errval_t err;
+    struct cnoderef argcn_cnref = {
+        .croot = CPTR_ROOTCN,
+        .cnode = ROOTCN_SLOT_ADDR(ROOTCN_SLOT_ARGCN),
+        .level = CNODE_TYPE_OTHER,
+    };
+
+    struct capref device_cap_iter = {
+        .cnode = argcn_cnref,
+        .slot = 0
+    };
+
+    for (; device_cap_iter.slot < L2_CNODE_SLOTS; device_cap_iter.slot++) {
+        // Get cap data
+        struct capability cap;
+        err = debug_cap_identify(device_cap_iter, &cap);
+        // If cap type was Null, kernel returns error
+        if (err_no(err) == SYS_ERR_IDENTIFY_LOOKUP ||
+            err_no(err) == SYS_ERR_CAP_NOT_FOUND ||
+            err_no(err) == SYS_ERR_LMP_CAPTRANSFER_SRC_LOOKUP) {
+            continue;
+        }
+
+        struct frame_identity fid;
+        err = frame_identify(device_cap_iter, &fid);
+        if (err_is_fail(err)) {
+            DEBUG_ERR(err, "Failure in frame_identify");
+            return err;
+        }
+        assert(err_is_ok(err));
+
+        lpaddr_t address_base = address & ~(BASE_PAGE_SIZE-1);
+        // XXX: should be address+size <= ...
+        // Need to add proper register size
+        if (address_base >= fid.base &&
+                (address_base + size) <= (fid.base + fid.bytes)) {
+            *out = device_cap_iter;
+            return SYS_ERR_OK;
+        }
+    }
+
+    return DRIVERKIT_ERR_NO_CAP_FOUND;
+}
+
+
+int main(int argc, char** argv)
+{
+    size_t drivers = 0;
+    struct bfdriver* cur = NULL;
+    driverkit_list(&cur, &drivers);
+    for (size_t i=0; i<drivers; i++) {
+        printf("%s:%s:%d: Found device driver class = %s\n", __FILE__, __FUNCTION__, __LINE__, cur->name);
+        cur += 1;
+    }
+
+    struct capref* caps = calloc(1, sizeof(struct capref));
+    errval_t err = find_cap_for(OMAP44XX_MAP_L4_CFG_SDMA, OMAP44XX_MAP_L4_CFG_SDMA_SIZE, &caps[0]);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "finding cap failed.");
+    }
+
+    iref_t dev, ctrl;
+    driverkit_create_driver("sdma", "sdma_inst", caps, 1, NULL, 0, 0, &dev, &ctrl);
+
+    messages_handler_loop();
+    return 0;
+}
index ae9420c..05dad39 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "sdma.h"
 
-static void run_service(struct omap_sdma_thc_service_binding_t *sv)
+static void run_service(struct sdma_driver_state* st, struct omap_sdma_thc_service_binding_t *sv)
 {
     omap_sdma_service_msg_t msg;
     bool loop = true;
@@ -41,19 +41,19 @@ static void run_service(struct omap_sdma_thc_service_binding_t *sv)
         // dispatch it
         switch(msg.msg) {
         case omap_sdma_mem_copy:
-            reterr = mem_copy(
+            reterr = mem_copy(st,
                 msg.args.mem_copy.in.dst,
                 msg.args.mem_copy.in.src);
             sv->send.mem_copy(sv, reterr);
             break;
         case omap_sdma_mem_fill:
-            reterr = mem_fill(
+            reterr = mem_fill(st,
                 msg.args.mem_fill.in.dst,
                 msg.args.mem_fill.in.color);
             sv->send.mem_fill(sv, reterr);
             break;
         case omap_sdma_mem_copy_2d:
-            reterr = mem_copy_2d(
+            reterr = mem_copy_2d(st,
                 msg.args.mem_copy_2d.in.dst,
                 msg.args.mem_copy_2d.in.src,
                 msg.args.mem_copy_2d.in.count,
@@ -62,7 +62,7 @@ static void run_service(struct omap_sdma_thc_service_binding_t *sv)
             sv->send.mem_copy_2d(sv, reterr);
             break;
         case omap_sdma_mem_fill_2d:
-            reterr = mem_fill_2d(
+            reterr = mem_fill_2d(st,
                 msg.args.mem_fill_2d.in.dst,
                 msg.args.mem_fill_2d.in.count,
                 msg.args.mem_fill_2d.in.color);
@@ -78,7 +78,7 @@ static void run_service(struct omap_sdma_thc_service_binding_t *sv)
     free(sv);
 }
 
-void start_service(void)
+void start_service(struct sdma_driver_state* st)
 {
     errval_t err;
 
@@ -110,7 +110,7 @@ void start_service(void)
                 USER_PANIC_ERR(err, "thc init failed");
             }
 
-            ASYNC({run_service(sv);});
+            ASYNC({run_service(st, sv);});
         }
     });
 }