aboutsummaryrefslogtreecommitdiffstats
path: root/firmware/microblaze/lib/dbsm.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/microblaze/lib/dbsm.c')
-rw-r--r--firmware/microblaze/lib/dbsm.c299
1 files changed, 0 insertions, 299 deletions
diff --git a/firmware/microblaze/lib/dbsm.c b/firmware/microblaze/lib/dbsm.c
deleted file mode 100644
index cee343eaa..000000000
--- a/firmware/microblaze/lib/dbsm.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,2008 Free Software Foundation, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * Double Buffering State Machine
- */
-
-#include "dbsm.h"
-#include "memory_map.h"
-#include "buffer_pool.h"
-#include <stdbool.h>
-#include "nonstdio.h"
-#include <stdlib.h>
-
-typedef enum {
- BS_EMPTY,
- BS_FILLING,
- BS_FULL,
- BS_EMPTYING,
-} buffer_state_t;
-
-static buffer_state_t buffer_state[NBUFFERS];
-
-bool
-dbsm_nop_inspector(dbsm_t *sm, int buf_this)
-{
- return false;
-}
-
-void
-dbsm_init(dbsm_t *sm, int buf0,
- const buf_cmd_args_t *recv, const buf_cmd_args_t *send,
- inspector_t inspect)
-{
- if (buf0 & 0x1) // must be even
- abort();
-
- sm->buf0 = buf0;
- sm->running = false;
- sm->recv_args = *recv;
- sm->send_args = *send;
-
- sm->rx_idle = true;
- sm->tx_idle = true;
-
- sm->inspect = inspect;
-
- // How much to adjust the last_line register.
- // It's 1 for everything but the ethernet.
- //sm->last_line_adj = recv->port == PORT_ETH ? 3 : 1;
- sm->last_line_adj = 1;
-
- buffer_state[sm->buf0] = BS_EMPTY;
- buffer_state[sm->buf0 ^ 1] = BS_EMPTY;
-
- sm->precomputed_receive_to_buf_ctrl_word[0] =
- (BPC_READ
- | BPC_BUFFER(sm->buf0)
- | BPC_PORT(sm->recv_args.port)
- | BPC_STEP(1)
- | BPC_FIRST_LINE(sm->recv_args.first_line)
- | BPC_LAST_LINE(sm->recv_args.last_line));
-
- sm->precomputed_receive_to_buf_ctrl_word[1] =
- (BPC_READ
- | BPC_BUFFER(sm->buf0 ^ 1)
- | BPC_PORT(sm->recv_args.port)
- | BPC_STEP(1)
- | BPC_FIRST_LINE(sm->recv_args.first_line)
- | BPC_LAST_LINE(sm->recv_args.last_line));
-
- sm->precomputed_send_from_buf_ctrl_word[0] =
- (BPC_WRITE
- | BPC_BUFFER(sm->buf0)
- | BPC_PORT(sm->send_args.port)
- | BPC_STEP(1)
- | BPC_FIRST_LINE(sm->send_args.first_line)
- | BPC_LAST_LINE(0)); // last line filled in at runtime
-
- sm->precomputed_send_from_buf_ctrl_word[1] =
- (BPC_WRITE
- | BPC_BUFFER(sm->buf0 ^ 1)
- | BPC_PORT(sm->send_args.port)
- | BPC_STEP(1)
- | BPC_FIRST_LINE(sm->send_args.first_line)
- | BPC_LAST_LINE(0)); // last line filled in at runtime
-
-}
-
-static inline void
-dbsm_receive_to_buf(dbsm_t *sm, int bufno)
-{
- buffer_pool_ctrl->ctrl = sm->precomputed_receive_to_buf_ctrl_word[bufno & 1];
-}
-
-static inline void
-dbsm_send_from_buf(dbsm_t *sm, int bufno)
-{
- buffer_pool_ctrl->ctrl =
- (sm->precomputed_send_from_buf_ctrl_word[bufno & 1]
- | BPC_LAST_LINE(buffer_pool_status->last_line[bufno] - sm->last_line_adj));
-}
-
-void
-dbsm_start(dbsm_t *sm)
-{
- // printf("dbsm_start: buf0 = %d, recv_port = %d\n", sm->buf0, sm->recv_args.port);
-
- sm->running = true;
-
- buffer_state[sm->buf0] = BS_EMPTY;
- buffer_state[sm->buf0 ^ 1] = BS_EMPTY;
-
- bp_clear_buf(sm->buf0);
- bp_clear_buf(sm->buf0 ^ 1);
-
- sm->tx_idle = true;
- sm->rx_idle = false;
- dbsm_receive_to_buf(sm, sm->buf0);
- buffer_state[sm->buf0] = BS_FILLING;
-
-}
-
-
-void
-dbsm_stop(dbsm_t *sm)
-{
- sm->running = false;
- bp_clear_buf(sm->buf0);
- bp_clear_buf(sm->buf0 ^ 1);
- buffer_state[sm->buf0] = BS_EMPTY;
- buffer_state[sm->buf0 ^ 1] = BS_EMPTY;
-}
-
-static void dbsm_process_helper(dbsm_t *sm, int buf_this);
-static void dbsm_error_helper(dbsm_t *sm, int buf_this);
-
-void
-dbsm_process_status(dbsm_t *sm, uint32_t status)
-{
- if (!sm->running)
- return;
-
- if (status & (BPS_ERROR(sm->buf0) | BPS_ERROR(sm->buf0 ^ 1))){
- putchar('E');
- // Most likely an ethernet Rx error. We just restart the transfer.
- if (status & (BPS_ERROR(sm->buf0)))
- dbsm_error_helper(sm, sm->buf0);
- //dbsm_process_helper(sm, sm->buf0); //forward errors
-
- if (status & (BPS_ERROR(sm->buf0 ^ 1)))
- dbsm_error_helper(sm, sm->buf0 ^ 1);
- //dbsm_process_helper(sm, sm->buf0 ^ 1); //forward errors
- }
-
- if (status & BPS_DONE(sm->buf0))
- dbsm_process_helper(sm, sm->buf0);
-
- if (status & BPS_DONE(sm->buf0 ^ 1))
- dbsm_process_helper(sm, sm->buf0 ^ 1);
-}
-
-static void
-dbsm_process_helper(dbsm_t *sm, int buf_this)
-{
- int buf_other = buf_this ^ 1;
-
- bp_clear_buf(buf_this);
-
- if (buffer_state[buf_this] == BS_FILLING){
- buffer_state[buf_this] = BS_FULL;
- //
- // does s/w handle this packet?
- //
- if (sm->inspect(sm, buf_this)){
- // s/w handled the packet; refill the buffer
- dbsm_receive_to_buf(sm, buf_this);
- buffer_state[buf_this] = BS_FILLING;
- }
-
- else { // s/w didn't handle this; pass it on
-
- if(buffer_state[buf_other] == BS_EMPTY){
- dbsm_receive_to_buf(sm, buf_other);
- buffer_state[buf_other] = BS_FILLING;
- }
- else
- sm->rx_idle = true;
-
- if (sm->tx_idle){
- sm->tx_idle = false;
- dbsm_send_from_buf(sm, buf_this);
- buffer_state[buf_this] = BS_EMPTYING;
- }
- }
- }
- else { // buffer was emptying
- buffer_state[buf_this] = BS_EMPTY;
- if (sm->rx_idle){
- sm->rx_idle = false;
- dbsm_receive_to_buf(sm, buf_this);
- buffer_state[buf_this] = BS_FILLING;
- }
- if (buffer_state[buf_other] == BS_FULL){
- dbsm_send_from_buf(sm, buf_other);
- buffer_state[buf_other] = BS_EMPTYING;
- }
- else
- sm->tx_idle = true;
- }
-}
-
-static void
-dbsm_error_helper(dbsm_t *sm, int buf_this)
-{
- bp_clear_buf(buf_this); // clears ERROR flag
-
- if (buffer_state[buf_this] == BS_FILLING){
- dbsm_receive_to_buf(sm, buf_this); // restart the xfer
- }
- else { // buffer was emptying
- dbsm_send_from_buf(sm, buf_this); // restart the xfer
- }
-}
-
-/*
- * Handle DSP Tx underrun
- */
-void
-dbsm_handle_tx_underrun(dbsm_t *sm)
-{
- // clear the DSP Tx state machine
- sr_tx_ctrl->clear_state = 1;
-
- // If there's a buffer that's empyting, clear it & flush xfer
-
- if (buffer_state[sm->buf0] == BS_EMPTYING){
- bp_clear_buf(sm->buf0);
- sr_tx_ctrl->clear_state = 1; // flush partial packet
- // drop frame in progress on ground. Pretend it finished
- dbsm_process_helper(sm, sm->buf0);
- }
- else if (buffer_state[sm->buf0 ^ 1] == BS_EMPTYING){
- bp_clear_buf(sm->buf0 ^ 1);
- sr_tx_ctrl->clear_state = 1; // flush partial packet
- // drop frame in progress on ground. Pretend it finished
- dbsm_process_helper(sm, sm->buf0 ^ 1);
- }
-}
-
-/*
- * Handle DSP Rx overrun
- */
-void
-dbsm_handle_rx_overrun(dbsm_t *sm)
-{
- sr_rx_ctrl->clear_overrun = 1;
-
- // If there's a buffer that's filling, clear it.
- // Any restart will be the job of the caller.
-
- if (buffer_state[sm->buf0] == BS_FILLING)
- bp_clear_buf(sm->buf0);
-
- if (buffer_state[sm->buf0 ^1] == BS_FILLING)
- bp_clear_buf(sm->buf0 ^ 1);
-}
-
-void
-dbsm_wait_for_opening(dbsm_t *sm)
-{
- if (buffer_state[sm->buf0] == BS_EMPTYING){
- // wait for xfer to complete
- int mask = BPS_DONE(sm->buf0) | BPS_ERROR(sm->buf0) | BPS_IDLE(sm->buf0);
- while ((buffer_pool_status->status & mask) == 0)
- ;
- }
- else if (buffer_state[sm->buf0 ^ 1] == BS_EMPTYING){
- // wait for xfer to complete
- int mask = BPS_DONE(sm->buf0 ^ 1) | BPS_ERROR(sm->buf0 ^ 1) | BPS_IDLE(sm->buf0 ^ 1);
- while ((buffer_pool_status->status & mask) == 0)
- ;
- }
-}