From 5dce36a875b20c0aeb35e3e5ec8d90f168685a21 Mon Sep 17 00:00:00 2001 From: mcuelenaere Date: Fri, 5 Sep 2008 15:09:40 +0000 Subject: [PATCH] Add Onda VX767 target git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18422 a1c6a512-1295-4272-9138-f99709370657 --- bootloader/SOURCES | 2 +- bootloader/ondavx747.c | 6 + firmware/SOURCES | 6 + firmware/export/config-ondavx747.h | 7 - .../{config-ondavx747.h => config-ondavx767.h} | 27 +-- firmware/export/config.h | 4 + firmware/export/cpu.h | 3 + .../ingenic_jz47xx/{onda_vx747 => }/lcd-target.h | 0 .../lcd-target.h => onda_vx767/adc-target.h} | 18 +- .../onda_vx767/backlight-ondavx767.c | 80 +++++++++ .../lcd-target.h => onda_vx767/backlight-target.h} | 25 +-- .../ingenic_jz47xx/onda_vx767/button-ondavx767.c | 70 ++++++++ .../lcd-target.h => onda_vx767/button-target.h} | 38 ++-- .../mips/ingenic_jz47xx/onda_vx767/lcd-ondavx767.c | 195 +++++++++++++++++++++ .../target/mips/ingenic_jz47xx/system-jz4740.c | 122 +++++++------ tools/configure | 23 +++ 16 files changed, 515 insertions(+), 111 deletions(-) copy firmware/export/{config-ondavx747.h => config-ondavx767.h} (91%) copy firmware/target/mips/ingenic_jz47xx/{onda_vx747 => }/lcd-target.h (100%) copy firmware/target/mips/ingenic_jz47xx/{onda_vx747/lcd-target.h => onda_vx767/adc-target.h} (75%) create mode 100644 firmware/target/mips/ingenic_jz47xx/onda_vx767/backlight-ondavx767.c copy firmware/target/mips/ingenic_jz47xx/{onda_vx747/lcd-target.h => onda_vx767/backlight-target.h} (74%) create mode 100644 firmware/target/mips/ingenic_jz47xx/onda_vx767/button-ondavx767.c rename firmware/target/mips/ingenic_jz47xx/{onda_vx747/lcd-target.h => onda_vx767/button-target.h} (56%) create mode 100644 firmware/target/mips/ingenic_jz47xx/onda_vx767/lcd-ondavx767.c diff --git a/bootloader/SOURCES b/bootloader/SOURCES index 2e78caa2a..c1771ff24 100644 --- a/bootloader/SOURCES +++ b/bootloader/SOURCES @@ -31,7 +31,7 @@ mrobe500.c telechips.c #elif defined(MEIZU_M6SL) meizu_m6sl.c -#elif defined(ONDA_VX747) +#elif defined(ONDA_VX747) || defined(ONDA_VX767) ondavx747.c #elif defined(CREATIVE_ZVx) creativezvm.c diff --git a/bootloader/ondavx747.c b/bootloader/ondavx747.c index a3a3571ac..8dd957eca 100644 --- a/bootloader/ondavx747.c +++ b/bootloader/ondavx747.c @@ -160,7 +160,11 @@ int main(void) #endif while(1) { +#ifdef ONDA_VX747 btn = button_read_device(&touch); +#else + btn = button_read_device(); +#endif #define KNOP(x,y) lcd_set_foreground(LCD_BLACK); \ if(btn & x) \ lcd_set_foreground(LCD_WHITE); \ @@ -184,6 +188,7 @@ int main(void) { power_off(); } +#ifdef ONDA_VX747 if(btn & BUTTON_TOUCH) { lcd_set_foreground(LCD_RGBPACK(touch & 0xFF, (touch >> 8)&0xFF, (touch >> 16)&0xFF)); @@ -191,6 +196,7 @@ int main(void) lcd_update(); lcd_set_foreground(LCD_WHITE); } +#endif snprintf(datetime, 30, "%02d/%02d/%04d %02d:%02d:%02d", get_time()->tm_mday, get_time()->tm_mon, get_time()->tm_year, get_time()->tm_hour, get_time()->tm_min, get_time()->tm_sec); lcd_putsxy(LCD_WIDTH-SYSFONT_WIDTH*strlen(datetime), LCD_HEIGHT-SYSFONT_HEIGHT, datetime); diff --git a/firmware/SOURCES b/firmware/SOURCES index 24be9e58a..2075f8089 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -1093,3 +1093,9 @@ target/mips/ingenic_jz47xx/onda_vx747/backlight-onda_vx747.c target/mips/ingenic_jz47xx/onda_vx747/lcd-onda_vx747.c target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c #endif + +#ifdef ONDA_VX767 +target/mips/ingenic_jz47xx/onda_vx767/backlight-ondavx767.c +target/mips/ingenic_jz47xx/onda_vx767/button-ondavx767.c +target/mips/ingenic_jz47xx/onda_vx767/lcd-ondavx767.c +#endif diff --git a/firmware/export/config-ondavx747.h b/firmware/export/config-ondavx747.h index 66570d462..e015a5337 100644 --- a/firmware/export/config-ondavx747.h +++ b/firmware/export/config-ondavx747.h @@ -155,13 +155,6 @@ #define USB_VENDOR_ID 0x041e #define USB_PRODUCT_ID 0x4133*/ -/*DEBUGGING!*/ -#ifdef BOOTLOADER -#define THREAD_EXTRA_CHECKS 1 -#define DEBUG 1 -#define debug(msg) printf(msg) -#endif - #include /* HACKY */ #endif diff --git a/firmware/export/config-ondavx747.h b/firmware/export/config-ondavx767.h similarity index 91% copy from firmware/export/config-ondavx747.h copy to firmware/export/config-ondavx767.h index 66570d462..a72b73ba3 100644 --- a/firmware/export/config-ondavx747.h +++ b/firmware/export/config-ondavx767.h @@ -26,12 +26,12 @@ #define CONFIG_SDRAM_START 0x80004000 -#define ONDA_VX747 1 +#define ONDA_VX767 1 -#define MODEL_NAME "Onda VX747" +#define MODEL_NAME "Onda VX767" /* For Rolo and boot loader */ -#define MODEL_NUMBER 30 +#define MODEL_NUMBER 31 /* define this if you use an ATA controller */ //#define HAVE_ATA @@ -55,21 +55,19 @@ #define HAVE_VOLUME_IN_LIST /* LCD dimensions */ -#define CONFIG_LCD LCD_ONDAVX747 +#define CONFIG_LCD LCD_ONDAVX767 -#define LCD_WIDTH 240 -#define LCD_HEIGHT 400 +#define LCD_WIDTH 320 +#define LCD_HEIGHT 240 #define LCD_DEPTH 16 /* 16bit colours */ #define LCD_PIXELFORMAT RGB565 /* rgb565 */ /* Define this if your LCD can be enabled/disabled */ -#define HAVE_LCD_ENABLE +//#define HAVE_LCD_ENABLE -#define CONFIG_KEYPAD ONDAVX747_PAD +#define CONFIG_KEYPAD ONDAVX767_PAD #define HAS_BUTTON_HOLD -#define HAVE_TOUCHSCREEN -#define HAVE_BUTTON_DATA /* Define this if you do software codec */ #define CONFIG_CODEC SWCODEC @@ -146,7 +144,7 @@ /* Define this if you have adjustable CPU frequency */ /* #define HAVE_ADJUSTABLE_CPU_FREQ */ -#define BOOTFILE_EXT "vx747" +#define BOOTFILE_EXT "vx767" #define BOOTFILE "rockbox." BOOTFILE_EXT #define BOOTDIR "/.rockbox" @@ -155,13 +153,6 @@ #define USB_VENDOR_ID 0x041e #define USB_PRODUCT_ID 0x4133*/ -/*DEBUGGING!*/ -#ifdef BOOTLOADER -#define THREAD_EXTRA_CHECKS 1 -#define DEBUG 1 -#define debug(msg) printf(msg) -#endif - #include /* HACKY */ #endif diff --git a/firmware/export/config.h b/firmware/export/config.h index d700a1510..bdf874394 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -94,6 +94,7 @@ #define PHILIPS_HDD1630_PAD 29 #define MEIZU_M6SL_PAD 30 #define ONDAVX747_PAD 31 +#define ONDAVX767_PAD 32 /* CONFIG_REMOTE_KEYPAD */ #define H100_REMOTE 1 @@ -137,6 +138,7 @@ #define LCD_HDD1630 27 /* as used by the Philips HDD1630 */ #define LCD_MEIZUM6 28 /* as used by the Meizu M6SP and M6SL (various models) */ #define LCD_ONDAVX747 29 /* as used by the Onda VX747 */ +#define LCD_ONDAVX767 30 /* as used by the Onda VX767 */ /* LCD_PIXELFORMAT */ #define HORIZONTAL_PACKING 1 @@ -291,6 +293,8 @@ #include "config-meizu-m6sl.h" #elif defined(ONDA_VX747) #include "config-ondavx747.h" +#elif defined(ONDA_VX767) +#include "config-ondavx767.h" #else /* no known platform */ #endif diff --git a/firmware/export/cpu.h b/firmware/export/cpu.h index 83beab2fd..86efd31ef 100644 --- a/firmware/export/cpu.h +++ b/firmware/export/cpu.h @@ -59,3 +59,6 @@ #if CONFIG_CPU == S5L8700 #include "s5l8700.h" #endif +#if CONFIG_CPU == JZ4732 +#include "jz4740.h" +#endif diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-target.h b/firmware/target/mips/ingenic_jz47xx/lcd-target.h similarity index 100% copy from firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-target.h copy to firmware/target/mips/ingenic_jz47xx/lcd-target.h diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-target.h b/firmware/target/mips/ingenic_jz47xx/onda_vx767/adc-target.h similarity index 75% copy from firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-target.h copy to firmware/target/mips/ingenic_jz47xx/onda_vx767/adc-target.h index e643608d5..e74f008a3 100644 --- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-target.h +++ b/firmware/target/mips/ingenic_jz47xx/onda_vx767/adc-target.h @@ -18,19 +18,11 @@ * KIND, either express or implied. * ****************************************************************************/ -#ifndef LCD_TARGET_H -#define LCD_TARGET_H +#ifndef _ADC_TARGET_H_ +#define _ADC_TARGET_H_ -#include +#define NUM_ADC_CHANNELS 4 -void lcd_enable(bool state); -bool lcd_enabled(void); -void lcd_init_device(void); +#define ADC_BUTTONS 0 - -void lcd_init_controller(void); -void lcd_set_target(short x, short y, short width, short height); -void lcd_on(void); -void lcd_off(void); - -#endif /* LCD_TARGET_H */ +#endif /* _ADC_TARGET_H_ */ diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx767/backlight-ondavx767.c b/firmware/target/mips/ingenic_jz47xx/onda_vx767/backlight-ondavx767.c new file mode 100644 index 000000000..9deab7712 --- /dev/null +++ b/firmware/target/mips/ingenic_jz47xx/onda_vx767/backlight-ondavx767.c @@ -0,0 +1,80 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 by Maurus Cuelenaere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "config.h" +#include "jz4740.h" +#include "backlight-target.h" + +#define GPIO_PWM 123 +#define PWM_CHN 7 +#define PWM_FULL 101 + +static void set_backlight(int unk, int val) +{ + if(val == 0) + __gpio_as_pwm7(); + else + { + REG_TCU_TCSR(7) |= 2; + REG_TCU_TCSR(7) &= ~0x100; + int tmp; + tmp = (unk/2 + __cpm_get_rtcclk()) / unk; + if(tmp > 0xFFFF) + tmp = 0xFFFF; + + __tcu_set_half_data(7, (tmp * unk * 1374389535) >> 5); + __tcu_set_full_data(7, tmp); + + REG_TCU_TSCR = (1 << 7); + REG_TCU_TESR = (1 << 7); + + __tcu_enable_pwm_output(7); + } + __tcu_set_count(7, 0); +} + +bool _backlight_init(void) +{ + __gpio_as_pwm7(); + + __tcu_stop_counter(7); + __tcu_disable_pwm_output(7); + + set_backlight(300, 7); + + return true; +} +void _backlight_on(void) +{ + set_backlight(300, 7); +} +void _backlight_off(void) +{ + set_backlight(300, 0); +} + +#ifdef HAVE_BACKLIGHT_BRIGHTNESS +void _backlight_set_brightness(int brightness) +{ + (void)brightness; + return; +} +#endif diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-target.h b/firmware/target/mips/ingenic_jz47xx/onda_vx767/backlight-target.h similarity index 74% copy from firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-target.h copy to firmware/target/mips/ingenic_jz47xx/onda_vx767/backlight-target.h index e643608d5..4170f96cc 100644 --- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-target.h +++ b/firmware/target/mips/ingenic_jz47xx/onda_vx767/backlight-target.h @@ -18,19 +18,20 @@ * KIND, either express or implied. * ****************************************************************************/ -#ifndef LCD_TARGET_H -#define LCD_TARGET_H +#ifndef BACKLIGHT_TARGET_H +#define BACKLIGHT_TARGET_H -#include - -void lcd_enable(bool state); -bool lcd_enabled(void); -void lcd_init_device(void); +#ifdef BOOTLOADER +#define BACKLIGHT_DRIVER_CLOSE +/* Force the whole driver to be built */ +#define BACKLIGHT_FULL_INIT +#endif +#include -void lcd_init_controller(void); -void lcd_set_target(short x, short y, short width, short height); -void lcd_on(void); -void lcd_off(void); +bool _backlight_init(void); +void _backlight_on(void); +void _backlight_off(void); +void _backlight_set_brightness(int brightness); -#endif /* LCD_TARGET_H */ +#endif /* BACKLIGHT_TARGET_H */ diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx767/button-ondavx767.c b/firmware/target/mips/ingenic_jz47xx/onda_vx767/button-ondavx767.c new file mode 100644 index 000000000..8b033a1be --- /dev/null +++ b/firmware/target/mips/ingenic_jz47xx/onda_vx767/button-ondavx767.c @@ -0,0 +1,70 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 by Maurus Cuelenaere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "config.h" +#include "system.h" +#include "jz4740.h" +#include "button-target.h" + +#define BTN_VOL_DOWN (1 << 27) +#define BTN_VOL_UP (1 << 0) +#define BTN_MENU (1 << 1) +#define BTN_OFF (1 << 29) +#define BTN_HOLD (1 << 16) +#define BTN_MASK (BTN_VOL_DOWN | BTN_VOL_UP \ + | BTN_MENU | BTN_OFF ) + +bool button_hold(void) +{ + return (~REG_GPIO_PXPIN(3) & BTN_HOLD ? 1 : 0); +} + +void button_init_device(void) +{ + __gpio_port_as_input(3, 29); + __gpio_port_as_input(3, 27); + __gpio_port_as_input(3, 16); + __gpio_port_as_input(3, 1); + __gpio_port_as_input(3, 0); +} + +int button_read_device(void) +{ + if(button_hold()) + return 0; + + unsigned int key = ~(__gpio_get_port(3)); + int ret = 0; + + if(key & BTN_MASK) + { + if(key & BTN_VOL_DOWN) + ret |= BUTTON_VOL_DOWN; + if(key & BTN_VOL_UP) + ret |= BUTTON_VOL_UP; + if(key & BTN_MENU) + ret |= BUTTON_MENU; + if(key & BTN_OFF) + ret |= BUTTON_POWER; + } + + return ret; +} diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-target.h b/firmware/target/mips/ingenic_jz47xx/onda_vx767/button-target.h similarity index 56% rename from firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-target.h rename to firmware/target/mips/ingenic_jz47xx/onda_vx767/button-target.h index e643608d5..32325d142 100644 --- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/lcd-target.h +++ b/firmware/target/mips/ingenic_jz47xx/onda_vx767/button-target.h @@ -18,19 +18,37 @@ * KIND, either express or implied. * ****************************************************************************/ -#ifndef LCD_TARGET_H -#define LCD_TARGET_H +#ifndef BUTTON_TARGET_H +#define BUTTON_TARGET_H #include +#include "config.h" -void lcd_enable(bool state); -bool lcd_enabled(void); -void lcd_init_device(void); +#define HAS_BUTTON_HOLD +bool button_hold(void); +void button_init_device(void); +int button_read_device(void); -void lcd_init_controller(void); -void lcd_set_target(short x, short y, short width, short height); -void lcd_on(void); -void lcd_off(void); +/* Main unit's buttons */ +#define BUTTON_POWER 0x00000001 +#define BUTTON_VOL_UP 0x00000002 +#define BUTTON_VOL_DOWN 0x00000004 +#define BUTTON_MENU 0x00000008 -#endif /* LCD_TARGET_H */ +/* Compatibility hacks for flipping. Needs a somewhat better fix. */ +#define BUTTON_LEFT 0 +#define BUTTON_RIGHT 0 +#define BUTTON_UP 0 +#define BUTTON_DOWN 0 + +#define BUTTON_MAIN (BUTTON_POWER | BUTTON_VOL_UP | BUTTON_VOL_DOWN | BUTTON_MENU) + +/* No remote */ +#define BUTTON_REMOTE 0 + +/* Software power-off */ +#define POWEROFF_BUTTON BUTTON_POWER +#define POWEROFF_COUNT 10 + +#endif /* BUTTON_TARGET_H */ diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx767/lcd-ondavx767.c b/firmware/target/mips/ingenic_jz47xx/onda_vx767/lcd-ondavx767.c new file mode 100644 index 000000000..63d1736eb --- /dev/null +++ b/firmware/target/mips/ingenic_jz47xx/onda_vx767/lcd-ondavx767.c @@ -0,0 +1,195 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 by Maurus Cuelenaere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "config.h" +#include "jz4740.h" +#include "lcd-target.h" + +#define PIN_CS_N (32*1+17) /* Chip select */ +#define PIN_RESET_N (32*1+18) /* Reset */ +#define PIN_UNK_N (32*2+19) + +#define my__gpio_as_lcd_16bit() \ +do { \ + REG_GPIO_PXFUNS(2) = 0x0014ffff; \ + REG_GPIO_PXSELC(2) = 0x0014ffff; \ + REG_GPIO_PXPES(2) = 0x0014ffff; \ +} while (0) + + +#define SLEEP(x) for(i=0; i 0x1ff ) + val = 0x1ff; /* CPM_LPCDR is too large, set it to 0x1ff */ + __cpm_set_pixdiv(val); + __cpm_start_lcd(); +} + +void lcd_init_controller(void) +{ + int i; + _display_pin_init(); + _set_lcd_bus(); + _set_lcd_clock(); + SLEEP(1000); + _display_init(); +} + +void lcd_set_target(short x, short y, short width, short height) +{ + SLCD_SEND_COMMAND(0x50, y); + SLCD_SEND_COMMAND(0x51, y+height-1); + SLCD_SEND_COMMAND(0x52, x); + SLCD_SEND_COMMAND(0x53, x+width-1); + /* TODO */ +} + +void lcd_on(void) +{ + _display_on(); +} + +void lcd_off(void) +{ + _display_off(); +} diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c index 8f1c3f5c1..61be6c60d 100644 --- a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c @@ -555,21 +555,7 @@ void dma_cache_wback_inv(unsigned long addr, unsigned long size) } } -extern int main(void); -extern void except_common_entry(void); - -#define mtc0_tlbw_hazard() \ - __asm__ __volatile__( \ - " .set noreorder \n" \ - " nop \n" \ - " nop \n" \ - " nop \n" \ - " nop \n" \ - " nop \n" \ - " nop \n" \ - " .set reorder \n"); - -#define tlbw_use_hazard() \ +#define BARRIER \ __asm__ __volatile__( \ " .set noreorder \n" \ " nop \n" \ @@ -580,10 +566,13 @@ extern void except_common_entry(void); " nop \n" \ " .set reorder \n"); - -#define PAGE_SHIFT PL_4K -#define PM_DEFAULT_MASK PM_4K -#define UNIQUE_ENTRYHI(idx) (A_K0BASE + ((idx) << (PAGE_SHIFT + 1))) +#define DEFAULT_PAGE_SHIFT PL_4K +#define DEFAULT_PAGE_MASK PM_4K +#define UNIQUE_ENTRYHI(idx, ps) (A_K0BASE + ((idx) << (ps + 1))) +#define ASID_MASK M_EntryHiASID +#define VPN2_SHIFT S_EntryHiVPN2 +#define PFN_SHIFT S_EntryLoPFN +#define PFN_MASK 0xffffff static void local_flush_tlb_all(void) { unsigned long old_ctx; @@ -594,59 +583,92 @@ static void local_flush_tlb_all(void) old_ctx = read_c0_entryhi(); write_c0_entrylo0(0); write_c0_entrylo1(0); + BARRIER; /* Blast 'em all away. */ - for(entry = read_c0_wired(); entry < 32; entry++) + for(entry = 0; entry < 32; entry++) { /* Make sure all entries differ. */ - write_c0_entryhi(UNIQUE_ENTRYHI(entry)); + write_c0_entryhi(UNIQUE_ENTRYHI(entry, DEFAULT_PAGE_SHIFT)); write_c0_index(entry); - mtc0_tlbw_hazard(); + BARRIER; tlb_write_indexed(); } - tlbw_use_hazard(); + BARRIER; write_c0_entryhi(old_ctx); restore_irq(old_irq); } +static void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, + unsigned long entryhi, unsigned long pagemask) +{ + unsigned long wired; + unsigned long old_pagemask; + unsigned long old_ctx; + unsigned int old_irq = disable_irq_save(); + + old_ctx = read_c0_entryhi() & ASID_MASK; + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); + write_c0_wired(wired + 1); + write_c0_index(wired); + BARRIER; + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); + BARRIER; + tlb_write_indexed(); + BARRIER; + + write_c0_entryhi(old_ctx); + BARRIER; + write_c0_pagemask(old_pagemask); + local_flush_tlb_all(); + restore_irq(old_irq); +} + +static void map_address(unsigned long virtual, unsigned long physical, unsigned long length) +{ + unsigned long entry0 = (physical & PFN_MASK) << PFN_SHIFT; + unsigned long entry1 = ((physical+length) & PFN_MASK) << PFN_SHIFT; + unsigned long entryhi = virtual & ~VPN2_SHIFT; + + entry0 |= (M_EntryLoG | M_EntryLoV | (K_CacheAttrC << S_EntryLoC) ); + entry1 |= (M_EntryLoG | M_EntryLoV | (K_CacheAttrC << S_EntryLoC) ); + + add_wired_entry(entry0, entry1, entryhi, DEFAULT_PAGE_MASK); +} + static void tlb_init(void) { - write_c0_pagemask(PM_DEFAULT_MASK); + write_c0_pagemask(DEFAULT_PAGE_MASK); write_c0_wired(0); write_c0_framemask(0); local_flush_tlb_all(); +/* + map_address(0x80000000, 0x80000000, 0x4000); + map_address(0x80004000, 0x80004000, MEM * 0x100000); +*/ } -static void tlb_refill_handler(void) +void tlb_refill_handler(void) { -#if 1 - panicf("TLB refill handler! [0x%x] [0x%x]", read_c0_badvaddr(), read_c0_epc()); -#else - __asm__ __volatile__( - "mfc0 k0, C0_BADVADDR\n" - "lui k1, pgdc\n" - "lw k1, pgdc>>16(k0)\n" - "srl k0, k0, 22\n" - "sll k0, k0, 2\n" - "addu k1, k1, k0\n" - "mfc0 k0, C0_CONTEXT\n" - "lw k1, 0(k1)\n" - "andi k0, k0, 0xFFC\n" - "addu k1, k1, k0\n" - "lw k0, 0(k1)\n" - "nop\n" - "mtc0 k0, C0_ENTRYLO0\n" - "mfc0 k1, C0_EPC\n" - "tlbwr\n" - "jr k1\n" - "rfe\n" - ); -#endif + panicf("TLB refill handler! [0x%x] [0x%lx]", read_c0_badvaddr(), read_c0_epc()); } +static void tlb_call_refill(void) +{ + asm("la $8, tlb_refill_handler \n" + "jr $8 \n"); +} + +extern int main(void); +extern void except_common_entry(void); + void system_main(void) { int i; @@ -657,7 +679,7 @@ void system_main(void) * 0x180 - Exception/Interrupt handler * 0x200 - Special Exception Interrupt handler (when IV is set in CP0_CAUSE) */ - memcpy((void *)A_K0BASE, (void *)&tlb_refill_handler, 0x20); + memcpy((void *)A_K0BASE, (void *)&tlb_call_refill, 0x20); memcpy((void *)(A_K0BASE + 0x100), (void *)&except_common_entry, 0x20); memcpy((void *)(A_K0BASE + 0x180), (void *)&except_common_entry, 0x20); memcpy((void *)(A_K0BASE + 0x200), (void *)&except_common_entry, 0x20); @@ -671,7 +693,7 @@ void system_main(void) for(i=0; i