diff options
author | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2009-01-21 20:58:33 +0000 |
---|---|---|
committer | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2009-01-21 20:58:33 +0000 |
commit | 29b136b82dda3b3170589df62120705b1b954652 (patch) | |
tree | 51dd27061fb7a2da2e2cc826bda1ec6dafb9e5b2 | |
parent | 868a4bdbc3f08a7c9d26a84bb67a5b3e083ffcec (diff) | |
download | rockbox-29b136b82dda3b3170589df62120705b1b954652.tar.gz rockbox-29b136b82dda3b3170589df62120705b1b954652.zip |
Onda VX747:
* Get USB working (it isn't good at writing support though)
* Clean up NAND & SD a bit
* Other comments/fixes
Ingenic Jz4740/MIPS:
* Split MMU from system
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19815 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/SOURCES | 1 | ||||
-rw-r--r-- | firmware/export/config-ondavx747.h | 20 | ||||
-rw-r--r-- | firmware/export/config-ondavx747p.h | 9 | ||||
-rw-r--r-- | firmware/export/config-ondavx767.h | 9 | ||||
-rw-r--r-- | firmware/export/jz4740.h | 72 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c | 105 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c | 36 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c | 2 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/onda_vx747/ata-sd-target.h | 19 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/onda_vx747/usb-target.h | 14 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/system-jz4740.c | 101 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/usb-jz4740.c | 138 | ||||
-rw-r--r-- | firmware/target/mips/mmu-mips.c | 125 | ||||
-rw-r--r-- | firmware/target/mips/mmu-mips.h | 28 |
14 files changed, 449 insertions, 230 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES index 3f558566f8..7169a669e8 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -408,6 +408,7 @@ common/memmove.c | |||
408 | common/memset.c | 408 | common/memset.c |
409 | common/memset16.c | 409 | common/memset16.c |
410 | common/strlen.c | 410 | common/strlen.c |
411 | target/mips/mmu-mips.c | ||
411 | #if CONFIG_CPU==JZ4732 | 412 | #if CONFIG_CPU==JZ4732 |
412 | target/mips/ingenic_jz47xx/crt0.S | 413 | target/mips/ingenic_jz47xx/crt0.S |
413 | #endif /* CONFIG_CPU == JZ4732 */ | 414 | #endif /* CONFIG_CPU == JZ4732 */ |
diff --git a/firmware/export/config-ondavx747.h b/firmware/export/config-ondavx747.h index 2fe0564e71..d4badf89cd 100644 --- a/firmware/export/config-ondavx747.h +++ b/firmware/export/config-ondavx747.h | |||
@@ -37,7 +37,7 @@ | |||
37 | //#define HAVE_HOTSWAP | 37 | //#define HAVE_HOTSWAP |
38 | 38 | ||
39 | //#define CONFIG_STORAGE (STORAGE_NAND | STORAGE_SD) | 39 | //#define CONFIG_STORAGE (STORAGE_NAND | STORAGE_SD) |
40 | #define CONFIG_STORAGE STORAGE_RAMDISK /* Multivolume currently handled at firmware/target/ level */ | 40 | #define CONFIG_STORAGE STORAGE_NAND /* Multivolume currently handled at firmware/target/ level */ |
41 | 41 | ||
42 | #define CONFIG_NAND NAND_CC | 42 | #define CONFIG_NAND NAND_CC |
43 | 43 | ||
@@ -144,7 +144,7 @@ | |||
144 | #define __BACKLIGHT_INIT | 144 | #define __BACKLIGHT_INIT |
145 | 145 | ||
146 | /* Offset ( in the firmware file's header ) to the file CRC */ | 146 | /* Offset ( in the firmware file's header ) to the file CRC */ |
147 | #define FIRMWARE_OFFSET_FILE_CRC 0 | 147 | #define FIRMWARE_OFFSET_FILE_CRC 0 |
148 | 148 | ||
149 | /* Offset ( in the firmware file's header ) to the real data */ | 149 | /* Offset ( in the firmware file's header ) to the real data */ |
150 | #define FIRMWARE_OFFSET_FILE_DATA 8 | 150 | #define FIRMWARE_OFFSET_FILE_DATA 8 |
@@ -153,12 +153,18 @@ | |||
153 | /* #define HAVE_ADJUSTABLE_CPU_FREQ */ | 153 | /* #define HAVE_ADJUSTABLE_CPU_FREQ */ |
154 | 154 | ||
155 | #define BOOTFILE_EXT "vx747" | 155 | #define BOOTFILE_EXT "vx747" |
156 | #define BOOTFILE "rockbox." BOOTFILE_EXT | 156 | #define BOOTFILE "rockbox." BOOTFILE_EXT |
157 | #define BOOTDIR "/.rockbox" | 157 | #define BOOTDIR "/.rockbox" |
158 | 158 | ||
159 | #define CONFIG_USBOTG USBOTG_JZ4740 | 159 | #define CONFIG_USBOTG USBOTG_JZ4740 |
160 | #define HAVE_USBSTACK | 160 | #define HAVE_USBSTACK |
161 | #define USB_VENDOR_ID 0x07C4 | 161 | #define USE_ROCKBOX_USB |
162 | #define USB_PRODUCT_ID 0xA4A5 | 162 | #define USB_VENDOR_ID 0x07C4 |
163 | #define USB_PRODUCT_ID 0xA4A5 | ||
164 | #define USB_NUM_ENDPOINTS 3 | ||
165 | /* This needs to be 2048 byte aligned, but USB_QHARRAY_ATTR should take care | ||
166 | * of that */ | ||
167 | #define USB_QHARRAY_ATTR __attribute__((section(".qharray"),nocommon,aligned(4))) | ||
168 | #define USB_DEVBSS_ATTR IBSS_ATTR | ||
163 | 169 | ||
164 | #endif | 170 | #endif |
diff --git a/firmware/export/config-ondavx747p.h b/firmware/export/config-ondavx747p.h index 5c4d3e7aea..2cd06d3323 100644 --- a/firmware/export/config-ondavx747p.h +++ b/firmware/export/config-ondavx747p.h | |||
@@ -158,7 +158,12 @@ | |||
158 | 158 | ||
159 | #define CONFIG_USBOTG USBOTG_JZ4740 | 159 | #define CONFIG_USBOTG USBOTG_JZ4740 |
160 | #define HAVE_USBSTACK | 160 | #define HAVE_USBSTACK |
161 | #define USB_VENDOR_ID 0x041e | 161 | #define USB_VENDOR_ID 0x07C4 |
162 | #define USB_PRODUCT_ID 0x4133 | 162 | #define USB_PRODUCT_ID 0xA4A5 |
163 | #define USB_NUM_ENDPOINTS 3 | ||
164 | /* This needs to be 2048 byte aligned, but USB_QHARRAY_ATTR should take care | ||
165 | * of that */ | ||
166 | #define USB_QHARRAY_ATTR __attribute__((section(".qharray"),nocommon,aligned(4))) | ||
167 | #define USB_DEVBSS_ATTR IBSS_ATTR | ||
163 | 168 | ||
164 | #endif | 169 | #endif |
diff --git a/firmware/export/config-ondavx767.h b/firmware/export/config-ondavx767.h index 7216ef0d35..cb44de9e6e 100644 --- a/firmware/export/config-ondavx767.h +++ b/firmware/export/config-ondavx767.h | |||
@@ -156,7 +156,12 @@ | |||
156 | 156 | ||
157 | #define CONFIG_USBOTG USBOTG_JZ4740 | 157 | #define CONFIG_USBOTG USBOTG_JZ4740 |
158 | #define HAVE_USBSTACK | 158 | #define HAVE_USBSTACK |
159 | #define USB_VENDOR_ID 0x041e | 159 | #define USB_VENDOR_ID 0x07C4 |
160 | #define USB_PRODUCT_ID 0x4133 | 160 | #define USB_PRODUCT_ID 0xA4A5 |
161 | #define USB_NUM_ENDPOINTS 3 | ||
162 | /* This needs to be 2048 byte aligned, but USB_QHARRAY_ATTR should take care | ||
163 | * of that */ | ||
164 | #define USB_QHARRAY_ATTR __attribute__((section(".qharray"),nocommon,aligned(4))) | ||
165 | #define USB_DEVBSS_ATTR IBSS_ATTR | ||
161 | 166 | ||
162 | #endif | 167 | #endif |
diff --git a/firmware/export/jz4740.h b/firmware/export/jz4740.h index 409d1d5a6a..aa31a229f9 100644 --- a/firmware/export/jz4740.h +++ b/firmware/export/jz4740.h | |||
@@ -2105,57 +2105,57 @@ | |||
2105 | *************************************************************************/ | 2105 | *************************************************************************/ |
2106 | 2106 | ||
2107 | #define SLCD_CFG (SLCD_BASE + 0xA0) /* SLCD Configure Register */ | 2107 | #define SLCD_CFG (SLCD_BASE + 0xA0) /* SLCD Configure Register */ |
2108 | #define SLCD_CTRL (SLCD_BASE + 0xA4) /* SLCD Control Register */ | 2108 | #define SLCD_CTRL (SLCD_BASE + 0xA4) /* SLCD Control Register */ |
2109 | #define SLCD_STATE (SLCD_BASE + 0xA8) /* SLCD Status Register */ | 2109 | #define SLCD_STATE (SLCD_BASE + 0xA8) /* SLCD Status Register */ |
2110 | #define SLCD_DATA (SLCD_BASE + 0xAC) /* SLCD Data Register */ | 2110 | #define SLCD_DATA (SLCD_BASE + 0xAC) /* SLCD Data Register */ |
2111 | #define SLCD_FIFO (SLCD_BASE + 0xB0) /* SLCD FIFO Register */ | 2111 | #define SLCD_FIFO (SLCD_BASE + 0xB0) /* SLCD FIFO Register */ |
2112 | 2112 | ||
2113 | #define REG_SLCD_CFG REG32(SLCD_CFG) | 2113 | #define REG_SLCD_CFG REG32(SLCD_CFG) |
2114 | #define REG_SLCD_CTRL REG8(SLCD_CTRL) | 2114 | #define REG_SLCD_CTRL REG8(SLCD_CTRL) |
2115 | #define REG_SLCD_STATE REG8(SLCD_STATE) | 2115 | #define REG_SLCD_STATE REG8(SLCD_STATE) |
2116 | #define REG_SLCD_DATA REG32(SLCD_DATA) | 2116 | #define REG_SLCD_DATA REG32(SLCD_DATA) |
2117 | #define REG_SLCD_FIFO REG32(SLCD_FIFO) | 2117 | #define REG_SLCD_FIFO REG32(SLCD_FIFO) |
2118 | 2118 | ||
2119 | /* SLCD Configure Register */ | 2119 | /* SLCD Configure Register */ |
2120 | #define SLCD_CFG_BURST_BIT 14 | 2120 | #define SLCD_CFG_BURST_BIT 14 |
2121 | #define SLCD_CFG_BURST_MASK (0x3 << SLCD_CFG_BURST_BIT) | 2121 | #define SLCD_CFG_BURST_MASK (0x3 << SLCD_CFG_BURST_BIT) |
2122 | #define SLCD_CFG_BURST_4_WORD (0 << SLCD_CFG_BURST_BIT) | 2122 | #define SLCD_CFG_BURST_4_WORD (0 << SLCD_CFG_BURST_BIT) |
2123 | #define SLCD_CFG_BURST_8_WORD (1 << SLCD_CFG_BURST_BIT) | 2123 | #define SLCD_CFG_BURST_8_WORD (1 << SLCD_CFG_BURST_BIT) |
2124 | #define SLCD_CFG_DWIDTH_BIT 10 | 2124 | #define SLCD_CFG_DWIDTH_BIT 10 |
2125 | #define SLCD_CFG_DWIDTH_MASK (0x7 << SLCD_CFG_DWIDTH_BIT) | 2125 | #define SLCD_CFG_DWIDTH_MASK (0x7 << SLCD_CFG_DWIDTH_BIT) |
2126 | #define SLCD_CFG_DWIDTH_18 (0 << SLCD_CFG_DWIDTH_BIT) | 2126 | #define SLCD_CFG_DWIDTH_18 (0 << SLCD_CFG_DWIDTH_BIT) |
2127 | #define SLCD_CFG_DWIDTH_16 (1 << SLCD_CFG_DWIDTH_BIT) | 2127 | #define SLCD_CFG_DWIDTH_16 (1 << SLCD_CFG_DWIDTH_BIT) |
2128 | #define SLCD_CFG_DWIDTH_8_x3 (2 << SLCD_CFG_DWIDTH_BIT) | 2128 | #define SLCD_CFG_DWIDTH_8_x3 (2 << SLCD_CFG_DWIDTH_BIT) |
2129 | #define SLCD_CFG_DWIDTH_8_x2 (3 << SLCD_CFG_DWIDTH_BIT) | 2129 | #define SLCD_CFG_DWIDTH_8_x2 (3 << SLCD_CFG_DWIDTH_BIT) |
2130 | #define SLCD_CFG_DWIDTH_8_x1 (4 << SLCD_CFG_DWIDTH_BIT) | 2130 | #define SLCD_CFG_DWIDTH_8_x1 (4 << SLCD_CFG_DWIDTH_BIT) |
2131 | #define SLCD_CFG_DWIDTH_9_x2 (7 << SLCD_CFG_DWIDTH_BIT) | 2131 | #define SLCD_CFG_DWIDTH_9_x2 (7 << SLCD_CFG_DWIDTH_BIT) |
2132 | #define SLCD_CFG_CWIDTH_BIT 8 | 2132 | #define SLCD_CFG_CWIDTH_BIT 8 |
2133 | #define SLCD_CFG_CWIDTH_MASK (0x3 << SLCD_CFG_CWIDTH_BIT) | 2133 | #define SLCD_CFG_CWIDTH_MASK (0x3 << SLCD_CFG_CWIDTH_BIT) |
2134 | #define SLCD_CFG_CWIDTH_16BIT (0 << SLCD_CFG_CWIDTH_BIT) | 2134 | #define SLCD_CFG_CWIDTH_16BIT (0 << SLCD_CFG_CWIDTH_BIT) |
2135 | #define SLCD_CFG_CWIDTH_8BIT (1 << SLCD_CFG_CWIDTH_BIT) | 2135 | #define SLCD_CFG_CWIDTH_8BIT (1 << SLCD_CFG_CWIDTH_BIT) |
2136 | #define SLCD_CFG_CWIDTH_18BIT (2 << SLCD_CFG_CWIDTH_BIT) | 2136 | #define SLCD_CFG_CWIDTH_18BIT (2 << SLCD_CFG_CWIDTH_BIT) |
2137 | #define SLCD_CFG_CS_ACTIVE_LOW (0 << 4) | 2137 | #define SLCD_CFG_CS_ACTIVE_LOW (0 << 4) |
2138 | #define SLCD_CFG_CS_ACTIVE_HIGH (1 << 4) | 2138 | #define SLCD_CFG_CS_ACTIVE_HIGH (1 << 4) |
2139 | #define SLCD_CFG_RS_CMD_LOW (0 << 3) | 2139 | #define SLCD_CFG_RS_CMD_LOW (0 << 3) |
2140 | #define SLCD_CFG_RS_CMD_HIGH (1 << 3) | 2140 | #define SLCD_CFG_RS_CMD_HIGH (1 << 3) |
2141 | #define SLCD_CFG_CLK_ACTIVE_FALLING (0 << 1) | 2141 | #define SLCD_CFG_CLK_ACTIVE_FALLING (0 << 1) |
2142 | #define SLCD_CFG_CLK_ACTIVE_RISING (1 << 1) | 2142 | #define SLCD_CFG_CLK_ACTIVE_RISING (1 << 1) |
2143 | #define SLCD_CFG_TYPE_PARALLEL (0 << 0) | 2143 | #define SLCD_CFG_TYPE_PARALLEL (0 << 0) |
2144 | #define SLCD_CFG_TYPE_SERIAL (1 << 0) | 2144 | #define SLCD_CFG_TYPE_SERIAL (1 << 0) |
2145 | 2145 | ||
2146 | /* SLCD Control Register */ | 2146 | /* SLCD Control Register */ |
2147 | #define SLCD_CTRL_DMA_EN (1 << 0) | 2147 | #define SLCD_CTRL_DMA_EN (1 << 0) |
2148 | 2148 | ||
2149 | /* SLCD Status Register */ | 2149 | /* SLCD Status Register */ |
2150 | #define SLCD_STATE_BUSY (1 << 0) | 2150 | #define SLCD_STATE_BUSY (1 << 0) |
2151 | 2151 | ||
2152 | /* SLCD Data Register */ | 2152 | /* SLCD Data Register */ |
2153 | #define SLCD_DATA_RS_DATA (0 << 31) | 2153 | #define SLCD_DATA_RS_DATA (0 << 31) |
2154 | #define SLCD_DATA_RS_COMMAND (1 << 31) | 2154 | #define SLCD_DATA_RS_COMMAND (1 << 31) |
2155 | 2155 | ||
2156 | /* SLCD FIFO Register */ | 2156 | /* SLCD FIFO Register */ |
2157 | #define SLCD_FIFO_RS_DATA (0 << 31) | 2157 | #define SLCD_FIFO_RS_DATA (0 << 31) |
2158 | #define SLCD_FIFO_RS_COMMAND (1 << 31) | 2158 | #define SLCD_FIFO_RS_COMMAND (1 << 31) |
2159 | 2159 | ||
2160 | 2160 | ||
2161 | /************************************************************************* | 2161 | /************************************************************************* |
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c index a4b4a86a55..4a36b069f9 100644 --- a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c | |||
@@ -22,11 +22,14 @@ | |||
22 | #include "config.h" | 22 | #include "config.h" |
23 | #include "jz4740.h" | 23 | #include "jz4740.h" |
24 | #include "ata.h" | 24 | #include "ata.h" |
25 | #include "ata-nand-target.h" | 25 | //#include "ata-nand-target.h" /* TODO */ |
26 | #include "nand_id.h" | 26 | #include "nand_id.h" |
27 | #include "system.h" | 27 | #include "system.h" |
28 | #include "panic.h" | 28 | #include "panic.h" |
29 | #include "kernel.h" | 29 | #include "kernel.h" |
30 | #include "storage.h" | ||
31 | #include "buffer.h" | ||
32 | #include "string.h" | ||
30 | 33 | ||
31 | /* | 34 | /* |
32 | * Standard NAND flash commands | 35 | * Standard NAND flash commands |
@@ -65,8 +68,8 @@ struct nand_param | |||
65 | unsigned int bus_width; /* data bus width: 8-bit/16-bit */ | 68 | unsigned int bus_width; /* data bus width: 8-bit/16-bit */ |
66 | unsigned int row_cycle; /* row address cycles: 2/3 */ | 69 | unsigned int row_cycle; /* row address cycles: 2/3 */ |
67 | unsigned int page_size; /* page size in bytes: 512/2048 */ | 70 | unsigned int page_size; /* page size in bytes: 512/2048 */ |
68 | unsigned int oob_size; /* oob size in bytes: 16/64 */ | 71 | unsigned int oob_size; /* oob size in bytes: 16/64 */ |
69 | unsigned int page_per_block; /* pages per block: 32/64/128 */ | 72 | unsigned int page_per_block; /* pages per block: 32/64/128 */ |
70 | }; | 73 | }; |
71 | 74 | ||
72 | /* | 75 | /* |
@@ -106,6 +109,8 @@ struct nand_param | |||
106 | static struct nand_info* chip_info = NULL; | 109 | static struct nand_info* chip_info = NULL; |
107 | static struct nand_param internal_param; | 110 | static struct nand_param internal_param; |
108 | static struct mutex nand_mtx; | 111 | static struct mutex nand_mtx; |
112 | static struct wakeup nand_wkup; | ||
113 | static unsigned char temp_page[4096]; /* Max page size */ | ||
109 | 114 | ||
110 | static inline void jz_nand_wait_ready(void) | 115 | static inline void jz_nand_wait_ready(void) |
111 | { | 116 | { |
@@ -141,7 +146,7 @@ static void jz_nand_write_dma(void *source, unsigned int len, int bw) | |||
141 | 146 | ||
142 | dma_enable(); | 147 | dma_enable(); |
143 | 148 | ||
144 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = 0; | 149 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = DMAC_DCCSR_NDES; |
145 | REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)source); | 150 | REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)source); |
146 | REG_DMAC_DTAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)NAND_DATAPORT); | 151 | REG_DMAC_DTAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)NAND_DATAPORT); |
147 | REG_DMAC_DTCR(DMA_NAND_CHANNEL) = len / 16; | 152 | REG_DMAC_DTCR(DMA_NAND_CHANNEL) = len / 16; |
@@ -149,9 +154,14 @@ static void jz_nand_write_dma(void *source, unsigned int len, int bw) | |||
149 | REG_DMAC_DCMD(DMA_NAND_CHANNEL) = (DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DS_16BYTE | | 154 | REG_DMAC_DCMD(DMA_NAND_CHANNEL) = (DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DS_16BYTE | |
150 | (bw == 8 ? DMAC_DCMD_DWDH_8 : DMAC_DCMD_DWDH_16)); | 155 | (bw == 8 ? DMAC_DCMD_DWDH_8 : DMAC_DCMD_DWDH_16)); |
151 | 156 | ||
152 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = (DMAC_DCCSR_EN | DMAC_DCCSR_NDES); | 157 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */ |
158 | #if 1 | ||
153 | while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) ) | 159 | while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) ) |
154 | yield(); | 160 | yield(); |
161 | #else | ||
162 | REG_DMAC_DCMD(DMA_NAND_CHANNEL) |= DMAC_DCMD_TIE; /* Enable DMA interrupt */ | ||
163 | wakeup_wait(&nand_wkup, TIMEOUT_BLOCK); | ||
164 | #endif | ||
155 | 165 | ||
156 | dma_disable(); | 166 | dma_disable(); |
157 | 167 | ||
@@ -167,22 +177,44 @@ static void jz_nand_read_dma(void *target, unsigned int len, int bw) | |||
167 | 177 | ||
168 | dma_enable(); | 178 | dma_enable(); |
169 | 179 | ||
170 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = 0; | 180 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = DMAC_DCCSR_NDES; |
171 | REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)NAND_DATAPORT); | 181 | REG_DMAC_DSAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)NAND_DATAPORT); |
172 | REG_DMAC_DTAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)target); | 182 | REG_DMAC_DTAR(DMA_NAND_CHANNEL) = PHYSADDR((unsigned long)target); |
173 | REG_DMAC_DTCR(DMA_NAND_CHANNEL) = len / 4; | 183 | REG_DMAC_DTCR(DMA_NAND_CHANNEL) = len / 4; |
174 | REG_DMAC_DRSR(DMA_NAND_CHANNEL) = DMAC_DRSR_RS_AUTO; | 184 | REG_DMAC_DRSR(DMA_NAND_CHANNEL) = DMAC_DRSR_RS_AUTO; |
175 | REG_DMAC_DCMD(DMA_NAND_CHANNEL) = (DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT | | 185 | REG_DMAC_DCMD(DMA_NAND_CHANNEL) = (DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT | |
176 | (bw == 8 ? DMAC_DCMD_SWDH_8 : DMAC_DCMD_SWDH_16)); | 186 | (bw == 8 ? DMAC_DCMD_SWDH_8 : DMAC_DCMD_SWDH_16)); |
177 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = (DMAC_DCCSR_EN | DMAC_DCCSR_NDES); | 187 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */ |
188 | #if 1 | ||
178 | while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) ) | 189 | while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) ) |
179 | yield(); | 190 | yield(); |
191 | #else | ||
192 | REG_DMAC_DCMD(DMA_NAND_CHANNEL) |= DMAC_DCMD_TIE; /* Enable DMA interrupt */ | ||
193 | wakeup_wait(&nand_wkup, TIMEOUT_BLOCK); | ||
194 | #endif | ||
180 | 195 | ||
181 | dma_disable(); | 196 | dma_disable(); |
182 | 197 | ||
183 | mutex_unlock(&nand_mtx); | 198 | mutex_unlock(&nand_mtx); |
184 | } | 199 | } |
185 | 200 | ||
201 | void DMA_CALLBACK(DMA_NAND_CHANNEL)(void) | ||
202 | { | ||
203 | if (REG_DMAC_DCCSR(DMA_NAND_CHANNEL) & DMAC_DCCSR_HLT) | ||
204 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_HLT; | ||
205 | |||
206 | if (REG_DMAC_DCCSR(DMA_NAND_CHANNEL) & DMAC_DCCSR_AR) | ||
207 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_AR; | ||
208 | |||
209 | if (REG_DMAC_DCCSR(DMA_NAND_CHANNEL) & DMAC_DCCSR_CT) | ||
210 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_CT; | ||
211 | |||
212 | if (REG_DMAC_DCCSR(DMA_NAND_CHANNEL) & DMAC_DCCSR_TT) | ||
213 | REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_TT; | ||
214 | |||
215 | wakeup_signal(&nand_wkup); | ||
216 | } | ||
217 | |||
186 | static inline void jz_nand_read_buf(void *buf, int count, int bw) | 218 | static inline void jz_nand_read_buf(void *buf, int count, int bw) |
187 | { | 219 | { |
188 | if (bw == 8) | 220 | if (bw == 8) |
@@ -368,6 +400,7 @@ static int jz_nand_read_page(int block, int page, unsigned char *dst) | |||
368 | { | 400 | { |
369 | /* Uncorrectable error occurred */ | 401 | /* Uncorrectable error occurred */ |
370 | panicf("Uncorrectable ECC error at NAND page 0x%x block 0x%x", page, block); | 402 | panicf("Uncorrectable ECC error at NAND page 0x%x block 0x%x", page, block); |
403 | return -1; | ||
371 | } | 404 | } |
372 | else | 405 | else |
373 | { | 406 | { |
@@ -451,16 +484,9 @@ static int jz_nand_init(void) | |||
451 | internal_param.oob_size = chip_info->page_size/32; | 484 | internal_param.oob_size = chip_info->page_size/32; |
452 | internal_param.page_per_block = chip_info->pages_per_block; | 485 | internal_param.page_per_block = chip_info->pages_per_block; |
453 | 486 | ||
454 | mutex_init(&nand_mtx); | ||
455 | |||
456 | return 0; | 487 | return 0; |
457 | } | 488 | } |
458 | 489 | ||
459 | void jz_nand_read(int block, int page, unsigned char *buf) | ||
460 | { | ||
461 | jz_nand_read_page(block, page, buf); | ||
462 | } | ||
463 | |||
464 | static bool inited = false; | 490 | static bool inited = false; |
465 | int nand_init(void) | 491 | int nand_init(void) |
466 | { | 492 | { |
@@ -469,23 +495,41 @@ int nand_init(void) | |||
469 | if(!inited) | 495 | if(!inited) |
470 | { | 496 | { |
471 | res = jz_nand_init(); | 497 | res = jz_nand_init(); |
498 | mutex_init(&nand_mtx); | ||
499 | wakeup_init(&nand_wkup); | ||
500 | |||
472 | inited = true; | 501 | inited = true; |
473 | } | 502 | } |
474 | 503 | ||
475 | return res; | 504 | return res; |
476 | } | 505 | } |
477 | 506 | ||
478 | /* TODO */ | 507 | int nand_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf) |
479 | int nand_read_sectors(unsigned long start, int count, void* buf) | ||
480 | { | 508 | { |
481 | (void)start; | 509 | int i, ret = 0; |
482 | (void)count; | 510 | |
483 | (void)buf; | 511 | start *= 512; |
484 | return -1; | 512 | count *= 512; |
513 | |||
514 | if(count <= chip_info->page_size) | ||
515 | { | ||
516 | ret = jz_nand_read_page(start % (chip_info->page_size * chip_info->pages_per_block), start % chip_info->page_size, temp_page); | ||
517 | memcpy(buf, temp_page, count); | ||
518 | return ret; | ||
519 | } | ||
520 | else | ||
521 | { | ||
522 | for(i=0; i<count && ret == 0; i+=chip_info->page_size) | ||
523 | { | ||
524 | ret = jz_nand_read_page((start+i) % (chip_info->page_size * chip_info->pages_per_block), (start+i) % chip_info->page_size, temp_page); | ||
525 | memcpy(buf+i, temp_page, (count-i < chip_info->page_size ? count-i : chip_info->page_size)); | ||
526 | } | ||
527 | return ret; | ||
528 | } | ||
485 | } | 529 | } |
486 | 530 | ||
487 | /* TODO */ | 531 | /* TODO */ |
488 | int nand_write_sectors(unsigned long start, int count, const void* buf) | 532 | int nand_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const void* buf) |
489 | { | 533 | { |
490 | (void)start; | 534 | (void)start; |
491 | (void)count; | 535 | (void)count; |
@@ -526,3 +570,20 @@ void nand_enable(bool on) | |||
526 | /* null - flash controller is enabled/disabled as needed. */ | 570 | /* null - flash controller is enabled/disabled as needed. */ |
527 | (void)on; | 571 | (void)on; |
528 | } | 572 | } |
573 | |||
574 | #ifdef STORAGE_GET_INFO | ||
575 | void nand_get_info(IF_MV2(int drive,) struct storage_info *info) | ||
576 | { | ||
577 | (void)drive; | ||
578 | /* firmware version */ | ||
579 | info->revision="0.00"; | ||
580 | |||
581 | info->vendor="Rockbox"; | ||
582 | info->product="NAND Storage"; | ||
583 | |||
584 | /* blocks count */ | ||
585 | /* TODO: proper amount of sectors! */ | ||
586 | info->num_sectors = (chip_info->page_size / 512) * chip_info->pages_per_block * chip_info->blocks_per_bank; | ||
587 | info->sector_size = 512; | ||
588 | } | ||
589 | #endif | ||
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c index 22e274b4d1..3bb9a27007 100644 --- a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c | |||
@@ -23,31 +23,20 @@ | |||
23 | #include "jz4740.h" | 23 | #include "jz4740.h" |
24 | #include "ata.h" | 24 | #include "ata.h" |
25 | #include "ata-sd-target.h" | 25 | #include "ata-sd-target.h" |
26 | #include "logf.h" | ||
26 | #include "sd.h" | 27 | #include "sd.h" |
27 | #include "system.h" | 28 | #include "system.h" |
28 | #include "kernel.h" | 29 | #include "kernel.h" |
29 | #include "panic.h" | 30 | #include "panic.h" |
30 | #include "debug.h" | 31 | #include "debug.h" |
32 | #include "storage.h" | ||
31 | 33 | ||
32 | static struct wakeup sd_wakeup; | 34 | static struct wakeup sd_wakeup; |
33 | 35 | ||
34 | //#define MMC_DMA_ENABLE | 36 | //#define MMC_DMA_ENABLE |
35 | #define MMC_DMA_INTERRUPT 0 | 37 | #define MMC_DMA_INTERRUPT 0 |
36 | 38 | ||
37 | //#define DEBUG(x...) DEBUGF(x); | 39 | #define DEBUG(x...) logf(x); |
38 | #define DEBUG(x...) printf(x); | ||
39 | |||
40 | #ifdef MMC_POWER_PIN | ||
41 | #define MMC_POWER_OFF() \ | ||
42 | do { \ | ||
43 | __gpio_set_pin(MMC_POWER_PIN); \ | ||
44 | } while (0) | ||
45 | |||
46 | #define MMC_POWER_ON() \ | ||
47 | do { \ | ||
48 | __gpio_clear_pin(MMC_POWER_PIN); \ | ||
49 | } while (0) | ||
50 | #endif | ||
51 | 40 | ||
52 | #ifdef MMC_CD_PIN | 41 | #ifdef MMC_CD_PIN |
53 | #define MMC_INSERT_STATUS() __gpio_get_pin(MMC_CD_PIN) | 42 | #define MMC_INSERT_STATUS() __gpio_get_pin(MMC_CD_PIN) |
@@ -1088,7 +1077,7 @@ static void mmc_send_cmd(struct mmc_request *request, int cmd, unsigned int arg, | |||
1088 | request->block_len = block_len; | 1077 | request->block_len = block_len; |
1089 | request->buffer = buffer; | 1078 | request->buffer = buffer; |
1090 | request->cnt = nob * block_len; | 1079 | request->cnt = nob * block_len; |
1091 | printf("mmc_send_cmd: command = %d",cmd); | 1080 | logf("mmc_send_cmd: command = %d",cmd); |
1092 | jz_mmc_exec_cmd(request); | 1081 | jz_mmc_exec_cmd(request); |
1093 | } | 1082 | } |
1094 | 1083 | ||
@@ -1154,3 +1143,20 @@ int _sd_write_sectors(unsigned long start, int count, const void* buf) | |||
1154 | (void)buf; | 1143 | (void)buf; |
1155 | return -1; | 1144 | return -1; |
1156 | } | 1145 | } |
1146 | |||
1147 | #ifdef STORAGE_GET_INFO | ||
1148 | void sd_get_info(IF_MV2(int drive,) struct storage_info *info) | ||
1149 | { | ||
1150 | (void)drive; | ||
1151 | /* firmware version */ | ||
1152 | info->revision="0.00"; | ||
1153 | |||
1154 | info->vendor="Rockbox"; | ||
1155 | info->product="SD Storage"; | ||
1156 | |||
1157 | /* blocks count */ | ||
1158 | /* TODO: proper amount of sectors! */ | ||
1159 | info->num_sectors = 0; | ||
1160 | info->sector_size = 512; | ||
1161 | } | ||
1162 | #endif | ||
diff --git a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c index 8112c21147..cc2c84c6b4 100644 --- a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c | |||
@@ -103,7 +103,7 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
103 | REG_DMAC_DCCSR(DMA_LCD_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */ | 103 | REG_DMAC_DCCSR(DMA_LCD_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */ |
104 | REG_DMAC_DCMD(DMA_LCD_CHANNEL) |= DMAC_DCMD_TIE; /* Enable DMA interrupt */ | 104 | REG_DMAC_DCMD(DMA_LCD_CHANNEL) |= DMAC_DCMD_TIE; /* Enable DMA interrupt */ |
105 | 105 | ||
106 | wakeup_wait(&lcd_wkup, TIMEOUT_BLOCK); | 106 | wakeup_wait(&lcd_wkup, TIMEOUT_BLOCK); /* Sleeping in lcd_update() should be safe */ |
107 | 107 | ||
108 | REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */ | 108 | REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */ |
109 | 109 | ||
diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/ata-sd-target.h b/firmware/target/mips/ingenic_jz47xx/onda_vx747/ata-sd-target.h index cc6bd8a773..ba324c1dcb 100644 --- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/ata-sd-target.h +++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/ata-sd-target.h | |||
@@ -39,13 +39,28 @@ int _sd_write_sectors(unsigned long start, int count, const void* buf); | |||
39 | int _sd_init(void); | 39 | int _sd_init(void); |
40 | 40 | ||
41 | #define MMC_CD_PIN (29 + 1 * 32) /* Pin to check card insertion */ | 41 | #define MMC_CD_PIN (29 + 1 * 32) /* Pin to check card insertion */ |
42 | //#define MMC_POWER_PIN (30 + 1 * 32) /* Pin to enable/disable card power */ | 42 | //#define MMC_POWER_PIN (22 + 2 * 32) /* Pin to enable/disable card power */ |
43 | //#define MMC_PW_PIN (14 + 3 * 32) /* Pin to check protect card */ | 43 | |
44 | #ifdef MMC_POWER_PIN | ||
45 | #define MMC_POWER_OFF() \ | ||
46 | do { \ | ||
47 | __gpio_clear_pin(MMC_POWER_PIN); \ | ||
48 | } while (0) | ||
49 | |||
50 | #define MMC_POWER_ON() \ | ||
51 | do { \ | ||
52 | __gpio_set_pin(MMC_POWER_PIN); \ | ||
53 | } while (0) | ||
54 | #endif | ||
44 | 55 | ||
45 | static inline void mmc_init_gpio(void) | 56 | static inline void mmc_init_gpio(void) |
46 | { | 57 | { |
47 | __gpio_as_msc(); | 58 | __gpio_as_msc(); |
48 | __gpio_as_input(MMC_CD_PIN); | 59 | __gpio_as_input(MMC_CD_PIN); |
60 | #ifdef MMC_POWER_PIN | ||
61 | __gpio_as_func0(MMC_POWER_PIN); | ||
62 | __gpio_as_output(MMC_POWER_PIN); | ||
63 | #endif | ||
49 | __gpio_enable_pull(32*3+29); | 64 | __gpio_enable_pull(32*3+29); |
50 | __gpio_enable_pull(32*3+10); | 65 | __gpio_enable_pull(32*3+10); |
51 | __gpio_enable_pull(32*3+11); | 66 | __gpio_enable_pull(32*3+11); |
diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/usb-target.h b/firmware/target/mips/ingenic_jz47xx/onda_vx747/usb-target.h index 09b563fd14..fbb14b7ac4 100644 --- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/usb-target.h +++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/usb-target.h | |||
@@ -26,17 +26,19 @@ | |||
26 | 26 | ||
27 | #define GPIO_UDC_DETE (32 * 3 + 28) | 27 | #define GPIO_UDC_DETE (32 * 3 + 28) |
28 | #define IRQ_GPIO_UDC_DETE (IRQ_GPIO_0 + GPIO_UDC_DETE) | 28 | #define IRQ_GPIO_UDC_DETE (IRQ_GPIO_0 + GPIO_UDC_DETE) |
29 | #define USB_GPIO_IRQ GPIO124 | ||
29 | 30 | ||
30 | #define USB_INIT_GPIO() \ | 31 | #define USB_INIT_GPIO() \ |
31 | { \ | 32 | { \ |
32 | REG_GPIO_PXFUNS(3) = 0x10000000; \ | 33 | REG_GPIO_PXPES(3) = 0x10000000; \ |
33 | REG_GPIO_PXSELS(3) = 0x10000000; \ | 34 | __gpio_as_irq_rise_edge(GPIO_UDC_DETE); \ |
34 | REG_GPIO_PXPES(3) = 0x10000000; \ | ||
35 | __gpio_as_input(GPIO_UDC_DETE); \ | ||
36 | } | 35 | } |
37 | 36 | ||
38 | #define USB_DRV_CONNECTED() (__gpio_get_pin(GPIO_UDC_DETE) == 1) | 37 | #define USB_DRV_CONNECTED() (__gpio_get_pin(GPIO_UDC_DETE) == 1) |
39 | 38 | ||
39 | /* Connect by events, not by tick polling */ | ||
40 | #define USB_STATUS_BY_EVENT | ||
41 | |||
40 | int usb_detect(void); | 42 | int usb_detect(void); |
41 | void usb_init_device(void); | 43 | void usb_init_device(void); |
42 | bool usb_drv_connected(void); | 44 | bool usb_drv_connected(void); |
diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c index 033b42214b..9c7f83530f 100644 --- a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "jz4740.h" | 23 | #include "jz4740.h" |
24 | #include "mips.h" | 24 | #include "mips.h" |
25 | #include "mipsregs.h" | 25 | #include "mipsregs.h" |
26 | #include "mmu-mips.h" | ||
26 | #include "panic.h" | 27 | #include "panic.h" |
27 | #include "system.h" | 28 | #include "system.h" |
28 | #include "string.h" | 29 | #include "string.h" |
@@ -524,106 +525,6 @@ void dma_cache_wback_inv(unsigned long addr, unsigned long size) | |||
524 | } | 525 | } |
525 | } | 526 | } |
526 | 527 | ||
527 | #define BARRIER \ | ||
528 | __asm__ __volatile__( \ | ||
529 | " .set noreorder \n" \ | ||
530 | " nop \n" \ | ||
531 | " nop \n" \ | ||
532 | " nop \n" \ | ||
533 | " nop \n" \ | ||
534 | " nop \n" \ | ||
535 | " nop \n" \ | ||
536 | " .set reorder \n"); | ||
537 | |||
538 | #define DEFAULT_PAGE_SHIFT PL_4K | ||
539 | #define DEFAULT_PAGE_MASK PM_4K | ||
540 | #define UNIQUE_ENTRYHI(idx, ps) (A_K0BASE + ((idx) << (ps + 1))) | ||
541 | #define ASID_MASK M_EntryHiASID | ||
542 | #define VPN2_SHIFT S_EntryHiVPN2 | ||
543 | #define PFN_SHIFT S_EntryLoPFN | ||
544 | #define PFN_MASK 0xffffff | ||
545 | static void local_flush_tlb_all(void) | ||
546 | { | ||
547 | unsigned long old_ctx; | ||
548 | int entry; | ||
549 | unsigned int old_irq = disable_irq_save(); | ||
550 | |||
551 | /* Save old context and create impossible VPN2 value */ | ||
552 | old_ctx = read_c0_entryhi(); | ||
553 | write_c0_entrylo0(0); | ||
554 | write_c0_entrylo1(0); | ||
555 | BARRIER; | ||
556 | |||
557 | /* Blast 'em all away. */ | ||
558 | for(entry = 0; entry < 32; entry++) | ||
559 | { | ||
560 | /* Make sure all entries differ. */ | ||
561 | write_c0_entryhi(UNIQUE_ENTRYHI(entry, DEFAULT_PAGE_SHIFT)); | ||
562 | write_c0_index(entry); | ||
563 | BARRIER; | ||
564 | tlb_write_indexed(); | ||
565 | } | ||
566 | BARRIER; | ||
567 | write_c0_entryhi(old_ctx); | ||
568 | |||
569 | restore_irq(old_irq); | ||
570 | } | ||
571 | |||
572 | static void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | ||
573 | unsigned long entryhi, unsigned long pagemask) | ||
574 | { | ||
575 | unsigned long wired; | ||
576 | unsigned long old_pagemask; | ||
577 | unsigned long old_ctx; | ||
578 | unsigned int old_irq = disable_irq_save(); | ||
579 | |||
580 | old_ctx = read_c0_entryhi() & ASID_MASK; | ||
581 | old_pagemask = read_c0_pagemask(); | ||
582 | wired = read_c0_wired(); | ||
583 | write_c0_wired(wired + 1); | ||
584 | write_c0_index(wired); | ||
585 | BARRIER; | ||
586 | write_c0_pagemask(pagemask); | ||
587 | write_c0_entryhi(entryhi); | ||
588 | write_c0_entrylo0(entrylo0); | ||
589 | write_c0_entrylo1(entrylo1); | ||
590 | BARRIER; | ||
591 | tlb_write_indexed(); | ||
592 | BARRIER; | ||
593 | |||
594 | write_c0_entryhi(old_ctx); | ||
595 | BARRIER; | ||
596 | write_c0_pagemask(old_pagemask); | ||
597 | local_flush_tlb_all(); | ||
598 | restore_irq(old_irq); | ||
599 | } | ||
600 | |||
601 | static void map_address(unsigned long virtual, unsigned long physical, unsigned long length) | ||
602 | { | ||
603 | unsigned long entry0 = (physical & PFN_MASK) << PFN_SHIFT; | ||
604 | unsigned long entry1 = ((physical+length) & PFN_MASK) << PFN_SHIFT; | ||
605 | unsigned long entryhi = virtual & ~VPN2_SHIFT; | ||
606 | |||
607 | entry0 |= (M_EntryLoG | M_EntryLoV | (K_CacheAttrC << S_EntryLoC) ); | ||
608 | entry1 |= (M_EntryLoG | M_EntryLoV | (K_CacheAttrC << S_EntryLoC) ); | ||
609 | |||
610 | add_wired_entry(entry0, entry1, entryhi, DEFAULT_PAGE_MASK); | ||
611 | } | ||
612 | |||
613 | |||
614 | static void tlb_init(void) | ||
615 | { | ||
616 | write_c0_pagemask(DEFAULT_PAGE_MASK); | ||
617 | write_c0_wired(0); | ||
618 | write_c0_framemask(0); | ||
619 | |||
620 | local_flush_tlb_all(); | ||
621 | /* | ||
622 | map_address(0x80000000, 0x80000000, 0x4000); | ||
623 | map_address(0x80004000, 0x80004000, MEM * 0x100000); | ||
624 | */ | ||
625 | } | ||
626 | |||
627 | void tlb_refill_handler(void) | 528 | void tlb_refill_handler(void) |
628 | { | 529 | { |
629 | panicf("TLB refill handler at 0x%08lx! [0x%x]", read_c0_epc(), read_c0_badvaddr()); | 530 | panicf("TLB refill handler at 0x%08lx! [0x%x]", read_c0_epc(), read_c0_badvaddr()); |
diff --git a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c index 0916a9414a..7bd0ba4ae5 100644 --- a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c | |||
@@ -60,9 +60,11 @@ struct usb_endpoint | |||
60 | unsigned int sent; | 60 | unsigned int sent; |
61 | unsigned int received; | 61 | unsigned int received; |
62 | }; | 62 | }; |
63 | bool busy; | ||
63 | 64 | ||
64 | const enum ep_type type; | 65 | const enum ep_type type; |
65 | const bool use_dma; | 66 | const bool use_dma; |
67 | bool wait; | ||
66 | 68 | ||
67 | const unsigned int fifo_addr; | 69 | const unsigned int fifo_addr; |
68 | unsigned short fifo_size; | 70 | unsigned short fifo_size; |
@@ -71,13 +73,14 @@ struct usb_endpoint | |||
71 | static unsigned char ep0_rx_buf[64]; | 73 | static unsigned char ep0_rx_buf[64]; |
72 | static unsigned char ep0state = USB_EP0_IDLE; | 74 | static unsigned char ep0state = USB_EP0_IDLE; |
73 | static struct usb_endpoint endpoints[] = | 75 | static struct usb_endpoint endpoints[] = |
74 | {/* buf length sent type use_dma fifo_addr fifo_size */ | 76 | {/* buf length sent busy type use_dma wait fifo_addr fifo_size */ |
75 | {&ep0_rx_buf, 0, {0}, ep_control, false, USB_FIFO_EP0, 64 }, | 77 | {&ep0_rx_buf, 0, {0}, false, ep_control, false, false, USB_FIFO_EP0, 64 }, |
76 | {NULL, 0, {0}, ep_control, false, USB_FIFO_EP0, 64 }, | 78 | {NULL, 0, {0}, false, ep_control, false, false, USB_FIFO_EP0, 64 }, |
77 | {NULL, 0, {0}, ep_bulk, false, USB_FIFO_EP1, 512}, | 79 | {NULL, 0, {0}, false, ep_bulk, false, false, USB_FIFO_EP1, 512}, |
78 | {NULL, 0, {0}, ep_bulk, false, USB_FIFO_EP1, 512}, | 80 | {NULL, 0, {0}, false, ep_bulk, false, false, USB_FIFO_EP1, 512}, |
79 | {NULL, 0, {0}, ep_interrupt, false, USB_FIFO_EP2, 64 } | 81 | {NULL, 0, {0}, false, ep_interrupt, false, false, USB_FIFO_EP2, 64 } |
80 | }; | 82 | }; |
83 | static struct wakeup ep_wkup[TOTAL_EP()]; | ||
81 | 84 | ||
82 | static inline void select_endpoint(int ep) | 85 | static inline void select_endpoint(int ep) |
83 | { | 86 | { |
@@ -167,13 +170,14 @@ static void EP0_send(void) | |||
167 | struct usb_endpoint* ep = &endpoints[1]; | 170 | struct usb_endpoint* ep = &endpoints[1]; |
168 | unsigned int length; | 171 | unsigned int length; |
169 | unsigned char csr0; | 172 | unsigned char csr0; |
170 | 173 | ||
171 | select_endpoint(0); | 174 | select_endpoint(0); |
172 | csr0 = REG_USB_REG_CSR0; | 175 | csr0 = REG_USB_REG_CSR0; |
173 | 176 | ||
174 | if(ep->length == 0) | 177 | if(ep->length == 0) |
175 | { | 178 | { |
176 | REG_USB_REG_CSR0 = (csr0 | USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND); | 179 | //REG_USB_REG_CSR0 = (csr0 | USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND); |
180 | REG_USB_REG_CSR0 = (csr0 | USB_CSR0_SVDOUTPKTRDY); | ||
177 | return; | 181 | return; |
178 | } | 182 | } |
179 | 183 | ||
@@ -189,6 +193,8 @@ static void EP0_send(void) | |||
189 | { | 193 | { |
190 | REG_USB_REG_CSR0 = (csr0 | USB_CSR0_INPKTRDY | USB_CSR0_DATAEND); /* Set data end! */ | 194 | REG_USB_REG_CSR0 = (csr0 | USB_CSR0_INPKTRDY | USB_CSR0_DATAEND); /* Set data end! */ |
191 | ep0state = USB_EP0_IDLE; | 195 | ep0state = USB_EP0_IDLE; |
196 | if(ep->wait) | ||
197 | wakeup_signal(&ep_wkup[1]); | ||
192 | } | 198 | } |
193 | else | 199 | else |
194 | REG_USB_REG_CSR0 = (csr0 | USB_CSR0_INPKTRDY); | 200 | REG_USB_REG_CSR0 = (csr0 | USB_CSR0_INPKTRDY); |
@@ -199,7 +205,7 @@ static void EP0_handler(void) | |||
199 | logf("EP0_handler"); | 205 | logf("EP0_handler"); |
200 | 206 | ||
201 | unsigned char csr0; | 207 | unsigned char csr0; |
202 | 208 | ||
203 | /* Read CSR0 */ | 209 | /* Read CSR0 */ |
204 | select_endpoint(0); | 210 | select_endpoint(0); |
205 | csr0 = REG_USB_REG_CSR0; | 211 | csr0 = REG_USB_REG_CSR0; |
@@ -229,11 +235,13 @@ static void EP0_handler(void) | |||
229 | /* Call relevant routines for endpoint 0 state */ | 235 | /* Call relevant routines for endpoint 0 state */ |
230 | if(ep0state == USB_EP0_IDLE) | 236 | if(ep0state == USB_EP0_IDLE) |
231 | { | 237 | { |
232 | if(csr0 & USB_CSR0_OUTPKTRDY) /* There is data in the fifo */ | 238 | if(csr0 & USB_CSR0_OUTPKTRDY) /* There is a packet in the fifo */ |
233 | { | 239 | { |
234 | readFIFO(&endpoints[0], REG_USB_REG_COUNT0); | 240 | readFIFO(&endpoints[0], REG_USB_REG_COUNT0); |
235 | REG_USB_REG_CSR0 = csr0 | USB_CSR0_SVDOUTPKTRDY; /* clear OUTPKTRDY bit */ | 241 | REG_USB_REG_CSR0 = csr0 | USB_CSR0_SVDOUTPKTRDY; /* clear OUTPKTRDY bit */ |
236 | usb_core_control_request((struct usb_ctrlrequest*)endpoints[0].buf); | 242 | usb_core_control_request((struct usb_ctrlrequest*)endpoints[0].buf); |
243 | if(endpoints[0].wait) | ||
244 | wakeup_signal(&ep_wkup[0]); | ||
237 | } | 245 | } |
238 | } | 246 | } |
239 | else if(ep0state == USB_EP0_TX) | 247 | else if(ep0state == USB_EP0_TX) |
@@ -249,7 +257,7 @@ static void EPIN_handler(unsigned int endpoint) | |||
249 | csr = REG_USB_REG_INCSR; | 257 | csr = REG_USB_REG_INCSR; |
250 | logf("EPIN_handler(%d): 0x%x", endpoint, csr); | 258 | logf("EPIN_handler(%d): 0x%x", endpoint, csr); |
251 | 259 | ||
252 | if(ep->buf == NULL || ep->length == 0) | 260 | if(!ep->busy) |
253 | return; | 261 | return; |
254 | 262 | ||
255 | if(csr & USB_INCSR_SENTSTALL) | 263 | if(csr & USB_INCSR_SENTSTALL) |
@@ -258,15 +266,19 @@ static void EPIN_handler(unsigned int endpoint) | |||
258 | return; | 266 | return; |
259 | } | 267 | } |
260 | 268 | ||
269 | #if 0 | ||
261 | if(ep->use_dma == true) | 270 | if(ep->use_dma == true) |
262 | return; | 271 | return; |
272 | #endif | ||
263 | 273 | ||
264 | if(csr & USB_INCSR_FFNOTEMPT) | 274 | if(csr & USB_INCSR_FFNOTEMPT) |
265 | { | 275 | { |
266 | logf("FIFO is not empty!"); | 276 | logf("FIFO is not empty!: 0x%x", csr); |
267 | return; | 277 | return; |
268 | } | 278 | } |
269 | 279 | ||
280 | logf("EP%d: %d -> %d", endpoint, ep->sent, ep->length); | ||
281 | |||
270 | if(ep->sent == 0) | 282 | if(ep->sent == 0) |
271 | length = (ep->length <= ep->fifo_size ? ep->length : ep->fifo_size); | 283 | length = (ep->length <= ep->fifo_size ? ep->length : ep->fifo_size); |
272 | else | 284 | else |
@@ -279,9 +291,13 @@ static void EPIN_handler(unsigned int endpoint) | |||
279 | if(ep->sent >= ep->length) | 291 | if(ep->sent >= ep->length) |
280 | { | 292 | { |
281 | usb_core_transfer_complete(endpoint, USB_DIR_IN, 0, ep->sent); | 293 | usb_core_transfer_complete(endpoint, USB_DIR_IN, 0, ep->sent); |
294 | if(ep->wait) | ||
295 | wakeup_signal(&ep_wkup[endpoint*2+1]); | ||
296 | logf("sent complete"); | ||
282 | ep->sent = 0; | 297 | ep->sent = 0; |
283 | ep->length = 0; | 298 | ep->length = 0; |
284 | ep->buf = NULL; | 299 | ep->buf = NULL; |
300 | ep->busy = false; | ||
285 | } | 301 | } |
286 | } | 302 | } |
287 | 303 | ||
@@ -289,36 +305,44 @@ static void EPOUT_handler(unsigned int endpoint) | |||
289 | { | 305 | { |
290 | struct usb_endpoint* ep = &endpoints[endpoint*2]; | 306 | struct usb_endpoint* ep = &endpoints[endpoint*2]; |
291 | unsigned int size, csr; | 307 | unsigned int size, csr; |
292 | 308 | ||
293 | select_endpoint(endpoint); | 309 | select_endpoint(endpoint); |
294 | csr = REG_USB_REG_OUTCSR; | 310 | csr = REG_USB_REG_OUTCSR; |
295 | logf("EPOUT_handler(%d): 0x%x", endpoint, csr); | 311 | logf("EPOUT_handler(%d): 0x%x", endpoint, csr); |
296 | 312 | ||
297 | if(ep->buf == NULL || ep->length == 0) | 313 | if(!ep->busy) |
298 | return; | 314 | return; |
299 | 315 | ||
300 | if(csr & USB_OUTCSR_SENTSTALL) | 316 | if(csr & USB_OUTCSR_SENTSTALL) |
301 | { | 317 | { |
318 | logf("stall sent, flushing fifo.."); | ||
319 | flushFIFO(ep); | ||
302 | REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_SENTSTALL; | 320 | REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_SENTSTALL; |
303 | return; | 321 | return; |
304 | } | 322 | } |
305 | 323 | ||
306 | size = REG_USB_REG_OUTCOUNT; | 324 | if(csr & USB_OUTCSR_OUTPKTRDY) /* There is a packet in the fifo */ |
307 | |||
308 | readFIFO(ep, size); | ||
309 | ep->received += size; | ||
310 | |||
311 | REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_OUTPKTRDY; | ||
312 | |||
313 | logf("received: %d length: %d", ep->received, ep->length); | ||
314 | |||
315 | if(size < ep->fifo_size || ep->received >= ep->length) | ||
316 | { | 325 | { |
317 | usb_core_transfer_complete(endpoint, USB_DIR_OUT, 0, ep->received); | 326 | size = REG_USB_REG_OUTCOUNT; |
318 | logf("receive transfer_complete"); | 327 | |
319 | ep->received = 0; | 328 | readFIFO(ep, size); |
320 | ep->length = 0; | 329 | ep->received += size; |
321 | ep->buf = NULL; | 330 | |
331 | REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_OUTPKTRDY; | ||
332 | |||
333 | logf("received: %d max length: %d", ep->received, ep->length); | ||
334 | |||
335 | if(size < ep->fifo_size || ep->received >= ep->length) | ||
336 | { | ||
337 | usb_core_transfer_complete(endpoint, USB_DIR_OUT, 0, ep->received); | ||
338 | if(ep->wait) | ||
339 | wakeup_signal(&ep_wkup[endpoint*2]); | ||
340 | logf("receive transfer_complete"); | ||
341 | ep->received = 0; | ||
342 | ep->length = 0; | ||
343 | ep->buf = NULL; | ||
344 | ep->busy = false; | ||
345 | } | ||
322 | } | 346 | } |
323 | } | 347 | } |
324 | 348 | ||
@@ -330,6 +354,9 @@ static void setup_endpoint(struct usb_endpoint *ep) | |||
330 | 354 | ||
331 | select_endpoint(EP_NUMBER2(ep)); | 355 | select_endpoint(EP_NUMBER2(ep)); |
332 | 356 | ||
357 | ep->busy = false; | ||
358 | ep->wait = false; | ||
359 | |||
333 | if(ep->type == ep_bulk) | 360 | if(ep->type == ep_bulk) |
334 | { | 361 | { |
335 | if(REG_USB_REG_POWER & USB_POWER_HSMODE) | 362 | if(REG_USB_REG_POWER & USB_POWER_HSMODE) |
@@ -474,11 +501,13 @@ void UDC(void) | |||
474 | 501 | ||
475 | bool usb_drv_stalled(int endpoint, bool in) | 502 | bool usb_drv_stalled(int endpoint, bool in) |
476 | { | 503 | { |
504 | endpoint &= 0x7F; | ||
505 | |||
477 | logf("usb_drv_stalled(%d, %s)", endpoint, in?"IN":"OUT"); | 506 | logf("usb_drv_stalled(%d, %s)", endpoint, in?"IN":"OUT"); |
478 | 507 | ||
479 | select_endpoint(endpoint & 0x7F); | 508 | select_endpoint(endpoint); |
480 | 509 | ||
481 | if(endpoint == 0) | 510 | if(endpoint == EP_CONTROL) |
482 | return (REG_USB_REG_CSR0 & USB_CSR0_SENDSTALL) != 0; | 511 | return (REG_USB_REG_CSR0 & USB_CSR0_SENDSTALL) != 0; |
483 | else | 512 | else |
484 | { | 513 | { |
@@ -491,6 +520,8 @@ bool usb_drv_stalled(int endpoint, bool in) | |||
491 | 520 | ||
492 | void usb_drv_stall(int endpoint, bool stall, bool in) | 521 | void usb_drv_stall(int endpoint, bool stall, bool in) |
493 | { | 522 | { |
523 | endpoint &= 0x7F; | ||
524 | |||
494 | logf("usb_drv_stall(%d,%s,%s)", endpoint, stall?"Y":"N", in?"IN":"OUT"); | 525 | logf("usb_drv_stall(%d,%s,%s)", endpoint, stall?"Y":"N", in?"IN":"OUT"); |
495 | 526 | ||
496 | select_endpoint(endpoint); | 527 | select_endpoint(endpoint); |
@@ -533,10 +564,25 @@ int usb_detect(void) | |||
533 | 564 | ||
534 | void usb_init_device(void) | 565 | void usb_init_device(void) |
535 | { | 566 | { |
567 | unsigned int i; | ||
568 | |||
536 | USB_INIT_GPIO(); | 569 | USB_INIT_GPIO(); |
570 | #ifdef USB_GPIO_IRQ | ||
571 | system_enable_irq(IRQ_GPIO_UDC_DETE); | ||
572 | #endif | ||
537 | system_enable_irq(IRQ_UDC); | 573 | system_enable_irq(IRQ_UDC); |
574 | |||
575 | for(i=0; i<TOTAL_EP(); i++) | ||
576 | wakeup_init(&ep_wkup[i]); | ||
538 | } | 577 | } |
539 | 578 | ||
579 | #ifdef USB_GPIO_IRQ | ||
580 | void USB_GPIO_IRQ(void) | ||
581 | { | ||
582 | usb_status_event(usb_detect()); | ||
583 | } | ||
584 | #endif | ||
585 | |||
540 | void usb_enable(bool on) | 586 | void usb_enable(bool on) |
541 | { | 587 | { |
542 | if(on) | 588 | if(on) |
@@ -545,6 +591,11 @@ void usb_enable(bool on) | |||
545 | usb_core_exit(); | 591 | usb_core_exit(); |
546 | } | 592 | } |
547 | 593 | ||
594 | void usb_attach(void) | ||
595 | { | ||
596 | usb_enable(true); | ||
597 | } | ||
598 | |||
548 | void usb_drv_init(void) | 599 | void usb_drv_init(void) |
549 | { | 600 | { |
550 | logf("usb_drv_init()"); | 601 | logf("usb_drv_init()"); |
@@ -591,7 +642,7 @@ void usb_drv_set_address(int address) | |||
591 | REG_USB_REG_FADDR = address; | 642 | REG_USB_REG_FADDR = address; |
592 | } | 643 | } |
593 | 644 | ||
594 | int usb_drv_send(int endpoint, void* ptr, int length) | 645 | int usb_drv_send_nonblocking(int endpoint, void* ptr, int length) |
595 | { | 646 | { |
596 | int flags; | 647 | int flags; |
597 | endpoint &= 0x7F; | 648 | endpoint &= 0x7F; |
@@ -619,6 +670,7 @@ int usb_drv_send(int endpoint, void* ptr, int length) | |||
619 | endpoints[endpoint*2+1].buf = ptr; | 670 | endpoints[endpoint*2+1].buf = ptr; |
620 | endpoints[endpoint*2+1].sent = 0; | 671 | endpoints[endpoint*2+1].sent = 0; |
621 | endpoints[endpoint*2+1].length = length; | 672 | endpoints[endpoint*2+1].length = length; |
673 | endpoints[endpoint*2+1].busy = true; | ||
622 | #if 0 | 674 | #if 0 |
623 | select_endpoint(endpoint); | 675 | select_endpoint(endpoint); |
624 | 676 | ||
@@ -626,7 +678,6 @@ int usb_drv_send(int endpoint, void* ptr, int length) | |||
626 | REG_USB_REG_COUNT2 = length; | 678 | REG_USB_REG_COUNT2 = length; |
627 | REG_USB_REG_CNTL2 = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 | USB_CNTL_DIR_IN | USB_CNTL_ENA); | 679 | REG_USB_REG_CNTL2 = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 | USB_CNTL_DIR_IN | USB_CNTL_ENA); |
628 | #else | 680 | #else |
629 | |||
630 | EPIN_handler(endpoint); | 681 | EPIN_handler(endpoint); |
631 | #endif | 682 | #endif |
632 | restore_irq(flags); | 683 | restore_irq(flags); |
@@ -634,9 +685,20 @@ int usb_drv_send(int endpoint, void* ptr, int length) | |||
634 | } | 685 | } |
635 | } | 686 | } |
636 | 687 | ||
637 | int usb_drv_send_nonblocking(int endpoint, void* ptr, int length) | 688 | int usb_drv_send(int endpoint, void* ptr, int length) |
638 | { | 689 | { |
639 | return usb_drv_send(endpoint, ptr, length); | 690 | int ret; |
691 | endpoint &= 0x7F; | ||
692 | |||
693 | if(endpoint == EP_CONTROL && ptr == NULL && length == 0) | ||
694 | return 0; /* ACK request, handled by the USB controller */ | ||
695 | |||
696 | endpoints[endpoint*2+1].wait = true; | ||
697 | ret = usb_drv_send_nonblocking(endpoint, ptr, length); | ||
698 | wakeup_wait(&ep_wkup[endpoint*2+1], TIMEOUT_BLOCK); | ||
699 | endpoints[endpoint*2+1].wait = false; | ||
700 | |||
701 | return ret; | ||
640 | } | 702 | } |
641 | 703 | ||
642 | int usb_drv_recv(int endpoint, void* ptr, int length) | 704 | int usb_drv_recv(int endpoint, void* ptr, int length) |
@@ -654,7 +716,9 @@ int usb_drv_recv(int endpoint, void* ptr, int length) | |||
654 | endpoints[endpoint*2].buf = ptr; | 716 | endpoints[endpoint*2].buf = ptr; |
655 | endpoints[endpoint*2].received = 0; | 717 | endpoints[endpoint*2].received = 0; |
656 | endpoints[endpoint*2].length = length; | 718 | endpoints[endpoint*2].length = length; |
719 | endpoints[endpoint*2].busy = true; | ||
657 | restore_irq(flags); | 720 | restore_irq(flags); |
721 | |||
658 | return 0; | 722 | return 0; |
659 | } | 723 | } |
660 | } | 724 | } |
diff --git a/firmware/target/mips/mmu-mips.c b/firmware/target/mips/mmu-mips.c new file mode 100644 index 0000000000..3c1b932325 --- /dev/null +++ b/firmware/target/mips/mmu-mips.c | |||
@@ -0,0 +1,125 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2009 by Maurus Cuelenaere | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "config.h" | ||
23 | #include "mips.h" | ||
24 | #include "mipsregs.h" | ||
25 | #include "system.h" | ||
26 | #include "mmu-mips.h" | ||
27 | |||
28 | #define BARRIER \ | ||
29 | __asm__ __volatile__( \ | ||
30 | " .set noreorder \n" \ | ||
31 | " nop \n" \ | ||
32 | " nop \n" \ | ||
33 | " nop \n" \ | ||
34 | " nop \n" \ | ||
35 | " nop \n" \ | ||
36 | " nop \n" \ | ||
37 | " .set reorder \n"); | ||
38 | |||
39 | #define DEFAULT_PAGE_SHIFT PL_4K | ||
40 | #define DEFAULT_PAGE_MASK PM_4K | ||
41 | #define UNIQUE_ENTRYHI(idx, ps) (A_K0BASE + ((idx) << (ps + 1))) | ||
42 | #define ASID_MASK M_EntryHiASID | ||
43 | #define VPN2_SHIFT S_EntryHiVPN2 | ||
44 | #define PFN_SHIFT S_EntryLoPFN | ||
45 | #define PFN_MASK 0xffffff | ||
46 | static void local_flush_tlb_all(void) | ||
47 | { | ||
48 | unsigned long old_ctx; | ||
49 | int entry; | ||
50 | unsigned int old_irq = disable_irq_save(); | ||
51 | |||
52 | /* Save old context and create impossible VPN2 value */ | ||
53 | old_ctx = read_c0_entryhi(); | ||
54 | write_c0_entrylo0(0); | ||
55 | write_c0_entrylo1(0); | ||
56 | BARRIER; | ||
57 | |||
58 | /* Blast 'em all away. */ | ||
59 | for(entry = 0; entry < 32; entry++) | ||
60 | { | ||
61 | /* Make sure all entries differ. */ | ||
62 | write_c0_entryhi(UNIQUE_ENTRYHI(entry, DEFAULT_PAGE_SHIFT)); | ||
63 | write_c0_index(entry); | ||
64 | BARRIER; | ||
65 | tlb_write_indexed(); | ||
66 | } | ||
67 | BARRIER; | ||
68 | write_c0_entryhi(old_ctx); | ||
69 | |||
70 | restore_irq(old_irq); | ||
71 | } | ||
72 | |||
73 | static void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | ||
74 | unsigned long entryhi, unsigned long pagemask) | ||
75 | { | ||
76 | unsigned long wired; | ||
77 | unsigned long old_pagemask; | ||
78 | unsigned long old_ctx; | ||
79 | unsigned int old_irq = disable_irq_save(); | ||
80 | |||
81 | old_ctx = read_c0_entryhi() & ASID_MASK; | ||
82 | old_pagemask = read_c0_pagemask(); | ||
83 | wired = read_c0_wired(); | ||
84 | write_c0_wired(wired + 1); | ||
85 | write_c0_index(wired); | ||
86 | BARRIER; | ||
87 | write_c0_pagemask(pagemask); | ||
88 | write_c0_entryhi(entryhi); | ||
89 | write_c0_entrylo0(entrylo0); | ||
90 | write_c0_entrylo1(entrylo1); | ||
91 | BARRIER; | ||
92 | tlb_write_indexed(); | ||
93 | BARRIER; | ||
94 | |||
95 | write_c0_entryhi(old_ctx); | ||
96 | BARRIER; | ||
97 | write_c0_pagemask(old_pagemask); | ||
98 | local_flush_tlb_all(); | ||
99 | restore_irq(old_irq); | ||
100 | } | ||
101 | |||
102 | void map_address(unsigned long virtual, unsigned long physical, unsigned long length) | ||
103 | { | ||
104 | unsigned long entry0 = (physical & PFN_MASK) << PFN_SHIFT; | ||
105 | unsigned long entry1 = ((physical+length) & PFN_MASK) << PFN_SHIFT; | ||
106 | unsigned long entryhi = virtual & ~VPN2_SHIFT; | ||
107 | |||
108 | entry0 |= (M_EntryLoG | M_EntryLoV | (K_CacheAttrC << S_EntryLoC) ); | ||
109 | entry1 |= (M_EntryLoG | M_EntryLoV | (K_CacheAttrC << S_EntryLoC) ); | ||
110 | |||
111 | add_wired_entry(entry0, entry1, entryhi, DEFAULT_PAGE_MASK); | ||
112 | } | ||
113 | |||
114 | void tlb_init(void) | ||
115 | { | ||
116 | write_c0_pagemask(DEFAULT_PAGE_MASK); | ||
117 | write_c0_wired(0); | ||
118 | write_c0_framemask(0); | ||
119 | |||
120 | local_flush_tlb_all(); | ||
121 | /* | ||
122 | map_address(0x80000000, 0x80000000, 0x4000); | ||
123 | map_address(0x80004000, 0x80004000, MEM * 0x100000); | ||
124 | */ | ||
125 | } | ||
diff --git a/firmware/target/mips/mmu-mips.h b/firmware/target/mips/mmu-mips.h new file mode 100644 index 0000000000..1670d57f1c --- /dev/null +++ b/firmware/target/mips/mmu-mips.h | |||
@@ -0,0 +1,28 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2009 by Maurus Cuelenaere | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #ifndef __MMU_MIPS_INCLUDE_H | ||
23 | #define __MMU_MIPS_INCLUDE_H | ||
24 | |||
25 | void map_address(unsigned long virtual, unsigned long physical, unsigned long length); | ||
26 | void tlb_init(void); | ||
27 | |||
28 | #endif /* __MMU_MIPS_INCLUDE_H */ | ||