diff --git a/NetBSD/9.0/usr/src/sys/dev/sbus/goblin.c b/NetBSD/9.0/usr/src/sys/dev/sbus/goblin.c index 124188e..cb8d07f 100644 --- a/NetBSD/9.0/usr/src/sys/dev/sbus/goblin.c +++ b/NetBSD/9.0/usr/src/sys/dev/sbus/goblin.c @@ -71,13 +71,16 @@ static void goblinloadcmap(struct goblin_softc *, int, int); static void goblin_set_video(struct goblin_softc *, int); static int goblin_get_video(struct goblin_softc *); +static void jareth_copyrows(void *, int, int, int); + dev_type_open(goblinopen); +dev_type_close(goblinclose); dev_type_ioctl(goblinioctl); dev_type_mmap(goblinmmap); const struct cdevsw goblin_cdevsw = { .d_open = goblinopen, - .d_close = nullclose, + .d_close = goblinclose, .d_read = noread, .d_write = nowrite, .d_ioctl = goblinioctl, @@ -107,12 +110,39 @@ struct wsscreen_descr goblin_defaultscreen = { NULL /* modecookie */ }; +struct scrolltest { + int y0; + int y1; + int x0; + int w; + int n; +}; +#define GOBLIN_SCROLL _IOW('X', 0, struct scrolltest) +#define GOBLIN_FILL _IOW('X', 1, struct scrolltest) + static int goblin_ioctl(void *, void *, u_long, void *, int, struct lwp *); static paddr_t goblin_mmap(void *, void *, off_t, int); static void goblin_init_screen(void *, struct vcons_screen *, int, long *); -int goblin_putcmap(struct goblin_softc *, struct wsdisplay_cmap *); -int goblin_getcmap(struct goblin_softc *, struct wsdisplay_cmap *); +static int goblin_putcmap(struct goblin_softc *, struct wsdisplay_cmap *); +static int goblin_getcmap(struct goblin_softc *, struct wsdisplay_cmap *); +static void goblin_init(struct goblin_softc *); +static void goblin_reset(struct goblin_softc *); + +/* Jareth stuff */ +static int init_programs(struct goblin_softc *sc); +static int power_on(struct goblin_softc *sc); +static int power_off(struct goblin_softc *sc); +static int scroll(struct goblin_softc *sc, int y0, int y1, int x0, int w, int n); +static int fill(struct goblin_softc *sc, int y0, int pat, int x0, int w, int n); +static const uint32_t program_scroll128[12] = { 0x407c0012,0x00140080,0x201c0013,0x60fc7013,0x00170146,0xfe000148,0x000e10c6,0x010000c9,0x00004005,0xfb000809,0x0000000a,0x0000000a }; +static const uint32_t program_fill128[12] = { 0x407c0012,0x00140080,0x607c1013,0x00170146,0xfe800148,0x000e10c6,0x010000c9,0x00004005,0xfb800809,0x0000000a,0x0000000a,0x0000000a }; + +static const uint32_t* programs[3] = { program_scroll128, program_fill128, NULL }; +static const uint32_t program_len[3] = { 12, 12, 0 }; +static uint32_t program_offset[3]; + +static void goblin_set_depth(struct goblin_softc *, int); struct wsdisplay_accessops goblin_accessops = { goblin_ioctl, @@ -148,9 +178,23 @@ goblinattach(struct goblin_softc *sc, const char *name, int isconsole) unsigned long defattr; volatile struct goblin_fbcontrol *fbc = sc->sc_fbc; + /* boot Jareth if present */ + if (sc->sc_has_jareth) { + /* first we need to turn the engine power on ... */ + power_on(sc); + if (init_programs(sc)) { + if (init_programs(sc)) { + aprint_normal_dev(sc->sc_dev, "INIT - FAILED\n"); + sc->sc_has_jareth = 0; + } + } + power_off(sc); + } + fb->fb_driver = &goblinfbdriver; + fb->fb_pfour = NULL; fb->fb_type.fb_cmsize = 256; - fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes; + fb->fb_type.fb_size = sc->sc_size; //fb->fb_type.fb_height * fb->fb_linebytes; printf(": %s, %d x %d", name, fb->fb_type.fb_width, fb->fb_type.fb_height); @@ -158,7 +202,6 @@ goblinattach(struct goblin_softc *sc, const char *name, int isconsole) fbc->vbl_mask = GOBOFB_VBL_MASK_OFF; /* Enable display in a supported mode */ - fbc->videoctrl = GOBOFB_VIDEOCTRL_OFF; fbc->mode = GOBOFB_MODE_8BIT; fbc->videoctrl = GOBOFB_VIDEOCTRL_ON; @@ -173,25 +216,31 @@ goblinattach(struct goblin_softc *sc, const char *name, int isconsole) sc->sc_stride = fb->fb_type.fb_width; sc->sc_height = fb->fb_type.fb_height; + wsfont_init(); + /* setup rasops and so on for wsdisplay */ sc->sc_mode = WSDISPLAYIO_MODE_EMUL; + sc->sc_opens = 0; - vcons_init(&sc->vd, sc, &goblin_defaultscreen, &goblin_accessops); - sc->vd.init_screen = goblin_init_screen; - + vcons_init(&sc->sc_vd, sc, &goblin_defaultscreen, &goblin_accessops); + sc->sc_vd.init_screen = goblin_init_screen; + if(isconsole) { /* we mess with gobo_console_screen only once */ - vcons_init_screen(&sc->vd, &gobo_console_screen, 1, - &defattr); + goblin_set_depth(sc, 8); + vcons_init_screen(&sc->sc_vd, &gobo_console_screen, 1, + &defattr); + /* clear the screen */ memset(sc->sc_fb.fb_pixels, (defattr >> 16) & 0xff, - sc->sc_stride * sc->sc_height); + sc->sc_stride * sc->sc_height); gobo_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; - + goblin_defaultscreen.textops = &ri->ri_ops; goblin_defaultscreen.capabilities = ri->ri_caps; goblin_defaultscreen.nrows = ri->ri_rows; goblin_defaultscreen.ncols = ri->ri_cols; - sc->vd.active = &gobo_console_screen; + sc->sc_vd.active = &gobo_console_screen; + wsdisplay_cnattach(&goblin_defaultscreen, ri, 0, 0, defattr); vcons_replay_msgbuf(&gobo_console_screen); } else { @@ -199,15 +248,17 @@ goblinattach(struct goblin_softc *sc, const char *name, int isconsole) * we're not the console so we just clear the screen and don't * set up any sort of text display */ + memset(sc->sc_fb.fb_pixels, (defattr >> 16) & 0xff, + sc->sc_stride * sc->sc_height); } - + /* Initialize the default color map. */ gobo_setup_palette(sc); aa.scrdata = &goblin_screenlist; aa.console = isconsole; aa.accessops = &goblin_accessops; - aa.accesscookie = &sc->vd; + aa.accesscookie = &sc->sc_vd; config_found(sc->sc_dev, &aa, wsemuldisplaydevprint); } @@ -215,10 +266,38 @@ goblinattach(struct goblin_softc *sc, const char *name, int isconsole) int goblinopen(dev_t dev, int flags, int mode, struct lwp *l) { - int unit = minor(dev); - - if (device_lookup(&goblin_cd, unit) == NULL) + struct goblin_softc *sc = device_lookup_private(&goblin_cd, + minor(dev)); + int oldopens; + + if (sc == NULL) return (ENXIO); + + oldopens = sc->sc_opens++; + + if (oldopens == 0) /* first open only */ + goblin_init(sc); + + return (0); +} + +int +goblinclose(dev_t dev, int flags, int mode, struct lwp *l) +{ + struct goblin_softc *sc = device_lookup_private(&goblin_cd, + minor(dev)); + int opens; + + opens = --sc->sc_opens; + if (sc->sc_opens < 0) /* should not happen... */ + opens = sc->sc_opens = 0; + + /* + * Restore video state to make the PROM happy, on last close. + */ + if (opens == 0) { + goblin_reset(sc); + } return (0); } @@ -270,6 +349,28 @@ goblinioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) goblin_set_video(sc, *(int *)data); break; + case GOBLIN_SET_PIXELMODE: { + int depth = *(int *)data; + + if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) + return EINVAL; + + goblin_set_depth(sc, depth); + } + break; + + case GOBLIN_SCROLL: { + struct scrolltest *st = (struct scrolltest *)data; + scroll(sc, st->y0, st->y1, st->x0, st->w, st->n); + } + break; + + case GOBLIN_FILL: { + struct scrolltest *st = (struct scrolltest *)data; + fill(sc, st->y0, st->y1, st->x0, st->w, st->n); + } + break; + default: return (ENOTTY); } @@ -284,6 +385,13 @@ goblinunblank(device_t self) { struct goblin_softc *sc = device_private(self); +#if NWSDISPLAY > 0 + if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) { + goblin_set_depth(sc, 8); + vcons_redraw_screen(sc->sc_vd.active); + sc->sc_mode = WSDISPLAYIO_MODE_EMUL; + } +#endif goblin_set_video(sc, 1); } @@ -425,7 +533,7 @@ goblin_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct vcons_data *vd = v; struct goblin_softc *sc = vd->cookie; struct wsdisplay_fbinfo *wdf; - struct vcons_screen *ms = sc->vd.active; + struct vcons_screen *ms = sc->sc_vd.active; struct rasops_info *ri = &ms->scr_ri; switch (cmd) { case WSDISPLAYIO_GTYPE: @@ -486,7 +594,7 @@ goblin_mmap(void *v, void *vs, off_t offset, int prot) prot, BUS_SPACE_MAP_LINEAR); } -int +static int goblin_putcmap(struct goblin_softc *sc, struct wsdisplay_cmap *cm) { u_int index = cm->index; @@ -516,7 +624,7 @@ goblin_putcmap(struct goblin_softc *sc, struct wsdisplay_cmap *cm) return 0; } -int +static int goblin_getcmap(struct goblin_softc *sc, struct wsdisplay_cmap *cm) { u_int index = cm->index; @@ -552,7 +660,7 @@ goblin_init_screen(void *cookie, struct vcons_screen *scr, struct goblin_softc *sc = cookie; struct rasops_info *ri = &scr->scr_ri; - scr->scr_flags |= VCONS_DONT_READ; + scr->scr_flags |= VCONS_NO_COPYCOLS; ri->ri_depth = 8; ri->ri_width = sc->sc_width; @@ -568,4 +676,310 @@ goblin_init_screen(void *cookie, struct vcons_screen *scr, sc->sc_width / ri->ri_font->fontwidth); ri->ri_hw = scr; + if (sc->sc_has_jareth) { + ri->ri_ops.copyrows = jareth_copyrows; + device_printf(sc->sc_dev, "Jareth enabled\n"); + } +} + +static void +goblin_set_depth(struct goblin_softc *sc, int depth) +{ + if (sc->sc_depth == depth) + return; + + switch (depth) { + case 8: + sc->sc_fbc->mode = GOBOFB_MODE_8BIT; + sc->sc_depth = 8; + break; + case 32: + sc->sc_fbc->mode = GOBOFB_MODE_24BIT; + sc->sc_depth = 32; + break; + default: + printf("%s: can't change to depth %d\n", + device_xname(sc->sc_dev), depth); + } +} + +/* Initialize the framebuffer, storing away useful state for later reset */ +static void +goblin_init(struct goblin_softc *sc) +{ + //goblin_set_depth(sc, 32); +} + +static void +/* Restore the state saved on goblin_init */ +goblin_reset(struct goblin_softc *sc) +{ + //goblin_set_depth(sc, 8); +} + + +#define CONFIG_CSR_DATA_WIDTH 32 +#define sbusfpga_jareth_softc goblin_softc +#include "dev/sbus/sbusfpga_csr_jareth.h" +#undef sbusfpga_jareth_softc + +#define REG_BASE(reg) (base + (reg * 32)) +#define SUBREG_ADDR(reg, off) (REG_BASE(reg) + (off)*4) + +static int start_job(struct goblin_softc *sc); +static int wait_job(struct goblin_softc *sc, uint32_t param); + +static int scroll(struct goblin_softc *sc, int y0, int y1, int x0, int w, int n) { + const uint32_t base = 0; + const int pidx = 0; + int i; + + power_on(sc); + + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(0,0), (0x8f800000 + y0 * sc->sc_stride + x0)); + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(0,1), (0x8f800000 + y1 * sc->sc_stride + x0)); + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(2,0), (w)); + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(3,0), (n)); + for (i = 1 ; i < 8 ; i++) { + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(2,i), 0); + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(3,i), 0); + } + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(4,0), (sc->sc_stride)); + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(4,1), (sc->sc_stride)); + jareth_mpstart_write(sc, program_offset[pidx]); + jareth_mplen_write(sc, program_len[pidx]); + + (void)start_job(sc); + delay(1); + (void)wait_job(sc, 2); + + power_off(sc); + + return 0; +} + + +static int fill(struct goblin_softc *sc, int y0, int pat, int x0, int w, int n) { + const uint32_t base = 0; + const int pidx = 1; + int i; + + power_on(sc); + + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(0,0), (0x8f800000 + y0 * sc->sc_stride + x0)); + for (i = 0 ; i < 8 ; i++) { + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(1,i), pat); + } + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(2,0), (w)); + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(3,0), (n)); + for (i = 1 ; i < 8 ; i++) { + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(2,i), 0); + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(3,i), 0); + } + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(4,0), (sc->sc_stride)); + jareth_mpstart_write(sc, program_offset[pidx]); + jareth_mplen_write(sc, program_len[pidx]); + + (void)start_job(sc); + delay(1); + (void)wait_job(sc, 1); + + power_off(sc); + + return 0; +} + +static void +jareth_copyrows(void *cookie, int src, int dst, int n) +{ + struct rasops_info *ri = cookie; + struct vcons_screen *scr = ri->ri_hw; + struct goblin_softc *sc = scr->scr_cookie; + + if (dst == src) + return; + if (src < 0) { + n += src; + src = 0; + } + if (src+n > ri->ri_rows) + n = ri->ri_rows - src; + if (dst < 0) { + n += dst; + dst = 0; + } + if (dst+n > ri->ri_rows) + n = ri->ri_rows - dst; + if (n <= 0) + return; + + n *= ri->ri_font->fontheight; + src *= ri->ri_font->fontheight; + dst *= ri->ri_font->fontheight; + + + int x0 = ri->ri_xorigin; + int y0 = ri->ri_yorigin + src; + //int x1 = ri->ri_xorigin + ri->ri_emuwidth - 1; + /* int y1 = ri->ri_yorigin + src + n - 1; */ + /* int x2 = ri->ri_xorigin; */ + int y2 = ri->ri_yorigin + dst; + /* int x3 = ri->ri_xorigin + ri->ri_emuwidth - 1; */ + /* int y3 = ri->ri_yorigin + dst + n - 1; */ + + scroll(sc, y0, y2, x0, ri->ri_emuwidth, n); + +#if 0 + if (y0 > y2) { + int x, y; + for (y = 0 ; y < n ; y++) { + for (x = x0 & ~3 ; x < x1 ; x+= 4) { + uint32_t* srcadr = (uint32_t*)(((uint8_t*)sc->sc_fb.fb_pixels) + (y0 + y) * sc->sc_stride + x); + uint32_t* dstadr = (uint32_t*)(((uint8_t*)sc->sc_fb.fb_pixels) + (y2 + y) * sc->sc_stride + x); + *dstadr = *srcadr; + } + } + } else { + int x, y; + for (y = n-1 ; y >= 0 ; y--) { + for (x = x0 & ~3; x < x1 ; x+= 4) { + uint32_t* srcadr = (uint32_t*)(((uint8_t*)sc->sc_fb.fb_pixels) + (y0 + y) * sc->sc_stride + x); + uint32_t* dstadr = (uint32_t*)(((uint8_t*)sc->sc_fb.fb_pixels) + (y2 + y) * sc->sc_stride + x); + *dstadr = *srcadr; + } + } + } +#endif +} + +static int start_job(struct goblin_softc *sc) { + uint32_t status = jareth_status_read(sc); + if (status & (1<sc_dev, "START - Jareth status: 0x%08x, still running?\n", status); + return ENXIO; + } + jareth_control_write(sc, 1); + //aprint_normal_dev(sc->sc_dev, "START - Jareth status: 0x%08x\n", jareth_status_read(sc)); + + return 0; +} + +static int wait_job(struct goblin_softc *sc, uint32_t param) { + uint32_t status = jareth_status_read(sc); + int count = 0; + int max_count = 2000; + int del = 1; + const int max_del = 64; + static int max_del_seen = 1; + static int max_cnt_seen = 0; + + while ((status & (1<sc_dev, "WAIT - ongoing, Jareth status: 0x%08x [%d] ls_status: 0x%08x\n", status, count, ls_status); + count ++; + delay(del * param); + del = del < max_del ? 2*del : del; + status = jareth_status_read(sc); + } + if (del > max_del_seen) { + max_del_seen = del; + aprint_normal_dev(sc->sc_dev, "WAIT - new max delay %d after %d count (param was %u)\n", max_del_seen, count, param); + } + if (count > max_cnt_seen) { + max_cnt_seen = count; + aprint_normal_dev(sc->sc_dev, "WAIT - new max count %d with %d delay (param was %u)\n", max_cnt_seen, del, param); + + } + + //jareth_control_write(sc, 0); + if (status & (1<sc_dev, "WAIT - Jareth status: 0x%08x (pc 0x%08x), did not finish in time? [inst: 0x%08x ls_status: 0x%08x]\n", status, (status>>1)&0x03ff, jareth_instruction_read(sc), jareth_ls_status_read(sc)); + return ENXIO; + } else if (status & (1<sc_dev, "WAIT - Jareth status: 0x%08x, sigill [inst: 0x%08x ls_status: 0x%08x]\n", status, jareth_instruction_read(sc), jareth_ls_status_read(sc)); + return ENXIO; + } else if (status & (1<sc_dev, "WAIT - Jareth status: 0x%08x, aborted [inst: 0x%08x ls_status: 0x%08x]\n", status, jareth_instruction_read(sc), jareth_ls_status_read(sc)); + return ENXIO; + } else { + //aprint_normal_dev(sc->sc_dev, "WAIT - Jareth status: 0x%08x [%d] ls_status: 0x%08x\n", status, count, jareth_ls_status_read(sc)); + } + + return 0; +} + +static int init_programs(struct goblin_softc *sc) { + /* the microcode is a the beginning */ + int err = 0; + uint32_t i, j; + uint32_t offset = 0; + + for (j = 0 ; programs[j] != NULL; j ++) { + program_offset[j] = offset; + for (i = 0 ; i < program_len[j] ; i++) { + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_microcode, ((offset+i)*4), programs[j][i]); + if ((i%16)==15) + delay(1); + } + offset += program_len[j]; + } + + jareth_window_write(sc, 0); /* could use window_window to access fields, but it creates a RMW cycle for nothing */ + jareth_mpstart_write(sc, 0); /* EC25519 */ + jareth_mplen_write(sc, program_len[0]); /* EC25519 */ + + aprint_normal_dev(sc->sc_dev, "INIT - Jareth status: 0x%08x\n", jareth_status_read(sc)); + +#if 1 + /* double check */ + u_int32_t x; + int count = 0; + for (i = 0 ; i < program_len[0] && count < 10; i++) { + x = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_microcode, (i*4)); + if (x != programs[0][i]) { + aprint_error_dev(sc->sc_dev, "INIT - Jareth program failure: [%d] 0x%08x <> 0x%08x\n", i, x, programs[0][i]); + err = 1; + count ++; + } + if ((i%8)==7) + delay(1); + } + if ((x = jareth_window_read(sc)) != 0) { + aprint_error_dev(sc->sc_dev, "INIT - Jareth register failure: window = 0x%08x\n", x); + err = 1; + } + if ((x = jareth_mpstart_read(sc)) != 0) { + aprint_error_dev(sc->sc_dev, "INIT - Jareth register failure: mpstart = 0x%08x\n", x); + err = 1; + } + if ((x = jareth_mplen_read(sc)) != program_len[0]) { + aprint_error_dev(sc->sc_dev, "INIT - Jareth register failure: mplen = 0x%08x\n", x); + err = 1; + } + const int test_reg_num = 73; + const uint32_t test_reg_value = 0x0C0FFEE0; + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile, 4*test_reg_num, test_reg_value); + delay(1); + if ((x = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile, 4*test_reg_num)) != test_reg_value) { + aprint_error_dev(sc->sc_dev, "INIT - Jareth register file failure: 0x%08x != 0x%08x\n", x, test_reg_value); + err = 1; + } +#endif + + return err; +} + +static int power_on(struct goblin_softc *sc) { + int err = 0; + if ((jareth_power_read(sc) & 1) == 0) { + jareth_power_write(sc, 1); + delay(1); + } + return err; +} + +static int power_off(struct goblin_softc *sc) { + int err = 0; + jareth_power_write(sc, 0); + return err; } diff --git a/NetBSD/9.0/usr/src/sys/dev/sbus/goblin_sbus.c b/NetBSD/9.0/usr/src/sys/dev/sbus/goblin_sbus.c index 01a8672..c8ff3ff 100644 --- a/NetBSD/9.0/usr/src/sys/dev/sbus/goblin_sbus.c +++ b/NetBSD/9.0/usr/src/sys/dev/sbus/goblin_sbus.c @@ -155,5 +155,53 @@ goblinattach_sbus(device_t parent, device_t self, void *args) fb->fb_pixels = (char *)bus_space_vaddr(sa->sa_bustag, bh); } + sc->sc_has_jareth = prom_getpropint(node, "goblin_has_jareth", 0); + + if (sc->sc_has_jareth) { + if (sa->sa_nreg < 5) { + aprint_error(": Not enough registers spaces for Jareth\n"); + sc->sc_has_jareth = 0; + } else { + /* map registers */ + if (sbus_bus_map(sc->sc_bustag, + sa->sa_reg[2].oa_space /* sa_slot */, + sa->sa_reg[2].oa_base /* sa_offset */, + sa->sa_reg[2].oa_size /* sa_size */, + BUS_SPACE_MAP_LINEAR, + &sc->sc_bhregs_jareth) != 0) { + aprint_error(": cannot map Jareth registers\n"); + sc->sc_has_jareth = 0; + } else { + aprint_normal_dev(self, "Jareth registers @ %p\n", (void*)sc->sc_bhregs_jareth); + /* map microcode */ + if (sbus_bus_map(sc->sc_bustag, + sa->sa_reg[3].oa_space /* sa_slot */, + sa->sa_reg[3].oa_base /* sa_offset */, + sa->sa_reg[3].oa_size /* sa_size */, + BUS_SPACE_MAP_LINEAR, + &sc->sc_bhregs_microcode) != 0) { + aprint_error(": cannot map Jareth microcode\n"); + sc->sc_has_jareth = 0; + } else { + aprint_normal_dev(self, "Jareth microcode @ %p\n", (void*)sc->sc_bhregs_microcode); + /* map register file */ + if (sbus_bus_map(sc->sc_bustag, + sa->sa_reg[4].oa_space /* sa_slot */, + sa->sa_reg[4].oa_base /* sa_offset */, + sa->sa_reg[4].oa_size /* sa_size */, + BUS_SPACE_MAP_LINEAR, + &sc->sc_bhregs_regfile) != 0) { + aprint_error(": cannot map Jareth regfile\n"); + sc->sc_has_jareth = 0; + } else { + aprint_normal_dev(self, "Jareth regfile @ %p\n", (void*)sc->sc_bhregs_regfile); + } + } + } + } + } else { + aprint_normal_dev(self, "Jareth not available\n"); + } + goblinattach(sc, name, isconsole); } diff --git a/NetBSD/9.0/usr/src/sys/dev/sbus/goblinreg.h b/NetBSD/9.0/usr/src/sys/dev/sbus/goblinreg.h index b145bb4..6c2df48 100644 --- a/NetBSD/9.0/usr/src/sys/dev/sbus/goblinreg.h +++ b/NetBSD/9.0/usr/src/sys/dev/sbus/goblinreg.h @@ -48,9 +48,9 @@ #define GOBOFB_MODE_24BIT 0x10 #define GOBOFB_VBL_MASK_OFF 0x0 -#define GOBOFB_VBL_MASK_ON 0x1 +#define GOBOFB_VBL_MASK_ON 0x1 #define GOBOFB_VIDEOCTRL_OFF 0x0 -#define GOBOFB_VIDEOCTRL_ON 0x3 +#define GOBOFB_VIDEOCTRL_ON 0x1 #define GOBOFB_INTR_CLEAR_CLEAR 0x0 diff --git a/NetBSD/9.0/usr/src/sys/dev/sbus/goblinvar.h b/NetBSD/9.0/usr/src/sys/dev/sbus/goblinvar.h index eed3875..7c24397 100644 --- a/NetBSD/9.0/usr/src/sys/dev/sbus/goblinvar.h +++ b/NetBSD/9.0/usr/src/sys/dev/sbus/goblinvar.h @@ -51,6 +51,12 @@ struct goblin_softc { bus_addr_t sc_reg_fbc_paddr; /* phys address for device mmap() */ bus_addr_t sc_fb_paddr; /* phys address for device mmap() */ uint32_t sc_size; /* full memory size */ + int sc_opens; /* number of open() to track 8/24 bits */ + int sc_has_jareth; /* whether we have a Jareth vector engine available */ + + bus_space_handle_t sc_bhregs_jareth; /* bus handle */ + bus_space_handle_t sc_bhregs_microcode; /* bus handle */ + bus_space_handle_t sc_bhregs_regfile; /* bus handle */ volatile struct goblin_fbcontrol *sc_fbc; /* control registers */ #if NWSDISPLAY > 0 @@ -58,9 +64,12 @@ struct goblin_softc { uint32_t sc_height; /* display width / height */ uint32_t sc_stride; int sc_mode; - struct vcons_data vd; + struct vcons_data sc_vd; + int sc_depth; #endif union bt_cmap sc_cmap; /* DAC color map */ }; +#define GOBLIN_SET_PIXELMODE _IOW('M', 3, int) + void goblinattach(struct goblin_softc *, const char *, int); diff --git a/NetBSD/9.0/usr/xsrc/external/mit/xf86-video-goblin/dist/src/goblin_driver.c b/NetBSD/9.0/usr/xsrc/external/mit/xf86-video-goblin/dist/src/goblin_driver.c index 1f8266f..9d2ed6a 100644 --- a/NetBSD/9.0/usr/xsrc/external/mit/xf86-video-goblin/dist/src/goblin_driver.c +++ b/NetBSD/9.0/usr/xsrc/external/mit/xf86-video-goblin/dist/src/goblin_driver.c @@ -673,9 +673,26 @@ GOBLINValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) static Bool GOBLINSaveScreen(ScreenPtr pScreen, int mode) { -/* ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; */ -/* GoblinPtr pGoblin = GET_GOBLIN_FROM_SCRN(pScrn); */ -/* xf86Msg(X_INFO, "%s: %s\n", pGoblin->psdp->device, __PRETTY_FUNCTION__); */ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GoblinPtr pGoblin = GET_GOBLIN_FROM_SCRN(pScrn); + /* xf86Msg(X_INFO, "%s: %s\n", pGoblin->psdp->device, __PRETTY_FUNCTION__); */ + + switch(mode) + { + case SCREEN_SAVER_ON: + case SCREEN_SAVER_CYCLE: + if (pGoblin->fbc->videoctrl != GOBOFB_VIDEOCTRL_OFF) + pGoblin->fbc->videoctrl = GOBOFB_VIDEOCTRL_OFF; + break; + case SCREEN_SAVER_OFF: + case SCREEN_SAVER_FORCER: + if (pGoblin->fbc->videoctrl != GOBOFB_VIDEOCTRL_ON) + pGoblin->fbc->videoctrl = GOBOFB_VIDEOCTRL_ON; + break; + default: + return FALSE; + } + return TRUE; } diff --git a/NetBSD/9.0/usr/xsrc/external/mit/xf86-video-goblin/dist/src/goblin_regs.h b/NetBSD/9.0/usr/xsrc/external/mit/xf86-video-goblin/dist/src/goblin_regs.h index 540ca68..943a93b 100644 --- a/NetBSD/9.0/usr/xsrc/external/mit/xf86-video-goblin/dist/src/goblin_regs.h +++ b/NetBSD/9.0/usr/xsrc/external/mit/xf86-video-goblin/dist/src/goblin_regs.h @@ -45,11 +45,10 @@ #define GOBOFB_VBL_MASK_ON 0x1 #define GOBOFB_VIDEOCTRL_OFF 0x0 -#define GOBOFB_VIDEOCTRL_ON 0x3 +#define GOBOFB_VIDEOCTRL_ON 0x1 #define GOBOFB_INTR_CLEAR_CLEAR 0x0 - typedef struct goblin_fbc { uint32_t mode; uint32_t vbl_mask; diff --git a/sbus-to-ztex-gateware-migen/goblin.fth b/sbus-to-ztex-gateware-migen/goblin.fth index 30125b9..9c7419d 100644 --- a/sbus-to-ztex-gateware-migen/goblin.fth +++ b/sbus-to-ztex-gateware-migen/goblin.fth @@ -23,7 +23,12 @@ h# SBUSFPGA_CG3_BUFSIZE constant /goblin-off-fb : goblin-reg my-address sbusfpga_regionaddr_goblin_bt + my-space encode-phys /goblin-off-dac encode-int encode+ my-address goblin-off-fb + my-space encode-phys encode+ /goblin-off-fb encode-int encode+ -" reg" property + h# 1 goblin_has_jareth = if + my-address sbusfpga_csraddr_jareth + my-space encode-phys encode+ h# 1000 encode-int encode+ + my-address sbusfpga_regionaddr_jareth-microcode + my-space encode-phys encode+ h# 1000 encode-int encode+ + my-address sbusfpga_regionaddr_jareth-regfile + my-space encode-phys encode+ h# 1000 encode-int encode+ + then + " reg" property ; : do-map-in ( offset size -- virt ) @@ -80,11 +85,11 @@ headerless ; : map-regs - dac-map fb-map + dac-map ; : unmap-regs - dac-unmap fb-unmap + dac-unmap ; \ @@ -95,7 +100,7 @@ headerless " display" device-type " RDOL,sbusfpga" model -: qemu-goblin-driver-install ( -- ) +: goblin-driver-install ( -- ) goblin-dac -1 = if map-regs @@ -104,30 +109,31 @@ headerless \ Initial palette taken from Sun's "Writing FCode Programs" h# ff h# ff h# ff h# 0 color! \ Background white h# 0 h# 0 h# 0 h# ff color! \ Foreground black - h# 64 h# 41 h# b4 h# 1 color! \ SUN-blue logo + \ h# 64 h# 41 h# b4 h# 1 color! \ SUN-blue logo + h# b4 h# 41 h# 64 h# 1 color! \ SUN-blue logo fb-addr to frame-buffer-adr default-font set-font frame-buffer-adr encode-int " address" property \ CHECKME - h# 3 h# 8 dac! \ enable DMA, VTG + h# 1 h# 8 dac! \ enable openbios-video-width openbios-video-height over char-width / over char-height / fb8-install then ; -: qemu-goblin-driver-remove ( -- ) +: goblin-driver-remove ( -- ) goblin-dac -1 <> if unmap-regs fb-unmap -1 to frame-buffer-adr - " address" delete-attribute + " address" delete-property then ; -: qemu-goblin-driver-init +: goblin-driver-init goblin-reg @@ -142,13 +148,15 @@ headerless " ISO8859-1" encode-string " character-set" property h# c encode-int " cursorshift" property /goblin-off-fb h# 14 >> encode-int " vmsize" property + goblin_has_jareth encode-int " goblin_has_jareth" property map-regs - 0 h# 4 dac! \ disable irq + h# 0 h# 4 dac! \ disable irq + h# 0 h# 8 dac! \ turn off videoctrl unmap-regs - ['] qemu-goblin-driver-install is-install - ['] qemu-goblin-driver-remove is-remove + ['] goblin-driver-install is-install + ['] goblin-driver-remove is-remove ; -qemu-goblin-driver-init +goblin-driver-init diff --git a/sbus-to-ztex-gateware-migen/jareth.py b/sbus-to-ztex-gateware-migen/jareth.py index 3105410..96d269f 100644 --- a/sbus-to-ztex-gateware-migen/jareth.py +++ b/sbus-to-ztex-gateware-migen/jareth.py @@ -17,10 +17,12 @@ opcodes = { # mnemonic : [bit coding, docstring] ; if bit 6 (0x20) is set, shif # 2 MSK "XOR" : [3, "Wd $\gets$ Ra ^ Rb // bitwise XOR"], "NOT" : [4, "Wd $\gets$ ~Ra // binary invert"], - "ADD" : [5, "Wd $\gets$ Ra + Rb // 256-bit binary add"], - "SUB" : [6, "Wd $\gets$ Ra - Rb // 256-bit binary subtraction"], + "ADD32" : [5, "Wd[x..x+32] $\gets$ Ra[x..x+32] + Rb[x..x+32] // vector 32-bit binary add"], + "SUB32" : [6, "Wd[x..x+32] $\gets$ Ra[x..x+32] - Rb[x..x+32] // vector 32-bit binary add"], + #"ADD" : [5, "Wd $\gets$ Ra + Rb // 256-bit binary add"], + #"SUB" : [6, "Wd $\gets$ Ra - Rb // 256-bit binary subtraction"], "AND" : [7, "Wd $\gets$ Ra & Rb // bitwise AND"], # replace MUL - "BRNZ" : [8, "If Ra != 0 then mpc[9:0] $\gets$ mpc[9:0] + immediate[9:0] + 1, else mpc $\gets$ mpc + 1 // Branch if non-zero"], # relace TRD + "BRNZ" : [8, "If Ra != 0 then mpc[9:0] $\gets$ mpc[9:0] + immediate[9:0] + 1, else mpc $\gets$ mpc + 1 // Branch if non-zero"], # replace TRD "BRZ" : [9, "If Ra == 0 then mpc[9:0] $\gets$ mpc[9:0] + immediate[9:0] + 1, else mpc $\gets$ mpc + 1 // Branch if zero"], "FIN" : [10, "halt execution and assert interrupt to host CPU that microcode execution is done"], "SHL" : [11, "Wd $\gets$ Ra << 1 // shift Ra left by one and store in Wd"], @@ -231,6 +233,7 @@ class JarethConst(Module, AutoDoc): #3: [3, "three", "The number three"], #4: [4, "four", "The number four"], #5: [5, "five", "The number five"], + 5: [32, "thirty-two", "The number thirty-two"], #6: [6, "six", "The number six"], #7: [7, "seven", "The number seven"], #8: [8, "eight", "The number eight"], @@ -328,41 +331,8 @@ passthrough. class ExecAddSub(ExecUnit, AutoDoc): def __init__(self, width=256): - ExecUnit.__init__(self, width, ["ADD", "SUB"]) + ExecUnit.__init__(self, width, ["ADD32", "SUB32"]) self.notes = ModuleDoc(title="Add/Sub ExecUnit Subclass", body=f""" -This execution module implements 256-bit binary addition and subtraction. - -Note that to implement operations in $\mathbf{{F}}_p$, where *p* is $2^{{255}}-19$, this must be compounded -with other operators as follows: - -Addition of Ra + Rb into Rc in {field_latex}: - -.. code-block:: c - - ADD Rc, Ra, Rb // Rc <- Ra + Rb - TRD Rd, Rc // Rd <- ReductionValue(Rc) - SUB Rc, Rc, Rd // Rc <- Rc - Rd - -Negation of Ra into Rc in {field_latex}: - -.. code-block:: c - - SUB Rc, #FIELDPRIME, Ra // Rc <- 2^255-19 - Ra - -Note that **#FIELDPRIME** is one of the 32 available hard-coded constants -that can be substituted for any register in any arithmetic operation, please -see the section on "Constants" for more details. - -Subtraction of Ra - Rb into Rc in {field_latex}: - -.. code-block:: c - - SUB Rb, #FIELDPRIME, Rb // Rb <- 2^255-19 - Rb - ADD Rc, Ra, Rb // Rc <- Ra + Rb - TRD Rd, Rc // Rd <- ReductionValue(Rc) - SUB Rc, Rc, Rd // Rc <- Rc - Rd - -In all the examples above, Ra and Rb must be members of {field_latex}. """) self.sync.eng_clk += [ @@ -370,10 +340,10 @@ In all the examples above, Ra and Rb must be members of {field_latex}. self.instruction_out.eq(self.instruction_in), ] self.comb += [ - If(self.instruction.opcode == opcodes["ADD"][0], - self.q.eq(self.a + self.b), - ).Elif(self.instruction.opcode == opcodes["SUB"][0], - self.q.eq(self.a - self.b), + If(self.instruction.opcode == opcodes["ADD32"][0], + [ self.q[x*32:(x+1)*32].eq(self.a[x*32:(x+1)*32] + self.b[x*32:(x+1)*32]) for x in range(0, width//32) ], + ).Elif(self.instruction.opcode == opcodes["SUB32"][0], + [ self.q[x*32:(x+1)*32].eq(self.a[x*32:(x+1)*32] - self.b[x*32:(x+1)*32]) for x in range(0, width//32) ], ), ] diff --git a/sbus-to-ztex-gateware-migen/jareth_code/jareth_code.rs b/sbus-to-ztex-gateware-migen/jareth_code/jareth_code.rs index aca9d00..b0bcfab 100644 --- a/sbus-to-ztex-gateware-migen/jareth_code/jareth_code.rs +++ b/sbus-to-ztex-gateware-migen/jareth_code/jareth_code.rs @@ -25,7 +25,7 @@ fn main() -> std::io::Result<()> { // slow setmq %31, %1, #16 and %5, %2, #15 - sub %6, %2, %5 + sub32 %6, %2, %5 brz done, %6 loop: psa %18, %16 @@ -33,7 +33,7 @@ fn main() -> std::io::Result<()> { psa* %17, %16 psa %20, %17 store128inc %31, %2, %17 - sub %6, %6, #16 + sub32 %6, %6, #16 brz last, %6 loadh128inc %16, %0, %16 loadh128inc %17, %1, %17 @@ -48,50 +48,125 @@ fn main() -> std::io::Result<()> { fin fin ); - let _mcode3 = assemble_jareth!( - // 0..0 / $DST / $SRC in %0 - // size in %2 - // pattern in %3 - start: - resm %31 - psa %31, #0 - psa %30, #1 - sub %30, %31, %30 - psa %29, #2 - setmq %31, %29, %2 - setma %31, %0, %2 - psa* %30, %3 - getm %3 - resm %31 - psa %2, %30 - setadr %31 , %0 - load256 %1, %0 - load128 %0, %0 - fin - fin + + let mcode_scroll256 = assemble_jareth!( + // x..x / $DST / $SRC in %0, aligned on 128 bits ; $DST < $SRC + // x..x / X size in %2, multiple of 256 bits (32 bytes) + // x..x / Y size in %3, arbitrary + // x..x / dst_stride / src_stride in %4 (screen width) + // ----- + // live X count in %5 + // // live Y count in %3 + // data in %7 + // 0/scrap in %31 + start: + // reset masks (probably not necessary with the starred-instruction) + // resm %31 + loop_y: + // set source and destination addresses for current Y, X=first + setadr %31, %0 + psa %5, %2 + loop_x: + // load from SRC w/ post-increment + load256inc %7, %0 + // store to DST w/ post-increment + store256inc %31, %1, %7 + // sub 32 (#5 is 32...) from live X count + sub32 %5, %5, #5 + // if X count is not 0, keep looping + brnz loop_x, %5 + + // decrement Y count + sub32 %3, %3, #1 + // if 0, finished + brz done, %3 + // add strides to initial addresses + add32 %0, %0, %4 + // loop to do next line + brz loop_y, #0 + done: + fin + fin ); - let _mcode2 = assemble_jareth!( - psa %1, %3 - setma %31, %0, %2 - psa %2, %3 - getm %3 + + let mcode_scroll128 = assemble_jareth!( + // x..x / $DST / $SRC in %0, aligned on 128 bits ; $DST < $SRC + // x..x / X size in %2, multiple of 128 bits (16 bytes) + // x..x / Y size in %3, arbitrary + // x..x / dst_stride / src_stride in %4 (screen width) + // ----- + // live X count in %5 + // // live Y count in %3 + // data in %7 + // 0/scrap in %31 + start: + // reset masks (probably not necessary with the starred-instruction) + // resm %31 + loop_y: + // set source and destination addresses for current Y, X=first + setadr %31, %0 + psa %5, %2 + loop_x: + // load from SRC w/ post-increment + load128inc %7, %0 + // store to DST w/ post-increment + store128inc %31, %1, %7 + // sub 16 (#16 is 16) from live X count + sub32 %5, %5, #16 + // if X count is not 0, keep looping + brnz loop_x, %5 + + // decrement Y count + sub32 %3, %3, #1 + // if 0, finished + brz done, %3 + // add strides to initial addresses + add32 %0, %0, %4 + // loop to do next line + brz loop_y, #0 + done: fin fin - resm %31 - psa %0, %3 - setmq %31, %1, %2 - psa %1, %3 + ); + + let mcode_fill128 = assemble_jareth!( + // x..x / $DST in %0, aligned on 128 bits + // 128-bits pattern in %1 + // x..x / X size in %2, multiple of 128 bits (16 bytes) + // x..x / Y size in %3, arbitrary + // x..x / dst_stride in %4 (screen width) + // ----- + // live X count in %5 + // // live Y count in %3 + // data in %7 + // 0/scrap in %31 + start: + // reset masks (probably not necessary with the starred-instruction) + // resm %31 + loop_y: + // set source and destination addresses for current Y, X=first + setadr %31, %0 + psa %5, %2 + loop_x: + // store to DST w/ post-increment + store128inc %31, %0, %1 + // sub 16 (#16 is 16) from live X count + sub32 %5, %5, #16 + // if X count is not 0, keep looping + brnz loop_x, %5 + + // decrement Y count + sub32 %3, %3, #1 + // if 0, finished + brz done, %3 + // add strides to initial addresses + add32 %0, %0, %4 + // loop to do next line + brz loop_y, #0 + done: fin fin - fin - setma %31, %0, %2 - setma %31, %0, %2 - resm %31 - fin - fin - fin - fin - ); + ); let mut pos; @@ -104,5 +179,32 @@ fn main() -> std::io::Result<()> { println!(""); println!("-> {}", mcode.len()); + pos = 0; + println!("scroll256:"); + while pos < mcode_scroll256.len() { + print!("0x{:08x},", mcode_scroll256[pos]); + pos = pos + 1; + } + println!(""); + println!("-> {}", mcode_scroll256.len()); + + pos = 0; + println!("scroll128:"); + while pos < mcode_scroll128.len() { + print!("0x{:08x},", mcode_scroll128[pos]); + pos = pos + 1; + } + println!(""); + println!("-> {}", mcode_scroll128.len()); + + pos = 0; + println!("fill128:"); + while pos < mcode_fill128.len() { + print!("0x{:08x},", mcode_fill128[pos]); + pos = pos + 1; + } + println!(""); + println!("-> {}", mcode_fill128.len()); + Ok(()) } diff --git a/sbus-to-ztex-gateware-migen/sbus_to_fpga_prom.py b/sbus-to-ztex-gateware-migen/sbus_to_fpga_prom.py index 7fcebc9..e99be9b 100644 --- a/sbus-to-ztex-gateware-migen/sbus_to_fpga_prom.py +++ b/sbus-to-ztex-gateware-migen/sbus_to_fpga_prom.py @@ -46,13 +46,16 @@ def get_header_map2_stuff(gname, name1, name2, size1, size2, type1="csr", type2= r += ";\n" return r -def get_header_map3_stuff(gname, name1, name2, name3, size1, size2, size3, type1="csr", type2="csr", type3="csr"): - r = f"my-address sbusfpga_{type1}addr_{name1} + my-space encode-phys h# {size1:x} encode-int encode+\n" - r += f"my-address sbusfpga_{type2}addr_{name2} + my-space encode-phys encode+ h# {size2:x} encode-int encode+\n" - r += f"my-address sbusfpga_{type3}addr_{name3} + my-space encode-phys encode+ h# {size3:x} encode-int encode+\n" - r += "\" reg\" property\n" - r += "h# 7f encode-int \" slave-burst-sizes\" property\n" # fixme: burst-sizes - r += "h# 7f encode-int \" burst-sizes\" property\n" # fixme: burst-sizes +def get_header_map3_stuff(gname, name1, name2, name3, size1, size2, size3, type1="csr", type2="csr", type3="csr", doreg=True): + if (doreg): + r = f"my-address sbusfpga_{type1}addr_{name1} + my-space encode-phys h# {size1:x} encode-int encode+\n" + r += f"my-address sbusfpga_{type2}addr_{name2} + my-space encode-phys encode+ h# {size2:x} encode-int encode+\n" + r += f"my-address sbusfpga_{type3}addr_{name3} + my-space encode-phys encode+ h# {size3:x} encode-int encode+\n" + r += "\" reg\" property\n" + r += "h# 7f encode-int \" slave-burst-sizes\" property\n" # fixme: burst-sizes + r += "h# 7f encode-int \" burst-sizes\" property\n" # fixme: burst-sizes + else: + r = "" r += "headers\n" r += f"-1 instance value {name1}-virt\n" r += f"-1 instance value {name2}-virt\n" @@ -71,13 +74,16 @@ def get_header_map3_stuff(gname, name1, name2, name3, size1, size2, size3, type1 r += ";\n" return r -def get_header_mapx_stuff(gname, names, sizes, types): - r = f"my-address sbusfpga_{types[0]}addr_{names[0]} + my-space encode-phys h# {sizes[0]:x} encode-int encode+\n" - for i in range(1, len(names)): - r += f"my-address sbusfpga_{types[i]}addr_{names[i]} + my-space encode-phys encode+ h# {sizes[i]:x} encode-int encode+\n" - r += "\" reg\" property\n" - r += "h# 7f encode-int \" slave-burst-sizes\" property\n" # fixme: burst-sizes - r += "h# 7f encode-int \" burst-sizes\" property\n" # fixme: burst-sizes +def get_header_mapx_stuff(gname, names, sizes, types, doreg=True): + if (doreg): + r = f"my-address sbusfpga_{types[0]}addr_{names[0]} + my-space encode-phys h# {sizes[0]:x} encode-int encode+\n" + for i in range(1, len(names)): + r += f"my-address sbusfpga_{types[i]}addr_{names[i]} + my-space encode-phys encode+ h# {sizes[i]:x} encode-int encode+\n" + r += "\" reg\" property\n" + r += "h# 7f encode-int \" slave-burst-sizes\" property\n" # fixme: burst-sizes + r += "h# 7f encode-int \" burst-sizes\" property\n" # fixme: burst-sizes + else: + r = "" r += "headers\n" for i in range(0, len(names)): r += f"-1 instance value {names[i]}-virt\n" @@ -122,7 +128,7 @@ def get_prom(soc, r += "\" RDOL,sbusstat\" device-name\n" r += get_header_map_stuff("sbus_bus_stat", "sbus_bus_stat", 256) - if (trng or usb or (sdram or not sdram) or engine or i2c or framebuffer or sdcard or jareth): + if (trng or usb or (sdram or not sdram) or engine or i2c or framebuffer or sdcard or (jareth and not goblin)): r += "finish-device\nnew-device\n" if (trng): @@ -134,7 +140,7 @@ def get_prom(soc, r += " map-out-trng\n" r += ";\n" r += "disabletrng!\n" - if (usb or (sdram or not sdram) or engine or i2c or framebuffer or sdcard or jareth): + if (usb or (sdram or not sdram) or engine or i2c or framebuffer or sdcard or (jareth and not goblin)): r += "finish-device\nnew-device\n" if (usb): @@ -154,7 +160,7 @@ def get_prom(soc, r += " map-out-usb_host_ctrl\n" r += ";\n" r += "my-reset!\n" - if ((sdram or not sdram) or engine or i2c or framebuffer or sdcard or jareth): + if ((sdram or not sdram) or engine or i2c or framebuffer or sdcard or (jareth and not goblin)): r += "finish-device\nnew-device\n" if (sdram): @@ -179,7 +185,7 @@ def get_prom(soc, r += "\" RDOL,hidden_sdram\" device-name\n" r += get_header_mapx_stuff("mregs", [ "ddrphy", "sdram" ], [ 4096, 4096 ], [ "csr", "csr" ]) r += "fload sdram_init.fth\ninit!\n" - if (engine or i2c or framebuffer or sdcard or jareth): + if (engine or i2c or framebuffer or sdcard or (jareth and not goblin)): r += "finish-device\nnew-device\n" if (engine): @@ -187,7 +193,7 @@ def get_prom(soc, r += ": sbusfpga_regionaddr_curve25519engine-microcode sbusfpga_regionaddr_curve25519engine ;\n" r += ": sbusfpga_regionaddr_curve25519engine-regfile sbusfpga_regionaddr_curve25519engine h# 10000 + ;\n" r += get_header_mapx_stuff("curve25519engine", [ "curve25519engine", "curve25519engine-microcode", "curve25519engine-regfile" ], [ 4096, 4096, 65536 ] , ["csr", "region", "region" ] ) - if (i2c or framebuffer or sdcard or jareth): + if (i2c or framebuffer or sdcard or (jareth and not goblin)): r += "finish-device\nnew-device\n" if (i2c): @@ -202,7 +208,7 @@ def get_prom(soc, r += " \" lm75\" encode-string \" compatible\" property\n" r += " h# 48 encode-int \" addr\" property\n" r += " finish-device\n" - if (framebuffer or sdcard or jareth): + if (framebuffer or sdcard or (jareth and not goblin)): r += "finish-device\nnew-device\n" if (framebuffer): @@ -210,6 +216,23 @@ def get_prom(soc, vres = int(cg3_res.split("@")[0].split("x")[1]) hres_h=(f"{hres:x}").replace("0x", "") vres_h=(f"{vres:x}").replace("0x", "") + + if (goblin): + if (jareth): + # first add the jareth stuff so we can use it from the goblin init + r += ": sbusfpga_regionaddr_jareth-microcode sbusfpga_regionaddr_jareth ;\n" + r += ": sbusfpga_regionaddr_jareth-regfile sbusfpga_regionaddr_jareth h# 10000 + ;\n" + r += get_header_mapx_stuff("jareth", [ "jareth", "jareth-microcode", "jareth-regfile" ], [ 4096, 4096, 4096 ], ["csr", "region", "region" ], doreg=False ) + r += "h# 1 constant goblin_has_jareth\n" + r += "fload goblin_jareth_define.fth\n" + r += "fload goblin_jareth_init.fth\n" + else: + # use some placeholder so the 'reg' proeperty works + r += "h# -1 constant sbusfpga_csraddr_jareth\n" + r += "h# -1 constant sbusfpga_regionaddr_jareth-microcode\n" + r += "h# -1 constant sbusfpga_regionaddr_jareth-regfile\n" + r += "h# 0 constant goblin_has_jareth\n" + if (bw2): cg3_file = open("bw2.fth") elif (cg3): @@ -242,7 +265,7 @@ def get_prom(soc, r += "fload cg6_init.fth\ncg6_init!\n" elif (goblin): r += "\n" - if (sdcard or jareth): + if (sdcard or (jareth and not goblin)): r += "finish-device\nnew-device\n" if (sdcard): @@ -261,7 +284,7 @@ def get_prom(soc, if (jareth): r += "finish-device\nnew-device\n" - if (jareth): + if (jareth and not goblin): # if there's a goblin, jareth is part of it r += "\" jareth\" device-name\n" r += ": sbusfpga_regionaddr_jareth-microcode sbusfpga_regionaddr_jareth ;\n" r += ": sbusfpga_regionaddr_jareth-regfile sbusfpga_regionaddr_jareth h# 10000 + ;\n" diff --git a/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py b/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py index f54b6ff..6e07910 100644 --- a/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py +++ b/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py @@ -528,6 +528,10 @@ class SBusFPGA(SoCCore): elif (goblin): self.submodules.goblin = goblin_fb.goblin(soc=self, phy=self.videophy, timings=cg3_res, clock_domain="vga", irq_line=Signal()) # clock_domain for the VGA side, cg6 is running in cd_sys self.bus.add_slave("goblin_bt", self.goblin.bus, SoCRegion(origin=self.mem_map.get("cg6_bt", None), size=0x1000, cached=False)) + #pad_SBUS_DATA_OE_LED = platform.request("SBUS_DATA_OE_LED") + #SBUS_DATA_OE_LED_o = Signal() + #self.comb += pad_SBUS_DATA_OE_LED.eq(SBUS_DATA_OE_LED_o) + #self.comb += SBUS_DATA_OE_LED_o.eq(self.goblin.video_framebuffer_vtg.enable) if (cg6): self.submodules.cg6_accel = cg6_accel.CG6Accel(soc = self, base_fb = base_fb, hres = hres, vres = vres)