Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 300813
b: refs/heads/master
c: 91fbe33
h: refs/heads/master
i:
  300811: 7519cc9
v: v3
  • Loading branch information
David S. Miller committed Apr 18, 2012
1 parent ce8124e commit 8b1c978
Show file tree
Hide file tree
Showing 8 changed files with 636 additions and 214 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1e5cc266dbc401d11aefb966ad35e651c2f67414
refs/heads/master: 91fbe33034c184c6a60e31c2207a2f7ec2f180dc
20 changes: 18 additions & 2 deletions trunk/arch/sparc/net/bpf_jit.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
/* Conventions:
* %g1 : temporary
* %g2 : Secondary temporary used by SKB data helper stubs.
* %g3 : packet offset passed into SKB data helper stubs.
* %o0 : pointer to skb (first argument given to JIT function)
* %o1 : BPF A accumulator
* %o2 : BPF X accumulator
* %o3 : Holds saved %o7 so we can call helper functions without needing
* to allocate a register window.
* %o4 : skb->data
* %o5 : skb->len - skb->data_len
* %o4 : skb->len - skb->data_len
* %o5 : skb->data
*/

#ifndef __ASSEMBLER__
Expand All @@ -37,6 +38,21 @@
#define r_TMP G1
#define r_TMP2 G2
#define r_OFF G3

/* assembly code in arch/sparc/net/bpf_jit_asm.S */
extern u32 bpf_jit_load_word[];
extern u32 bpf_jit_load_half[];
extern u32 bpf_jit_load_byte[];
extern u32 bpf_jit_load_byte_msh[];
extern u32 bpf_jit_load_word_positive_offset[];
extern u32 bpf_jit_load_half_positive_offset[];
extern u32 bpf_jit_load_byte_positive_offset[];
extern u32 bpf_jit_load_byte_msh_positive_offset[];
extern u32 bpf_jit_load_word_negative_offset[];
extern u32 bpf_jit_load_half_negative_offset[];
extern u32 bpf_jit_load_byte_negative_offset[];
extern u32 bpf_jit_load_byte_msh_negative_offset[];

#else
#define r_SKB %o0
#define r_A %o1
Expand Down
10 changes: 8 additions & 2 deletions trunk/arch/sparc/net/bpf_jit_asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ bpf_jit_load_word_positive_offset:
bne load_word_unaligned
nop
retl
ld [r_SKB_DATA + r_OFF], r_A
ld [r_TMP], r_A
load_word_unaligned:
ldub [r_TMP + 0x0], r_OFF
ldub [r_TMP + 0x1], r_TMP2
Expand Down Expand Up @@ -59,7 +59,7 @@ bpf_jit_load_half_positive_offset:
bne load_half_unaligned
nop
retl
lduh [r_SKB_DATA + r_OFF], r_A
lduh [r_TMP], r_A
load_half_unaligned:
ldub [r_TMP + 0x0], r_OFF
ldub [r_TMP + 0x1], r_TMP2
Expand Down Expand Up @@ -195,5 +195,11 @@ bpf_jit_load_byte_msh_negative_offset:
sll r_OFF, 2, r_X

bpf_error:
/* Make the JIT program return zero. The JIT epilogue
* stores away the original %o7 into r_saved_O7. The
* normal leaf function return is to use "retl" which
* would evalute to "jmpl %o7 + 8, %g0" but we want to
* use the saved value thus the sequence you see here.
*/
jmpl r_saved_O7 + 8, %g0
clr %o0
111 changes: 64 additions & 47 deletions trunk/arch/sparc/net/bpf_jit_comp.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,6 @@

int bpf_jit_enable __read_mostly;

/* assembly code in arch/sparc/net/bpf_jit_asm.S */
extern u32 bpf_jit_load_word[];
extern u32 bpf_jit_load_half[];
extern u32 bpf_jit_load_byte[];
extern u32 bpf_jit_load_byte_msh[];
extern u32 bpf_jit_load_word_positive_offset[];
extern u32 bpf_jit_load_half_positive_offset[];
extern u32 bpf_jit_load_byte_positive_offset[];
extern u32 bpf_jit_load_byte_msh_positive_offset[];
extern u32 bpf_jit_load_word_negative_offset[];
extern u32 bpf_jit_load_half_negative_offset[];
extern u32 bpf_jit_load_byte_negative_offset[];
extern u32 bpf_jit_load_byte_msh_negative_offset[];

static inline bool is_simm13(unsigned int value)
{
return value + 0x1000 < 0x2000;
Expand Down Expand Up @@ -65,22 +51,22 @@ static void bpf_flush_icache(void *start_, void *end_)
#define F2(X, Y) (OP(X) | OP2(Y))
#define F3(X, Y) (OP(X) | OP3(Y))

#define CONDN COND (0x0)
#define CONDE COND (0x1)
#define CONDLE COND (0x2)
#define CONDL COND (0x3)
#define CONDLEU COND (0x4)
#define CONDCS COND (0x5)
#define CONDNEG COND (0x6)
#define CONDVC COND (0x7)
#define CONDA COND (0x8)
#define CONDNE COND (0x9)
#define CONDG COND (0xa)
#define CONDGE COND (0xb)
#define CONDGU COND (0xc)
#define CONDCC COND (0xd)
#define CONDPOS COND (0xe)
#define CONDVS COND (0xf)
#define CONDN COND(0x0)
#define CONDE COND(0x1)
#define CONDLE COND(0x2)
#define CONDL COND(0x3)
#define CONDLEU COND(0x4)
#define CONDCS COND(0x5)
#define CONDNEG COND(0x6)
#define CONDVC COND(0x7)
#define CONDA COND(0x8)
#define CONDNE COND(0x9)
#define CONDG COND(0xa)
#define CONDGE COND(0xb)
#define CONDGU COND(0xc)
#define CONDCC COND(0xd)
#define CONDPOS COND(0xe)
#define CONDVS COND(0xf)

#define CONDGEU CONDCC
#define CONDLU CONDCS
Expand Down Expand Up @@ -172,7 +158,7 @@ do { /* sethi %hi(K), REG */ \

/* Emit
*
* OP r_A, r_X, r_A
* OP r_A, r_X, r_A
*/
#define emit_alu_X(OPCODE) \
do { \
Expand All @@ -195,7 +181,7 @@ do { \
* is zero.
*/
#define emit_alu_K(OPCODE, K) \
do { \
do { \
if (K) { \
unsigned int _insn = OPCODE; \
_insn |= RS1(r_A) | RD(r_A); \
Expand All @@ -204,7 +190,7 @@ do { \
} else { \
emit_set_const(K, r_TMP); \
*prog++ = _insn | RS2(r_TMP); \
} \
} \
} \
} while (0)

Expand All @@ -222,39 +208,37 @@ do { \
do { unsigned int _off = offsetof(STRUCT, FIELD); \
BUILD_BUG_ON(FIELD_SIZEOF(STRUCT, FIELD) != sizeof(void *)); \
*prog++ = LDPTRI | RS1(BASE) | S13(_off) | RD(DEST); \
} while(0)
} while (0)

#define emit_load32(BASE, STRUCT, FIELD, DEST) \
do { unsigned int _off = offsetof(STRUCT, FIELD); \
BUILD_BUG_ON(FIELD_SIZEOF(STRUCT, FIELD) != sizeof(u32)); \
*prog++ = LD32I | RS1(BASE) | S13(_off) | RD(DEST); \
} while(0)
} while (0)

#define emit_load16(BASE, STRUCT, FIELD, DEST) \
do { unsigned int _off = offsetof(STRUCT, FIELD); \
BUILD_BUG_ON(FIELD_SIZEOF(STRUCT, FIELD) != sizeof(u16)); \
*prog++ = LD16I | RS1(BASE) | S13(_off) | RD(DEST); \
} while(0)
} while (0)

#define __emit_load8(BASE, STRUCT, FIELD, DEST) \
do { unsigned int _off = offsetof(STRUCT, FIELD); \
*prog++ = LD8I | RS1(BASE) | S13(_off) | RD(DEST); \
} while(0)
} while (0)

#define emit_load8(BASE, STRUCT, FIELD, DEST) \
do { BUILD_BUG_ON(FIELD_SIZEOF(STRUCT, FIELD) != sizeof(u8)); \
__emit_load8(BASE, STRUCT, FIELD, DEST); \
} while(0)
} while (0)

#define emit_ldmem(OFF, DEST) \
do { *prog++ = LD32I | RS1(FP) | S13(-(OFF)) | RD(DEST); \
} while(0)
} while (0)

#define emit_stmem(OFF, SRC) \
do { *prog++ = LD32I | RS1(FP) | S13(-(OFF)) | RD(SRC); \
} while(0)

#define cpu_off offsetof(struct thread_info, cpu)
} while (0)

#ifdef CONFIG_SMP
#ifdef CONFIG_SPARC64
Expand Down Expand Up @@ -292,16 +276,16 @@ do { void *_here = image + addrs[i] - 8; \
#define emit_branch(BR_OPC, DEST) \
do { unsigned int _here = addrs[i] - 8; \
*prog++ = BR_OPC | WDISP22((DEST) - _here); \
} while(0)
} while (0)

#define emit_branch_off(BR_OPC, OFF) \
do { *prog++ = BR_OPC | WDISP22(OFF); \
} while(0)
} while (0)

#define emit_jump(DEST) emit_branch(BA, DEST)

#define emit_read_y(REG) *prog++ = RD_Y | RD(REG);
#define emit_write_y(REG) *prog++ = WR_Y | IMMED | RS1(REG) | S13(0);
#define emit_read_y(REG) *prog++ = RD_Y | RD(REG)
#define emit_write_y(REG) *prog++ = WR_Y | IMMED | RS1(REG) | S13(0)

#define emit_cmp(R1, R2) \
*prog++ = (SUBCC | RS1(R1) | RS2(R2) | RD(G0))
Expand Down Expand Up @@ -333,6 +317,35 @@ do { *prog++ = BR_OPC | WDISP22(OFF); \
#define emit_release_stack(SZ) \
*prog++ = (ADD | IMMED | RS1(SP) | S13(SZ) | RD(SP))

/* A note about branch offset calculations. The addrs[] array,
* indexed by BPF instruction, records the address after all the
* sparc instructions emitted for that BPF instruction.
*
* The most common case is to emit a branch at the end of such
* a code sequence. So this would be two instructions, the
* branch and it's delay slot.
*
* Therefore by default the branch emitters calculate the branch
* offset field as:
*
* destination - (addrs[i] - 8)
*
* This "addrs[i] - 8" is the address of the branch itself or
* what "." would be in assembler notation. The "8" part is
* how we take into consideration the branch and it's delay
* slot mentioned above.
*
* Sometimes we need to emit a branch earlier in the code
* sequence. And in these situations we adjust "destination"
* to accomodate this difference. For example, if we needed
* to emit a branch (and it's delay slot) right before the
* final instruction emitted for a BPF opcode, we'd use
* "destination + 4" instead of just plain "destination" above.
*
* This is why you see all of these funny emit_branch() and
* emit_jump() calls with adjusted offsets.
*/

void bpf_jit_compile(struct sk_filter *fp)
{
unsigned int cleanup_addr, proglen, oldproglen = 0;
Expand Down Expand Up @@ -378,7 +391,7 @@ void bpf_jit_compile(struct sk_filter *fp)
emit_clear(r_X);

/* If this filter needs to access skb data,
* load %o4 and %o4 with:
* load %o4 and %o5 with:
* %o4 = skb->len - skb->data_len
* %o5 = skb->data
* And also back up %o7 into r_saved_O7 so we can
Expand Down Expand Up @@ -493,6 +506,10 @@ void bpf_jit_compile(struct sk_filter *fp)
}
emit_write_y(G0);
#ifdef CONFIG_SPARC32
/* The Sparc v8 architecture requires
* three instructions between a %y
* register write and the first use.
*/
emit_nop();
emit_nop();
emit_nop();
Expand Down
6 changes: 5 additions & 1 deletion trunk/drivers/net/ethernet/dec/tulip/dmfe.c
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,7 @@ static int dmfe_stop(struct DEVICE *dev)

/* Reset & stop DM910X board */
dw32(DCR0, DM910X_RESET);
udelay(5);
udelay(100);
phy_write(ioaddr, db->phy_addr, 0, 0x8000, db->chip_id);

/* free interrupt */
Expand Down Expand Up @@ -1601,7 +1601,9 @@ static u16 read_srom_word(void __iomem *ioaddr, int offset)
int i;

dw32(DCR9, CR9_SROM_READ);
udelay(5);
dw32(DCR9, CR9_SROM_READ | CR9_SRCS);
udelay(5);

/* Send the Read Command 110b */
srom_clk_write(ioaddr, SROM_DATA_1);
Expand All @@ -1615,6 +1617,7 @@ static u16 read_srom_word(void __iomem *ioaddr, int offset)
}

dw32(DCR9, CR9_SROM_READ | CR9_SRCS);
udelay(5);

for (i = 16; i > 0; i--) {
dw32(DCR9, CR9_SROM_READ | CR9_SRCS | CR9_SRCLK);
Expand All @@ -1626,6 +1629,7 @@ static u16 read_srom_word(void __iomem *ioaddr, int offset)
}

dw32(DCR9, CR9_SROM_READ);
udelay(5);
return srom_data;
}

Expand Down
Loading

0 comments on commit 8b1c978

Please sign in to comment.