mirror of
https://github.com/rdolbeau/NuBusFPGA.git
synced 2024-06-17 13:29:40 +00:00
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) \
|
#define WAIT_FOR_HW(accel) \
|
||||||
while (accel->reg_status & brev(1<<WORK_IN_PROGRESS_BIT))
|
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 uint8_t unsigned char
|
||||||
#define uint16_t unsigned short
|
#define uint16_t unsigned short
|
||||||
#define uint32_t unsigned long
|
#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) {
|
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_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));
|
struct qdstuff* qdstack = (struct qdstuff*)(stack - sizeof(struct qdstuff));
|
||||||
short height = qdstack->MINRECT.bottom - qdstack->MINRECT.top;
|
short height = qdstack->MINRECT.bottom - qdstack->MINRECT.top;
|
||||||
short dstshift = qdstack->DSTSHIFT;
|
short dstshift = qdstack->DSTSHIFT;
|
||||||
|
@ -520,23 +523,23 @@ int hwblit(char* stack, char* p_fb_base, /* short dstshift, */ short mode, Patte
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
WAIT_FOR_HW(accel);
|
WAIT_FOR_HW_LE(accel_le);
|
||||||
|
|
||||||
accel->reg_width = brev(width);
|
accel_le->reg_width = (width);
|
||||||
accel->reg_height = brev(height);
|
accel_le->reg_height = (height);
|
||||||
accel->reg_bitblt_dst_x = brev(dstv.left << dstshift);
|
accel_le->reg_bitblt_dst_x = (dstv.left << dstshift);
|
||||||
accel->reg_bitblt_dst_y = brev(dstv.top);
|
accel_le->reg_bitblt_dst_y = (dstv.top);
|
||||||
|
|
||||||
if (mode == 0) {
|
if (mode == 0) {
|
||||||
accel->reg_bitblt_src_x = brev(srcv.left << dstshift);
|
accel_le->reg_bitblt_src_x = (srcv.left << dstshift);
|
||||||
accel->reg_bitblt_src_y = brev(srcv.top);
|
accel_le->reg_bitblt_src_y = (srcv.top);
|
||||||
accel->reg_cmd = brev(1<<DO_BLIT_BIT);
|
accel_le->reg_cmd = (1<<DO_BLIT_BIT);
|
||||||
} else if (mode == 8) {
|
} else if (mode == 8) {
|
||||||
accel->reg_fgcolor = qdstack->EXPAT[0];
|
accel_le->reg_fgcolor = (qdstack->EXPAT[0]);
|
||||||
accel->reg_cmd = brev(1<<DO_FILL_BIT);
|
accel_le->reg_cmd = (1<<DO_FILL_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
WAIT_FOR_HW(accel);
|
WAIT_FOR_HW_LE(accel_le);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
|
|
||||||
#define GOBLIN_FB_BASE 0xFC000000 // FIXME !!!!
|
#define GOBLIN_FB_BASE 0xFC000000 // FIXME !!!!
|
||||||
|
|
||||||
#define GOBLIN_BT_OFFSET 0x00900000
|
#define GOBLIN_BT_OFFSET 0x00900000
|
||||||
#define GOBLIN_ACCEL_OFFSET 0x00901000
|
#define GOBLIN_ACCEL_OFFSET 0x00901000
|
||||||
|
#define GOBLIN_ACCEL_OFFSET_LE 0x00901800
|
||||||
|
|
||||||
#define u_int32_t volatile unsigned long
|
#define u_int32_t volatile unsigned long
|
||||||
|
|
||||||
|
@ -14,6 +15,7 @@
|
||||||
// cmd
|
// cmd
|
||||||
#define DO_BLIT_BIT 0 // hardwired in goblin_accel.py
|
#define DO_BLIT_BIT 0 // hardwired in goblin_accel.py
|
||||||
#define DO_FILL_BIT 1 // 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
|
#define FUN_DONE_BIT 31
|
||||||
|
@ -30,19 +32,20 @@ struct goblin_bt_regs {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct goblin_accel_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_cmd;
|
||||||
u_int32_t reg_r5_cmd;
|
u_int32_t reg_r5_cmd;
|
||||||
u_int32_t resv0;
|
u_int32_t resv0;
|
||||||
u_int32_t reg_width;
|
u_int32_t reg_width; // 4
|
||||||
u_int32_t reg_height;
|
u_int32_t reg_height;
|
||||||
u_int32_t reg_fgcolor;
|
u_int32_t reg_fgcolor;
|
||||||
u_int32_t resv2;
|
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_src_y;
|
||||||
u_int32_t reg_bitblt_dst_x;
|
u_int32_t reg_bitblt_dst_x;
|
||||||
u_int32_t reg_bitblt_dst_y;
|
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
|
# global status register reg_status
|
||||||
WORK_IN_PROGRESS_BIT = 0
|
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")
|
self.submodules.wishbone_fsm = wishbone_fsm = FSM(reset_state = "Reset")
|
||||||
wishbone_fsm.act("Reset",
|
wishbone_fsm.act("Reset",
|
||||||
NextValue(bus.ack, 0),
|
NextValue(bus.ack, 0),
|
||||||
NextState("Idle"))
|
NextState("Idle"))
|
||||||
wishbone_fsm.act("Idle",
|
wishbone_fsm.act("Idle",
|
||||||
If(bus.cyc & bus.stb & bus.we & ~bus.ack, #write
|
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": [ ],
|
"default": [ ],
|
||||||
# 0: reg_status R/O
|
# 0: reg_status R/O
|
||||||
0: [ NextValue(reg_status, bus.dat_w) ], # debug, remove me
|
0: [ NextValue(reg_status, bus_dat_w_endian) ], # debug, remove me
|
||||||
1: [ NextValue(reg_cmd, bus.dat_w),
|
1: [ NextValue(reg_cmd, bus_dat_w_endian),
|
||||||
NextValue(do_blit, bus.dat_w[DO_BLIT_BIT] & ~reg_status[WORK_IN_PROGRESS_BIT]),
|
NextValue(do_blit, bus_dat_w_endian[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_fill, bus_dat_w_endian[DO_FILL_BIT] & ~reg_status[WORK_IN_PROGRESS_BIT]),
|
||||||
NextValue(do_test, bus.dat_w[DO_TEST_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
|
# 3
|
||||||
4: [ NextValue(reg_width, bus.dat_w) ],
|
4: [ NextValue(reg_width, bus_dat_w_endian) ],
|
||||||
5: [ NextValue(reg_height, bus.dat_w) ],
|
5: [ NextValue(reg_height, bus_dat_w_endian) ],
|
||||||
6: [ NextValue(reg_fgcolor, bus.dat_w) ],
|
6: [ NextValue(reg_fgcolor, bus_dat_w_endian) ],
|
||||||
# 7
|
# 7
|
||||||
8: [ NextValue(reg_bitblt_src_x, bus.dat_w) ],
|
8: [ NextValue(reg_bitblt_src_x, bus_dat_w_endian) ],
|
||||||
9: [ NextValue(reg_bitblt_src_y, bus.dat_w) ],
|
9: [ NextValue(reg_bitblt_src_y, bus_dat_w_endian) ],
|
||||||
10: [ NextValue(reg_bitblt_dst_x, bus.dat_w) ],
|
10: [ NextValue(reg_bitblt_dst_x, bus_dat_w_endian) ],
|
||||||
11: [ NextValue(reg_bitblt_dst_y, bus.dat_w) ],
|
11: [ NextValue(reg_bitblt_dst_y, bus_dat_w_endian) ],
|
||||||
12: [ NextValue(reg_chk_adr, bus.dat_w) ],
|
12: [ NextValue(reg_chk_adr, bus_dat_w_endian) ],
|
||||||
13: [ NextValue(reg_chk_val, bus.dat_w) ],
|
13: [ NextValue(reg_chk_val, bus_dat_w_endian) ],
|
||||||
}),
|
}),
|
||||||
NextValue(bus.ack, 1),
|
NextValue(bus.ack, 1),
|
||||||
).Elif(bus.cyc & bus.stb & ~bus.we & ~bus.ack, #read
|
).Elif(bus.cyc & bus.stb & ~bus.we & ~bus.ack, #read
|
||||||
Case(bus.adr[0:10], {
|
Case(bus.adr[0:9], { # bit 9 is used for endianess, so not there
|
||||||
"default": [ NextValue(bus.dat_r, 0xDEADBEEF) ],
|
"default": [ NextValue(bus_dat_r_endian, 0xDEADBEEF) ],
|
||||||
0: [ NextValue(bus.dat_r, reg_status) ],
|
0: [ NextValue(bus_dat_r_endian, reg_status) ],
|
||||||
1: [ NextValue(bus.dat_r, reg_cmd) ],
|
1: [ NextValue(bus_dat_r_endian, reg_cmd) ],
|
||||||
2: [ NextValue(bus.dat_r, reg_r5_cmd) ],
|
2: [ NextValue(bus_dat_r_endian, reg_r5_cmd) ],
|
||||||
# 3
|
# 3
|
||||||
4: [ NextValue(bus.dat_r, reg_width) ],
|
4: [ NextValue(bus_dat_r_endian, reg_width) ],
|
||||||
5: [ NextValue(bus.dat_r, reg_height) ],
|
5: [ NextValue(bus_dat_r_endian, reg_height) ],
|
||||||
6: [ NextValue(bus.dat_r, reg_fgcolor) ],
|
6: [ NextValue(bus_dat_r_endian, reg_fgcolor) ],
|
||||||
# 7
|
# 7
|
||||||
8: [ NextValue(bus.dat_r, reg_bitblt_src_x) ],
|
8: [ NextValue(bus_dat_r_endian, reg_bitblt_src_x) ],
|
||||||
9: [ NextValue(bus.dat_r, reg_bitblt_src_y) ],
|
9: [ NextValue(bus_dat_r_endian, reg_bitblt_src_y) ],
|
||||||
10: [ NextValue(bus.dat_r, reg_bitblt_dst_x) ],
|
10: [ NextValue(bus_dat_r_endian, reg_bitblt_dst_x) ],
|
||||||
11: [ NextValue(bus.dat_r, reg_bitblt_dst_y) ],
|
11: [ NextValue(bus_dat_r_endian, reg_bitblt_dst_y) ],
|
||||||
12: [ NextValue(bus.dat_r, reg_chk_adr) ],
|
12: [ NextValue(bus_dat_r_endian, reg_chk_adr) ],
|
||||||
13: [ NextValue(bus.dat_r, reg_chk_val) ],
|
13: [ NextValue(bus_dat_r_endian, reg_chk_val) ],
|
||||||
}),
|
}),
|
||||||
NextValue(bus.ack, 1),
|
NextValue(bus.ack, 1),
|
||||||
).Else(
|
).Else(
|
||||||
|
|
Loading…
Reference in New Issue
Block a user