📄 scratch_rings.c
字号:
// Copyright (C) 2002-2003 Intel Corporation, All Rights Reserved.
// Permission is hereby granted to merge this program code with
// other program material to create a derivative work. This
// derivative work may be distributed in compiled object form only.
// Any other publication of this program, in any form, without the
// explicit permission of the copyright holder is prohibited.
//
// Send questions and comments to erik.j.johnson@intel.com,
// aaron.kunze@intel.com
//-------------------------------------------------------------------
// rings.c - Chapter 5
// Common utilities for accessing the scratch rings used between
// rx, processing and tx
//
#include "ixp.h"
#include "scratch_rings.h"
//-------------------------------------------------------------------
// scratch_ring_init
//
// Description:
// Initialize the given scratch ring
//
// Parameters:
// Outputs: n/a
// In/Outs: n/a
// Inputs: ring_number - The scratchpad ring number
// ring_base - The base address in scratchpad memory
// for the ring data
// ring_size - The number of long words for the ring
// Constants: n/a
// Labels: n/a
//
// Side effects: n/a
// See also: n/a
//
void scratch_ring_init(
unsigned int ring_number,
unsigned int ring_base,
unsigned int ring_size)
{
__declspec(sram_write_reg) unsigned int ring_init;
__declspec(sram_write_reg) unsigned int ring_head;
__declspec(sram_write_reg) unsigned int ring_tail;
SIGNAL ring_init_sig,
ring_head_sig,
ring_tail_sig;
ring_init = ring_base |
(((ring_size/128)-1) << RING_BASE_SIZE_BITPOS);
cap_write(&ring_init,
csr_scratch_ring_base_0 +
(ring_number * 16),
1,
sig_initiator,
sig_done,
&ring_init_sig);
ring_head = 0;
cap_write(&ring_head,
csr_scratch_ring_head_0 +
(ring_number * 16),
1,
sig_initiator,
sig_done,
&ring_head_sig);
ring_tail = 0;
cap_write(&ring_tail,
csr_scratch_ring_tail_0 +
(ring_number * 16),
1,
sig_initiator,
sig_done,
&ring_tail_sig);
wait_for_all(&ring_init_sig,
&ring_head_sig,
&ring_tail_sig);
free_write_buffer(&ring_init);
free_write_buffer(&ring_head);
free_write_buffer(&ring_tail);
}
//-------------------------------------------------------------------
// scratch_ring_empty
//
// Description:
// Check if the given scratchpad ring is empty.
//
// Parameters:
// Outputs: n/a
// In/Outs: n/a
// Inputs: ring_number - The scratchpad ring number
// Constants: n/a
// Labels: n/a
//
// Side effects: This function cannot atomically check for
// an empty ring. Instead, it reads both the head and tail
// pointers (non-atomically) and compares them.
// See also: n/a
//
bool scratch_ring_empty(unsigned int ring_number)
{
__declspec(sram_read_reg) unsigned int ring_head;
__declspec(sram_read_reg) unsigned int ring_tail;
SIGNAL ring_head_sig;
SIGNAL ring_tail_sig;
cap_read(&ring_head,
csr_scratch_ring_head_0 +
(ring_number * 16),
1,
sig_initiator,
sig_done,
&ring_head_sig);
cap_read(&ring_tail,
csr_scratch_ring_tail_0 +
(ring_number * 16),
1,
sig_initiator,
sig_done,
&ring_tail_sig);
wait_for_all(&ring_head_sig, &ring_tail_sig);
return ring_head == ring_tail ? 1 : 0;
}
//-------------------------------------------------------------------
// scratch_ring_get_buffer
//
// Description:
// Dequeue a buffer, length and offset tuple from the given
// scratchpad ring.
//
// Parameters:
// Outputs: ring data, which includes:
// handle - the buffer handle
// length - the length, in bytes, of the buffer
// offset - the offset of the start of the actual data
// within the buffer, in bytes
// In/Outs: n/a
// Inputs: ring_number - The scratchpad ring number
// Constants: n/a
// Labels: n/a
//
// Side effects: n/a
// See also: n/a
//
void scratch_ring_get_buffer(
unsigned int ring_number,
ring_data_t *data)
{
__declspec(scratch) void* ring_addr =
(void*)(ring_number << 2);
SIGNAL ring_signal;
__declspec(sram_read_reg) ring_data_t packet;
scratch_get_ring(&packet,
ring_addr,
sizeof(packet) / sizeof(unsigned int),
ctx_swap,
&ring_signal);
*data = packet;
}
//-------------------------------------------------------------------
// scratch_ring_put_buffer
//
// Description:
// Put (enqueue) a buffer, length and offset tuple onto the
// given scratchpad ring.
//
// Parameters:
// Outputs: n/a
// In/Outs: n/a
// Inputs: ring_number - The scratchpad ring number
// ring data, which includes:
// handle - the buffer handle
// length - the length, in bytes, of the buffer
// offset - the offset of the start of the actual data
// within the buffer, in bytes
// Constants: n/a
// Labels: n/a
//
// Side effects: n/a
// See also: n/a
//
void scratch_ring_put_buffer(
unsigned int ring_number,
ring_data_t data)
{
__declspec(scratch) void* ring_addr =
(void*)(ring_number << 2);
SIGNAL ring_signal;
__declspec(sram_write_reg) ring_data_t packet;
packet = data;
scratch_put_ring(&packet,
ring_addr,
sizeof(packet) / sizeof(unsigned int),
ctx_swap,
&ring_signal);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -