diff -ur qemu-omap3-orig/hw/omap3_lcd_panel_template.h qemu-omap3/hw/omap3_lcd_panel_template.h --- qemu-omap3-orig/hw/omap3_lcd_panel_template.h 2008-12-04 11:57:47.000000000 +0000 +++ qemu-omap3/hw/omap3_lcd_panel_template.h 2009-03-02 21:03:53.000000000 +0000 @@ -52,16 +52,166 @@ # define SWAP_WORDS 1 #endif +/* + * 1-bit colour + */ +static void glue(omap3_lcd_panel_draw_line1_, DEPTH)( + PIXEL_TYPE *dest, const uint8_t *src, unsigned int width, const uint32_t *pal) +{ + unsigned int v, r, g, b; + const uint8_t *end = src + (width>>3); + + while (src < end) { + v = ldub_raw((void *) (src++)); + b = pal[v&0x1] & 0xff; + g = (pal[v&0x1]>>8) & 0xff; + r = (pal[v&0x1]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>1; + b = pal[v&0x1] & 0xff; + g = (pal[v&0x1]>>8) & 0xff; + r = (pal[v&0x1]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>1; + b = pal[v&0x1] & 0xff; + g = (pal[v&0x1]>>8) & 0xff; + r = (pal[v&0x1]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>1; + b = pal[v&0x1] & 0xff; + g = (pal[v&0x1]>>8) & 0xff; + r = (pal[v&0x1]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>1; + b = pal[v&0x1] & 0xff; + g = (pal[v&0x1]>>8) & 0xff; + r = (pal[v&0x1]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>1; + b = pal[v&0x1] & 0xff; + g = (pal[v&0x1]>>8) & 0xff; + r = (pal[v&0x1]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>1; + b = pal[v&0x1] & 0xff; + g = (pal[v&0x1]>>8) & 0xff; + r = (pal[v&0x1]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>1; + b = pal[v] & 0xff; + g = (pal[v]>>8) & 0xff; + r = (pal[v]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + } +} +/* + * 2-bit colour + */ +static void glue(omap3_lcd_panel_draw_line2_, DEPTH)( + PIXEL_TYPE *dest, const uint8_t *src, unsigned int width, const uint32_t *pal) +{ + unsigned int v, r, g, b; + const uint8_t *end = src + (width>>2); + + while (src < end) { + v = ldub_raw((void *) (src++)); + b = pal[v&0x3] & 0xff; + g = (pal[v&0x3]>>8) & 0xff; + r = (pal[v&0x3]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>2; + b = pal[v&0x3] & 0xff; + g = (pal[v&0x3]>>8) & 0xff; + r = (pal[v&0x3]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>2; + b = pal[v&0x3] & 0xff; + g = (pal[v&0x3]>>8) & 0xff; + r = (pal[v&0x3]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>2; + b = pal[v] & 0xff; + g = (pal[v]>>8) & 0xff; + r = (pal[v]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + } +} + +/* + * 4-bit colour + */ +static void glue(omap3_lcd_panel_draw_line4_, DEPTH)( + PIXEL_TYPE *dest, const uint8_t *src, unsigned int width, const uint32_t *pal) +{ + unsigned int v, r, g, b; + const uint8_t *end = src + (width>>1); + + while (src < end) { + v = ldub_raw((void *) (src++)); + b = pal[v&0xf] & 0xff; + g = (pal[v&0xf]>>8) & 0xff; + r = (pal[v&0xf]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>4; + b = pal[v] & 0xff; + g = (pal[v]>>8) & 0xff; + r = (pal[v]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + } +} + +/* + * 8-bit colour + */ +static void glue(omap3_lcd_panel_draw_line8_, DEPTH)( + PIXEL_TYPE *dest, const uint8_t *src, unsigned int width, const uint32_t *pal) +{ + unsigned int v, r, g, b; + const uint8_t *end = src + width; + + while (src < end) { + v = ldub_raw((void *) (src++)); + r = pal[v] & 0xff; + g = (pal[v]>>8) & 0xff; + b = (pal[v]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + } +} + +/* + * 16-bit colour with alpha + */ +static void glue(omap3_lcd_panel_draw_line16a_, DEPTH)(PIXEL_TYPE *dest, + const uint16_t *src, unsigned int width, const uint32_t *pal) +{ + uint16_t data; + unsigned int r, g, b; + const uint16_t *end = src + width; + while (src < end) { + data = lduw_raw(src ++); + b = (data & 0xf) << 4; + data >>= 4; + g = (data & 0xf) << 4; + data >>= 4; + r = (data & 0xf) << 4; + data >>= 4; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + } +} + +/* + * 16-bit colour + */ static void glue(omap3_lcd_panel_draw_line16_, DEPTH)(PIXEL_TYPE *dest, - const uint16_t *src, unsigned int width) + const uint16_t *src, unsigned int width, const uint32_t *pal) { #if !defined(SWAP_WORDS) && DEPTH == 16 memcpy(dest, src, width); #else uint16_t data; unsigned int r, g, b; - const uint16_t *end = (const void *) src + width; + const uint16_t *end = src + width; while (src < end) { data = lduw_raw(src ++); b = (data & 0x1f) << 3; @@ -92,12 +242,12 @@ /* No rotation */ static omap3_lcd_panel_fn_t glue(omap3_lcd_panel_draw_fn_, DEPTH)[0x10] = { - NULL, /*0x0*/ - NULL, /*0x1*/ - NULL, /*0x2*/ - NULL, /*0x3*/ + (omap3_lcd_panel_fn_t)glue(omap3_lcd_panel_draw_line1_, DEPTH), /*0x0*/ + (omap3_lcd_panel_fn_t)glue(omap3_lcd_panel_draw_line2_, DEPTH), /*0x1*/ + (omap3_lcd_panel_fn_t)glue(omap3_lcd_panel_draw_line4_, DEPTH), /*0x2*/ + (omap3_lcd_panel_fn_t)glue(omap3_lcd_panel_draw_line8_, DEPTH), /*0x3*/ NULL, /*0x4:RGB 12 */ - NULL, /*0x5: ARGB16 */ + (omap3_lcd_panel_fn_t)glue(omap3_lcd_panel_draw_line16a_, DEPTH), /*0x5: ARGB16 */ (omap3_lcd_panel_fn_t)glue(omap3_lcd_panel_draw_line16_, DEPTH), /*0x6: RGB 16 */ NULL, /*0x7*/ NULL, /*0x8: RGB 24 (un-packed in 32-bit container) */ diff -ur qemu-omap3-orig/hw/omap_dss.c qemu-omap3/hw/omap_dss.c --- qemu-omap3-orig/hw/omap_dss.c 2008-12-12 09:58:04.000000000 +0000 +++ qemu-omap3/hw/omap_dss.c 2009-03-01 16:28:41.000000000 +0000 @@ -629,6 +629,25 @@ (fb & ~TARGET_PAGE_MASK); } +static void *omap_rfbi_get_palette(struct omap_dss_s *s) +{ + target_phys_addr_t fb; + uint32_t pd; + + /* TODO */ + fb = s->dispc.l[0].addr[2]; + + pd = cpu_get_physical_page_desc(fb); + if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) + /* TODO */ + cpu_abort(cpu_single_env, "%s: palette outside RAM!\n", + __FUNCTION__); + else + return phys_ram_base + + (pd & TARGET_PAGE_MASK) + + (fb & ~TARGET_PAGE_MASK); +} + static void omap_rfbi_transfer_stop(struct omap_dss_s *s) { if (!s->rfbi.busy) @@ -1120,23 +1139,23 @@ /*omap3 lcd panel stuff*/ -/* Bytes(!) per pixel */ +/* Bits per pixel */ static const int omap3_lcd_panel_bpp[0x10] = { - 0, /*0x0*/ - 0, /*0x1*/ - 0, /*0x2*/ - 0, /*0x3*/ - 2, /*0x4:RGB 12 */ - 2, /*0x5: ARGB16 */ - 2, /*0x6: RGB 16 */ + 1, /*0x0*/ + 2, /*0x1*/ + 4, /*0x2*/ + 8, /*0x3*/ + 12, /*0x4:RGB 12 */ + 16, /*0x5: ARGB16 */ + 16, /*0x6: RGB 16 */ 0, /*0x7*/ - 4, /*0x8: RGB 24 (un-packed in 32-bit container) */ - 3, /*0x9: RGB 24 (packed in 24-bit container) */ + 32, /*0x8: RGB 24 (un-packed in 32-bit container) */ + 24, /*0x9: RGB 24 (packed in 24-bit container) */ 0, /*0xa */ 0, /*0xb */ - 4, /*0xc: ARGB32 */ - 4, /*0xd: RGBA32 */ - 4, /*0xe: RGBx 32 (24-bit RGB aligned on MSB of the 32-bit container) */ + 32, /*0xc: ARGB32 */ + 32, /*0xd: RGBA32 */ + 32, /*0xe: RGBx 32 (24-bit RGB aligned on MSB of the 32-bit container) */ 0, /*0xf */ }; @@ -1239,10 +1258,16 @@ copy_height = lcd_height>graphic_height ? graphic_height:lcd_height; + uint32_t *pal = 0; + if(dss->dispc.l[0].gfx_format < 4) + pal = (uint32_t *) omap_rfbi_get_palette(dss); + else + pal = src; // Avoid crash? + for (y=start_y;yline_fn(dest,src,copy_width*lcd_Bpp); - src += graphic_width*lcd_Bpp; + s->line_fn(dest,src,copy_width,pal); + src += (graphic_width*lcd_Bpp)>>3; dest += linesize; } diff -ur qemu-omap3-orig/hw/omap.h qemu-omap3/hw/omap.h --- qemu-omap3-orig/hw/omap.h 2008-12-15 08:16:05.000000000 +0000 +++ qemu-omap3/hw/omap.h 2009-03-01 16:11:54.000000000 +0000 @@ -851,7 +851,7 @@ void (*block)(void *opaque, int dc, void *buf, size_t len, int pitch); uint16_t (*read)(void *opaque, int dc); }; -typedef void (*omap3_lcd_panel_fn_t)(uint8_t *, const uint8_t *, unsigned int); +typedef void (*omap3_lcd_panel_fn_t)(uint8_t *, const uint8_t *, unsigned int,const uint32_t *); struct omap3_lcd_panel_s { struct omap_dss_s *dss; DisplayState *state; diff -ur qemu-omap3-orig/target-arm/helper.c qemu-omap3/target-arm/helper.c --- qemu-omap3-orig/target-arm/helper.c 2008-11-15 08:42:06.000000000 +0000 +++ qemu-omap3/target-arm/helper.c 2009-03-02 21:07:48.000000000 +0000 @@ -1303,6 +1303,16 @@ return ret; } +static uint32_t omap3_cacheconfig[16] = +{ +0xE007E01A, //16K L1 data +0x2007E01A, //16K L1 instr +0xF03FE03A, //256K L2 unified +0,0,0,0,0,0,0,0,0,0,0,0,0, // Others reserved +}; + +static uint32_t omap3_cachelevel = 0; + void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val) { int op1; @@ -1315,7 +1325,8 @@ switch ((insn >> 16) & 0xf) { case 0: if (((insn >> 21) & 7) == 2) { - /* ??? Select cache level. Ignore. */ + printf("set cache level id = %08x\n",val); + omap3_cachelevel = val & 0xF; return; } /* ID codes. */ @@ -1512,7 +1523,13 @@ case 10: /* MMU TLB lockdown. */ /* ??? TLB lockdown not implemented. */ break; - case 12: /* Reserved. */ + case 12: + if((op1 == 0) && (op2 == 0) && (crm == 0)) + { + /* Exception vector base - ignore */ + break; + } + /* Else reserved. */ goto bad_reg; case 13: /* Process ID. */ switch (op2) { @@ -1643,6 +1660,16 @@ goto bad_reg; if (arm_feature(env, ARM_FEATURE_XSCALE)) goto bad_reg; + if (op2 == 0) + { + printf("cache level %d config = %08x\n",omap3_cachelevel,omap3_cacheconfig[omap3_cachelevel]); + return omap3_cacheconfig[omap3_cachelevel]; + } + else if(op2 == 1) + { + printf("cache level id\n"); + return 0x0a000023; + } return 0; default: goto bad_reg; @@ -1794,7 +1821,25 @@ /* ??? TLB lockdown not implemented. */ return 0; case 11: /* TCM DMA control. */ - case 12: /* Reserved. */ + case 12: /* Interrupt status register */ + if((op1 == 0) && (op2 == 0) && (crm == 1)) + { + /* Just claim that both IRQ and FIQ are pending; the code below doesn't work reliably (or at all?) */ + return 0xC0; + /* switch(env->exception_index) + { + case EXCP_IRQ: + return 0x80; + case EXCP_FIQ: + return 0x40; + default: + return 0; + } */ + } + else if((op1 == 0) && (op2 == 0) && (crm == 0)) + { + return 0; + } goto bad_reg; case 13: /* Process ID. */ switch (op2) {