void MachineS3c6400::hardwareShutdown(struct fbinfo *fbi) { fb_printf(fbi, "\n\n MachineS3c6400::hardwareShutdown USB...\n"); resetUSB(usb_sigmask); fb_printf(fbi, " MachineS3c6400::hardwareShutdown DMA...\n"); s3c6400ShutdownDMA(fbi); fb_printf(fbi, " MachineS3c6400::hardwareShutdown Clear IRQ...\n"); clearIRQS(); }
static int writeData(void* _call) { unsigned char r; unsigned char g; unsigned char b; unsigned char a; int x,y; int res = 0; unsigned char* dst; WriterFBCallData_t* call = (WriterFBCallData_t*) _call; fb_printf(100, "\n"); if (call == NULL) { fb_err("call data is NULL...\n"); return 0; } if (call->destination == NULL) { fb_err("file pointer < 0. ignoring ...\n"); return 0; } if (call->data != NULL) { unsigned int opacity = 255 - ((unsigned int)_a(call->color)); unsigned int r = (unsigned int)_r(call->color); unsigned int g = (unsigned int)_g(call->color); unsigned int b = (unsigned int) _b(call->color); int src_stride = call->Stride; int dst_stride = call->destStride; int dst_delta = dst_stride - call->Width*4; int x,y; const unsigned char *src = call->data; unsigned char *dst = call->destination + (call->y * dst_stride + call->x * 4); //uint32_t *dst = call->destination + call->y * dst_stride + call->x; unsigned int k,ck,t; static uint32_t last_color = 0, colortable[256]; if (last_color != call->color) { // call->color is rgba, our spark frame buffer is argb uint32_t c = call->color >> 8, a = 255 - (call->color & 0xff); int i; for (i = 0; i < 256; i++) { uint32_t k = (a * i) >> 8; colortable[i] = k ? (c | (k << 24)) : 0; } last_color = call->color; }
/* * Bootmenu frame */ void bootmenu_frame(void) { /* Centered */ char buffer[TEXT_LINE_CHARS+1]; const char* hint = "Use volume keys to highlight, power to select."; int i; int l = strlen(hint); /* clear screen */ fb_clear(); /* set status */ fb_set_status("Bootmenu Mode"); /* Draw hint */ for (i = 0; i < (TEXT_LINE_CHARS - l) / 2; i++) buffer[i] = ' '; strncpy(&(buffer[(TEXT_LINE_CHARS - l) / 2]), hint, l); fb_printf(buffer); fb_printf("\n\n\n"); }
void fb_compat_println_error(const char* fmt, ...) { char buffer[256]; /* Parse arguments */ va_list args; va_start(args, fmt); vsnprintf(buffer, ARRAY_SIZE(buffer), fmt, args); va_end(args); /* Send it */ fb_printf("%s%s\n", fb_text_color_code2(error_text_color), buffer); fb_refresh(); }
static int writeData(void* _call) { unsigned char r; unsigned char g; unsigned char b; unsigned char a; int x,y; int res = 0; unsigned char* dst; WriterFBCallData_t* call = (WriterFBCallData_t*) _call; fb_printf(100, "\n"); if (call == NULL) { fb_err("call data is NULL...\n"); return 0; } if (call->destination == NULL) { fb_err("file pointer < 0. ignoring ...\n"); return 0; } if (call->data != NULL) { unsigned int opacity = 255 - ((unsigned int)_a(call->color)); unsigned int r = (unsigned int)_r(call->color); unsigned int g = (unsigned int)_g(call->color); unsigned int b = (unsigned int) _b(call->color); int src_stride = call->Stride; int dst_stride = call->destStride; int dst_delta = dst_stride - call->Width*4; int x,y; const unsigned char *src = call->data; unsigned char *dst = call->destination + (call->y * dst_stride + call->x * 4); unsigned int k,ck,t; fb_printf(100, "x %d\n", call->x); fb_printf(100, "y %d\n", call->y); fb_printf(100, "width %d\n", call->Width); fb_printf(100, "height %d\n", call->Height); fb_printf(100, "stride %d\n", call->Stride); fb_printf(100, "color %d\n", call->color); fb_printf(100, "data %p\n", call->data); fb_printf(100, "dest %p\n", call->destination); fb_printf(100, "dest.stride %d\n", call->destStride); fb_printf(100, "r 0x%hhx, g 0x%hhx, b 0x%hhx, a 0x%hhx, opacity %d\n", r, g, b, a, opacity); for (y=0;y<call->Height;y++) { for (x = 0; x < call->Width; x++) { k = ((unsigned)src[x]) * opacity / 255; ck = 255 - k; t = *dst; *dst++ = (k*b + ck*t) / 255; t = *dst; *dst++ = (k*g + ck*t) / 255; t = *dst; *dst++ = (k*r + ck*t) / 255; *dst++ = 0; } dst += dst_delta; src += src_stride; } } else { for (y = 0; y < call->Height; y++) memset(call->destination + ((call->y + y) * call->destStride) + call->x * 4, 0, call->Width * 4); } fb_printf(100, "< %d\n", res); return res; }
void MachineS3c6400::s3c6400ShutdownDMA(struct fbinfo *fbi) { volatile uint32 * SDMA_SEL; volatile uint32 * DMA_CTRL; uint32 ch_conf, config; int timeout; int dma_ctrl, dma_ch, sdma_sel; int ctrl_count=4; const uint32 S3C6410_DMA_CTRL_LIST[] = { S3C6400_PA_DMA0, S3C6400_PA_DMA1, S3C6400_PA_SDMA0, S3C6400_PA_SDMA1 }; SDMA_SEL = (uint32*)memPhysMap(0x7E00F110); if (SDMA_SEL) { sdma_sel = SDMA_SEL[0]; fb_printf(fbi,"%s: SDMA_SEL=%x", __func__, sdma_sel); if (sdma_sel == 0xcfffffff) //SDMA disabled ctrl_count = 2; //set to standard DMA SDMA_SEL[0]=0xcfffffff; } fb_printf(fbi, " set\n"); /* 6410 : we have 2 (+2 secure) controllers with 8 channels each */ for (dma_ctrl = 0; dma_ctrl < ctrl_count; dma_ctrl++) { DMA_CTRL = (uint32*) memPhysMap(S3C6410_DMA_CTRL_LIST[dma_ctrl]); if (DMA_CTRL) { config = s3c_readl(DMA_CTRL, PL080_EN_CHAN); if (config == 0) { fb_printf(fbi, "%s: controller %d already disabled\n", __func__, dma_ctrl); fb_printf(fbi, "%s: clear controller %d irq\n", __func__, dma_ctrl); s3c_writel(DMA_CTRL, PL080_TC_CLEAR, 0xFF); s3c_writel(DMA_CTRL, PL080_ERR_CLEAR, 0xFF); fb_printf(fbi, "%s: clear controller %d irq done\n", __func__, dma_ctrl); //continue; } for (dma_ch = 0; dma_ch < 8; dma_ch ++) { int offset = 0x114 + (dma_ch*0x20); //if (dma_ctrl < 2) // ch_conf = PL080_Cx_CONFIG(dma_ch); //else ch_conf = PL080S_Cx_CONFIG(dma_ch); config = s3c_readl(DMA_CTRL, ch_conf); config |= PL080_CONFIG_HALT; s3c_writel(DMA_CTRL, ch_conf, config); timeout = 1000; do { config = s3c_readl(DMA_CTRL, ch_conf); fb_printf(fbi, "%s: dma_ctrl %d, dma_ch %d : t%d - config@%x/%x = %x\n", __func__, dma_ctrl, dma_ch, timeout, ch_conf, offset, config); if (config & PL080_CONFIG_ACTIVE) s3c_udelay(10); else break; } while (--timeout > 0); if (config & PL080_CONFIG_ACTIVE) { fb_printf(fbi, "%s: channel still active\n", __func__); // return -EFAULT; } config = s3c_readl(DMA_CTRL, ch_conf); config &= ~PL080_CONFIG_ENABLE; s3c_writel(DMA_CTRL, ch_conf, config); } } /* clear controller interrupts */ fb_printf(fbi, "%s: clear controller %d irq\n", __func__, dma_ctrl); s3c_writel(DMA_CTRL, PL080_TC_CLEAR, 0xFF); s3c_writel(DMA_CTRL, PL080_ERR_CLEAR, 0xFF); fb_printf(fbi, "%s: clear controller %d irq done\n", __func__, dma_ctrl); } fb_printf(fbi, "%s: done\n", __func__); return; }
/* * Entry point of bootmenu * Magic is Acer BL data structure, used as parameter for some functions. * * - keystate at boot is loaded * - boot partition (primary or secondary) is loaded * - can continue boot, and force fastboot or recovery mode * * boot_handle - pass to boot partition */ void main(void* global_handle, int boot_handle) { /* Selected option in boot menu */ int selected_option = 0; /* Key press: -1 nothing, 0 Vol DOWN, 1 Vol UP, 2 Power */ enum key_type key_press = KEY_NONE; /* Which kernel image is booted */ const char* boot_partition_str; const char* other_boot_partition_str; const char* boot_partition_attempt; /* Debug mode status */ const char* debug_mode_str; const char* other_debug_mode_str; /* Print error, from which partition booting failed */ char error_message[TEXT_LINE_CHARS + 1]; /* Line builder - two color codes used */ char line_builder[TEXT_LINE_CHARS + 8 + 1]; int i, l; struct color* b; struct font_color* fc; error_message[0] = '\0'; /* Initialize framebuffer */ fb_init(); /* Set title */ fb_set_title(bootloader_id); /* Print it */ fb_refresh(); /* Ensure we have bootloader update */ check_bootloader_update(global_handle); /* Read msc command */ msc_cmd_read(); /* First, check MSC command */ if (!strncmp((const char*)msc_cmd.boot_command, MSC_CMD_RECOVERY, strlen(MSC_CMD_RECOVERY))) this_boot_mode = BM_RECOVERY; else if (!strncmp((const char*)msc_cmd.boot_command, MSC_CMD_FCTRY_RESET, strlen(MSC_CMD_FCTRY_RESET))) this_boot_mode = BM_FCTRY_RESET; else if (!strncmp((const char*)msc_cmd.boot_command, MSC_CMD_FASTBOOT, strlen(MSC_CMD_FASTBOOT))) this_boot_mode = BM_FASTBOOT; else if (!strncmp((const char*)msc_cmd.boot_command, MSC_CMD_BOOTMENU, strlen(MSC_CMD_BOOTMENU))) this_boot_mode = BM_BOOTMENU; else this_boot_mode = BM_NORMAL; msc_boot_mode = this_boot_mode; /* Evaluate key status */ if (get_key_active(KEY_VOLUME_UP)) this_boot_mode = BM_BOOTMENU; else if (get_key_active(KEY_VOLUME_DOWN)) this_boot_mode = BM_RECOVERY; /* Clear boot command from msc */ memset(msc_cmd.boot_command, 0, ARRAY_SIZE(msc_cmd.boot_command)); msc_cmd_write(); /* Evaluate boot mode */ if (this_boot_mode == BM_NORMAL) { if (msc_cmd.boot_partition == 0) boot_partition_attempt = "primary (LNX)"; else boot_partition_attempt = "secondary (AKB)"; boot_normal(msc_cmd.boot_partition, boot_handle); snprintf(error_message, ARRAY_SIZE(error_message), "ERROR: Invalid %s kernel image.", boot_partition_attempt); } else if (this_boot_mode == BM_RECOVERY) { boot_recovery(boot_handle); snprintf(error_message, ARRAY_SIZE(error_message), "ERROR: Invalid recovery (SOS) kernel image."); } else if (this_boot_mode == BM_FCTRY_RESET) { fb_set_status("Factory reset\n"); /* Erase userdata */ fb_printf("Erasing UDA partition...\n\n"); fb_refresh(); format_partition("UDA"); /* Erase cache */ fb_printf("Erasing CAC partition...\n\n"); fb_refresh(); format_partition("CAC"); /* Finished */ fb_printf("Done.\n"); fb_refresh(); /* Sleep */ sleep(5000); /* Reboot */ reboot(global_handle); /* Reboot returned */ bootmenu_error(); } else if (this_boot_mode == BM_FASTBOOT) { /* Load fastboot */ fastboot_main(global_handle, boot_handle, error_message, ARRAY_SIZE(error_message)); /* Fastboot returned - show bootmenu */ } /* Allright - now we're in bootmenu */ /* Boot menu */ while (1) { /* New frame */ bootmenu_frame(); /* Print current boot mode */ if (msc_cmd.boot_partition == 0) { boot_partition_str = "Primary"; other_boot_partition_str = "Secondary"; } else { boot_partition_str = "Secondary"; other_boot_partition_str = "Primary"; } fb_printf("Current boot mode: %s kernel image\n", boot_partition_str); if (msc_cmd.debug_mode == 0) { debug_mode_str = "OFF"; other_debug_mode_str = "ON"; } else { debug_mode_str = "ON"; other_debug_mode_str = "OFF"; } fb_printf("Debug mode: %s\n\n", debug_mode_str); /* Print error if we're stuck in bootmenu */ if (error_message[0] != '\0') fb_color_printf("%s\n\n", NULL, &error_text_color, error_message); else fb_printf("\n"); /* Print options */ for (i = 0; i < ARRAY_SIZE(boot_menu_items); i++) { memset(line_builder, 0x20, ARRAY_SIZE(line_builder)); line_builder[ARRAY_SIZE(line_builder) - 1] = '\0'; line_builder[ARRAY_SIZE(line_builder) - 2] = '\n'; if (i == selected_option) { b = &highlight_color; fc = &highlight_text_color; } else { b = NULL; fc = &text_color; } if (i == 5) snprintf(line_builder, ARRAY_SIZE(line_builder), boot_menu_items[i], other_boot_partition_str); else if (i == 6) snprintf(line_builder, ARRAY_SIZE(line_builder), boot_menu_items[i], other_debug_mode_str); else snprintf(line_builder, ARRAY_SIZE(line_builder), boot_menu_items[i]); l = strlen(line_builder); if (l == ARRAY_SIZE(line_builder) - 1) line_builder[ARRAY_SIZE(line_builder) - 2] = '\n'; else if (l < ARRAY_SIZE(line_builder) - 1) line_builder[l] = ' '; fb_color_printf(line_builder, b, fc); } /* Draw framebuffer */ fb_refresh(); key_press = wait_for_key_event(); if (key_press == KEY_NONE) continue; /* Volume DOWN */ if (key_press == KEY_VOLUME_DOWN) { selected_option++; if (selected_option >= ARRAY_SIZE(boot_menu_items)) selected_option = 0; continue; } /* Volume UP */ if (key_press == KEY_VOLUME_UP) { selected_option--; if (selected_option < 0) selected_option = ARRAY_SIZE(boot_menu_items) - 1; continue; } /* Power */ if (key_press == KEY_POWER) { switch(selected_option) { case 0: /* Reboot */ reboot(global_handle); /* Reboot returned */ bootmenu_error(); case 1: /* Fastboot mode */ fastboot_main(global_handle, boot_handle, error_message, ARRAY_SIZE(error_message)); /* Returned? Continue bootmenu */ break; case 2: /* Primary kernel image */ boot_normal(0, boot_handle); snprintf(error_message, ARRAY_SIZE(error_message), "ERROR: Invalid primary (LNX) kernel image."); break; case 3: /* Secondary kernel image */ boot_normal(1, boot_handle); snprintf(error_message, ARRAY_SIZE(error_message), "ERROR: Invalid secondary (AKB) kernel image."); break; case 4: /* Recovery kernel image */ boot_recovery(boot_handle); snprintf(error_message, ARRAY_SIZE(error_message), "ERROR: Invalid recovery (SOS) kernel image."); break; case 5: /* Toggle boot kernel image */ msc_cmd.boot_partition = !msc_cmd.boot_partition; msc_cmd_write(); selected_option = 0; break; case 6: /* Toggle debug mode */ msc_cmd.debug_mode = !msc_cmd.debug_mode; msc_cmd_write(); selected_option = 0; break; case 7: /* Wipe cache */ bootmenu_basic_frame(); fb_set_status("Bootmenu Mode"); fb_printf("Erasing CAC partition...\n\n"); fb_refresh(); format_partition("CAC"); fb_printf("Done.\n"); fb_refresh(); sleep(2000); selected_option = 0; break; } } } }