add a byte-reversed access mode to accel registers, avoid the byte-reverse on the host
This commit is contained in:
parent
fbcfe3152c
commit
9a50f36153
|
@ -67,6 +67,9 @@ static inline unsigned long brev(const unsigned long r) {
|
|||
#define WAIT_FOR_HW(accel) \
|
||||
while (accel->reg_status & brev(1<<WORK_IN_PROGRESS_BIT))
|
||||
|
||||
#define WAIT_FOR_HW_LE(accel_le) \
|
||||
while (accel_le->reg_status & (1<<WORK_IN_PROGRESS_BIT))
|
||||
|
||||
#define uint8_t unsigned char
|
||||
#define uint16_t unsigned short
|
||||
#define uint32_t unsigned long
|
||||
|
@ -378,7 +381,7 @@ struct qdstuff {
|
|||
|
||||
int hwblit(char* stack, char* p_fb_base, /* short dstshift, */ short mode, Pattern* pat, PixMapPtr dstpix, PixMapPtr srcpix, Rect *dstrect, Rect *srcrect) {
|
||||
struct goblin_bt_regs* bt = (struct goblin_bt_regs*)(p_fb_base + GOBLIN_BT_OFFSET);
|
||||
struct goblin_accel_regs* accel = (struct goblin_accel_regs*)(p_fb_base + GOBLIN_ACCEL_OFFSET);
|
||||
struct goblin_accel_regs* accel_le = (struct goblin_accel_regs*)(p_fb_base + GOBLIN_ACCEL_OFFSET_LE);
|
||||
struct qdstuff* qdstack = (struct qdstuff*)(stack - sizeof(struct qdstuff));
|
||||
short height = qdstack->MINRECT.bottom - qdstack->MINRECT.top;
|
||||
short dstshift = qdstack->DSTSHIFT;
|
||||
|
@ -520,23 +523,23 @@ int hwblit(char* stack, char* p_fb_base, /* short dstshift, */ short mode, Patte
|
|||
|
||||
return 0;
|
||||
#else
|
||||
WAIT_FOR_HW(accel);
|
||||
WAIT_FOR_HW_LE(accel_le);
|
||||
|
||||
accel->reg_width = brev(width);
|
||||
accel->reg_height = brev(height);
|
||||
accel->reg_bitblt_dst_x = brev(dstv.left << dstshift);
|
||||
accel->reg_bitblt_dst_y = brev(dstv.top);
|
||||
accel_le->reg_width = (width);
|
||||
accel_le->reg_height = (height);
|
||||
accel_le->reg_bitblt_dst_x = (dstv.left << dstshift);
|
||||
accel_le->reg_bitblt_dst_y = (dstv.top);
|
||||
|
||||
if (mode == 0) {
|
||||
accel->reg_bitblt_src_x = brev(srcv.left << dstshift);
|
||||
accel->reg_bitblt_src_y = brev(srcv.top);
|
||||
accel->reg_cmd = brev(1<<DO_BLIT_BIT);
|
||||
accel_le->reg_bitblt_src_x = (srcv.left << dstshift);
|
||||
accel_le->reg_bitblt_src_y = (srcv.top);
|
||||
accel_le->reg_cmd = (1<<DO_BLIT_BIT);
|
||||
} else if (mode == 8) {
|
||||
accel->reg_fgcolor = qdstack->EXPAT[0];
|
||||
accel->reg_cmd = brev(1<<DO_FILL_BIT);
|
||||
accel_le->reg_fgcolor = (qdstack->EXPAT[0]);
|
||||
accel_le->reg_cmd = (1<<DO_FILL_BIT);
|
||||
}
|
||||
|
||||
WAIT_FOR_HW(accel);
|
||||
WAIT_FOR_HW_LE(accel_le);
|
||||
|
||||
return 1;
|
||||
#endif
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
|
||||
#define GOBLIN_FB_BASE 0xFC000000 // FIXME !!!!
|
||||
|
||||
#define GOBLIN_BT_OFFSET 0x00900000
|
||||
#define GOBLIN_ACCEL_OFFSET 0x00901000
|
||||
#define GOBLIN_BT_OFFSET 0x00900000
|
||||
#define GOBLIN_ACCEL_OFFSET 0x00901000
|
||||
#define GOBLIN_ACCEL_OFFSET_LE 0x00901800
|
||||
|
||||
#define u_int32_t volatile unsigned long
|
||||
|
||||
|
@ -14,6 +15,7 @@
|
|||
// cmd
|
||||
#define DO_BLIT_BIT 0 // hardwired in goblin_accel.py
|
||||
#define DO_FILL_BIT 1 // hardwired in goblin_accel.py
|
||||
#define DO_TEST_BIT 3 // hardwired in goblin_accel.py
|
||||
|
||||
|
||||
#define FUN_DONE_BIT 31
|
||||
|
@ -30,19 +32,20 @@ struct goblin_bt_regs {
|
|||
};
|
||||
|
||||
struct goblin_accel_regs {
|
||||
u_int32_t reg_status;
|
||||
u_int32_t reg_status; // 0
|
||||
u_int32_t reg_cmd;
|
||||
u_int32_t reg_r5_cmd;
|
||||
u_int32_t resv0;
|
||||
u_int32_t reg_width;
|
||||
u_int32_t reg_width; // 4
|
||||
u_int32_t reg_height;
|
||||
u_int32_t reg_fgcolor;
|
||||
u_int32_t resv2;
|
||||
u_int32_t reg_bitblt_src_x;
|
||||
u_int32_t reg_bitblt_src_x; // 8
|
||||
u_int32_t reg_bitblt_src_y;
|
||||
u_int32_t reg_bitblt_dst_x;
|
||||
u_int32_t reg_bitblt_dst_y;
|
||||
|
||||
u_int32_t reg_chk_adr; // 12
|
||||
u_int32_t reg_chk_val;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -42,52 +42,72 @@ class GoblinAccel(Module): # AutoCSR ?
|
|||
# global status register reg_status
|
||||
WORK_IN_PROGRESS_BIT = 0
|
||||
|
||||
# replicate all registers in both endianess
|
||||
# we want to avoid byte-reversal on either the host or the Vex
|
||||
bus_dat_w_endian = Signal(32)
|
||||
bus_dat_r_endian = Signal(32)
|
||||
self.comb += [
|
||||
If(bus.adr[9], # 9 on bus is 11 for host
|
||||
bus_dat_w_endian[24:32].eq(bus.dat_w[ 0: 8]),
|
||||
bus_dat_w_endian[16:24].eq(bus.dat_w[ 8:16]),
|
||||
bus_dat_w_endian[ 8:16].eq(bus.dat_w[16:24]),
|
||||
bus_dat_w_endian[ 0: 8].eq(bus.dat_w[24:32]),
|
||||
bus.dat_r[24:32].eq(bus_dat_r_endian[ 0: 8]),
|
||||
bus.dat_r[16:24].eq(bus_dat_r_endian[ 8:16]),
|
||||
bus.dat_r[ 8:16].eq(bus_dat_r_endian[16:24]),
|
||||
bus.dat_r[ 0: 8].eq(bus_dat_r_endian[24:32]),
|
||||
).Else(
|
||||
bus_dat_w_endian.eq(bus.dat_w),
|
||||
bus.dat_r.eq(bus_dat_r_endian),
|
||||
)
|
||||
]
|
||||
|
||||
self.submodules.wishbone_fsm = wishbone_fsm = FSM(reset_state = "Reset")
|
||||
wishbone_fsm.act("Reset",
|
||||
NextValue(bus.ack, 0),
|
||||
NextState("Idle"))
|
||||
wishbone_fsm.act("Idle",
|
||||
If(bus.cyc & bus.stb & bus.we & ~bus.ack, #write
|
||||
Case(bus.adr[0:10], { #
|
||||
Case(bus.adr[0:9], { # bit 9 is used for endianess, so not there
|
||||
"default": [ ],
|
||||
# 0: reg_status R/O
|
||||
0: [ NextValue(reg_status, bus.dat_w) ], # debug, remove me
|
||||
1: [ NextValue(reg_cmd, bus.dat_w),
|
||||
NextValue(do_blit, bus.dat_w[DO_BLIT_BIT] & ~reg_status[WORK_IN_PROGRESS_BIT]),
|
||||
NextValue(do_fill, bus.dat_w[DO_FILL_BIT] & ~reg_status[WORK_IN_PROGRESS_BIT]),
|
||||
NextValue(do_test, bus.dat_w[DO_TEST_BIT] & ~reg_status[WORK_IN_PROGRESS_BIT]),
|
||||
0: [ NextValue(reg_status, bus_dat_w_endian) ], # debug, remove me
|
||||
1: [ NextValue(reg_cmd, bus_dat_w_endian),
|
||||
NextValue(do_blit, bus_dat_w_endian[DO_BLIT_BIT] & ~reg_status[WORK_IN_PROGRESS_BIT]),
|
||||
NextValue(do_fill, bus_dat_w_endian[DO_FILL_BIT] & ~reg_status[WORK_IN_PROGRESS_BIT]),
|
||||
NextValue(do_test, bus_dat_w_endian[DO_TEST_BIT] & ~reg_status[WORK_IN_PROGRESS_BIT]),
|
||||
],
|
||||
2: [ NextValue(reg_r5_cmd, bus.dat_w) ],
|
||||
2: [ NextValue(reg_r5_cmd, bus_dat_w_endian) ],
|
||||
# 3
|
||||
4: [ NextValue(reg_width, bus.dat_w) ],
|
||||
5: [ NextValue(reg_height, bus.dat_w) ],
|
||||
6: [ NextValue(reg_fgcolor, bus.dat_w) ],
|
||||
4: [ NextValue(reg_width, bus_dat_w_endian) ],
|
||||
5: [ NextValue(reg_height, bus_dat_w_endian) ],
|
||||
6: [ NextValue(reg_fgcolor, bus_dat_w_endian) ],
|
||||
# 7
|
||||
8: [ NextValue(reg_bitblt_src_x, bus.dat_w) ],
|
||||
9: [ NextValue(reg_bitblt_src_y, bus.dat_w) ],
|
||||
10: [ NextValue(reg_bitblt_dst_x, bus.dat_w) ],
|
||||
11: [ NextValue(reg_bitblt_dst_y, bus.dat_w) ],
|
||||
12: [ NextValue(reg_chk_adr, bus.dat_w) ],
|
||||
13: [ NextValue(reg_chk_val, bus.dat_w) ],
|
||||
8: [ NextValue(reg_bitblt_src_x, bus_dat_w_endian) ],
|
||||
9: [ NextValue(reg_bitblt_src_y, bus_dat_w_endian) ],
|
||||
10: [ NextValue(reg_bitblt_dst_x, bus_dat_w_endian) ],
|
||||
11: [ NextValue(reg_bitblt_dst_y, bus_dat_w_endian) ],
|
||||
12: [ NextValue(reg_chk_adr, bus_dat_w_endian) ],
|
||||
13: [ NextValue(reg_chk_val, bus_dat_w_endian) ],
|
||||
}),
|
||||
NextValue(bus.ack, 1),
|
||||
).Elif(bus.cyc & bus.stb & ~bus.we & ~bus.ack, #read
|
||||
Case(bus.adr[0:10], {
|
||||
"default": [ NextValue(bus.dat_r, 0xDEADBEEF) ],
|
||||
0: [ NextValue(bus.dat_r, reg_status) ],
|
||||
1: [ NextValue(bus.dat_r, reg_cmd) ],
|
||||
2: [ NextValue(bus.dat_r, reg_r5_cmd) ],
|
||||
Case(bus.adr[0:9], { # bit 9 is used for endianess, so not there
|
||||
"default": [ NextValue(bus_dat_r_endian, 0xDEADBEEF) ],
|
||||
0: [ NextValue(bus_dat_r_endian, reg_status) ],
|
||||
1: [ NextValue(bus_dat_r_endian, reg_cmd) ],
|
||||
2: [ NextValue(bus_dat_r_endian, reg_r5_cmd) ],
|
||||
# 3
|
||||
4: [ NextValue(bus.dat_r, reg_width) ],
|
||||
5: [ NextValue(bus.dat_r, reg_height) ],
|
||||
6: [ NextValue(bus.dat_r, reg_fgcolor) ],
|
||||
4: [ NextValue(bus_dat_r_endian, reg_width) ],
|
||||
5: [ NextValue(bus_dat_r_endian, reg_height) ],
|
||||
6: [ NextValue(bus_dat_r_endian, reg_fgcolor) ],
|
||||
# 7
|
||||
8: [ NextValue(bus.dat_r, reg_bitblt_src_x) ],
|
||||
9: [ NextValue(bus.dat_r, reg_bitblt_src_y) ],
|
||||
10: [ NextValue(bus.dat_r, reg_bitblt_dst_x) ],
|
||||
11: [ NextValue(bus.dat_r, reg_bitblt_dst_y) ],
|
||||
12: [ NextValue(bus.dat_r, reg_chk_adr) ],
|
||||
13: [ NextValue(bus.dat_r, reg_chk_val) ],
|
||||
8: [ NextValue(bus_dat_r_endian, reg_bitblt_src_x) ],
|
||||
9: [ NextValue(bus_dat_r_endian, reg_bitblt_src_y) ],
|
||||
10: [ NextValue(bus_dat_r_endian, reg_bitblt_dst_x) ],
|
||||
11: [ NextValue(bus_dat_r_endian, reg_bitblt_dst_y) ],
|
||||
12: [ NextValue(bus_dat_r_endian, reg_chk_adr) ],
|
||||
13: [ NextValue(bus_dat_r_endian, reg_chk_val) ],
|
||||
}),
|
||||
NextValue(bus.ack, 1),
|
||||
).Else(
|
||||
|
|
Loading…
Reference in New Issue