diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2008-03-25 02:34:12 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2008-03-25 02:34:12 +0000 |
commit | 27cf67733936abd75fcb1f8da765977cd75906ee (patch) | |
tree | f894211a8a0c77b402dd3250b2bee2d17dcfe13f /firmware/target/arm | |
parent | bc2f8fd8f38a3e010cd67bbac358f6e9991153c6 (diff) | |
download | rockbox-27cf67733936abd75fcb1f8da765977cd75906ee.tar.gz rockbox-27cf67733936abd75fcb1f8da765977cd75906ee.zip |
Add a complete priority inheritance implementation to the scheduler (all mutex ownership and queue_send calls are inheritable). Priorities are differential so that dispatch depends on the runnable range of priorities. Codec priority can therefore be raised in small steps (pcmbuf updated to enable). Simplify the kernel functions to ease implementation and use the same kernel.c for both sim and target (I'm tired of maintaining two ;_). 1) Not sure if a minor audio break at first buffering issue will exist on large-sector disks (the main mutex speed issue was genuinely resolved earlier). At this point it's best dealt with at the buffering level. It seems a larger filechunk could be used again. 2) Perhaps 64-bit sims will have some minor issues (finicky) but a backroll of the code of concern there is a 5-minute job. All kernel objects become incompatible so a full rebuild and update is needed.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16791 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/ffs-arm.S | 74 | ||||
-rw-r--r-- | firmware/target/arm/i2c-pp.c | 2 | ||||
-rw-r--r-- | firmware/target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c | 2 | ||||
-rw-r--r-- | firmware/target/arm/sandisk/ata-c200_e200.c | 4 |
4 files changed, 78 insertions, 4 deletions
diff --git a/firmware/target/arm/ffs-arm.S b/firmware/target/arm/ffs-arm.S new file mode 100644 index 0000000000..bb888ab558 --- /dev/null +++ b/firmware/target/arm/ffs-arm.S | |||
@@ -0,0 +1,74 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 by Michael Sevakis | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "config.h" | ||
20 | |||
21 | /**************************************************************************** | ||
22 | * int find_first_set_bit(uint32_t val); | ||
23 | * | ||
24 | * Find the index of the least significant set bit in the 32-bit word. | ||
25 | * | ||
26 | * return values: | ||
27 | * 0 - bit 0 is set | ||
28 | * 1 - bit 1 is set | ||
29 | * ... | ||
30 | * 31 - bit 31 is set | ||
31 | * 32 - no bits set | ||
32 | ****************************************************************************/ | ||
33 | .align 2 | ||
34 | .global find_first_set_bit | ||
35 | .type find_first_set_bit,%function | ||
36 | find_first_set_bit: | ||
37 | @ Standard trick to isolate bottom bit in r0 or 0 if r0 = 0 on entry | ||
38 | rsb r2, r0, #0 @ r1 = r0 & -r0 | ||
39 | ands r1, r0, r2 @ | ||
40 | |||
41 | @ now r1 has at most one set bit, call this X | ||
42 | |||
43 | #if ARM_ARCH >= 5 | ||
44 | clz r0, r1 @ Get lead 0's count | ||
45 | rsbne r0, r0, #31 @ lead 0's -> bit index | ||
46 | bx lr @ | ||
47 | #else | ||
48 | @ this is the ffs algorithm devised by D.Seal and posted to | ||
49 | @ comp.sys.arm on 16 Feb 1994. | ||
50 | @ | ||
51 | @ Output modified to suit Rockbox purposes. | ||
52 | |||
53 | adr r2, L_ffs_table | ||
54 | orrne r1, r1, r1, lsl #4 @ r1 = X * 0x11 | ||
55 | orrne r1, r1, r1, lsl #6 @ r1 = X * 0x451 | ||
56 | rsbne r1, r1, r1, lsl #16 @ r1 = X * 0x0450fbaf | ||
57 | |||
58 | @ now lookup in table indexed on top 6 bits of r1 | ||
59 | ldrb r0, [ r2, r1, lsr #26 ] @ | ||
60 | bx lr @ | ||
61 | |||
62 | L_ffs_table: | ||
63 | @ 0 1 2 3 4 5 6 7 | ||
64 | @---------------------------------------------- | ||
65 | .byte 32, 0, 1, 12, 2, 6, 0, 13 @ 0- 7 | ||
66 | .byte 3, 0, 7, 0, 0, 0, 0, 14 @ 8-15 | ||
67 | .byte 10, 4, 0, 0, 8, 0, 0, 25 @ 16-23 | ||
68 | .byte 0, 0, 0, 0, 0, 21, 27, 15 @ 24-31 | ||
69 | .byte 31, 11, 5, 0, 0, 0, 0, 0 @ 32-39 | ||
70 | .byte 9, 0, 0, 24, 0, 0, 20, 26 @ 40-47 | ||
71 | .byte 30, 0, 0, 0, 0, 23, 0, 19 @ 48-55 | ||
72 | .byte 29, 0, 22, 18, 28, 17, 16, 0 @ 56-63 | ||
73 | #endif | ||
74 | .size find_first_set_bit, .-find_first_set_bit | ||
diff --git a/firmware/target/arm/i2c-pp.c b/firmware/target/arm/i2c-pp.c index 092a59be84..1cfbfaeff1 100644 --- a/firmware/target/arm/i2c-pp.c +++ b/firmware/target/arm/i2c-pp.c | |||
@@ -45,7 +45,7 @@ static int pp_i2c_wait_not_busy(void) | |||
45 | if (!(I2C_STATUS & I2C_BUSY)) { | 45 | if (!(I2C_STATUS & I2C_BUSY)) { |
46 | return 0; | 46 | return 0; |
47 | } | 47 | } |
48 | priority_yield(); | 48 | yield(); |
49 | } | 49 | } |
50 | 50 | ||
51 | return -1; | 51 | return -1; |
diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c index 1f5c5c8fbe..f5d37baf5f 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c | |||
@@ -128,7 +128,7 @@ void copy_read_sectors(unsigned char* buf, int wordcount) | |||
128 | 128 | ||
129 | /* Wait for transfer to complete */ | 129 | /* Wait for transfer to complete */ |
130 | while((DSTAT0 & 0x000fffff)) | 130 | while((DSTAT0 & 0x000fffff)) |
131 | priority_yield(); | 131 | yield(); |
132 | /* Dump cache for the buffer */ | 132 | /* Dump cache for the buffer */ |
133 | } | 133 | } |
134 | #endif | 134 | #endif |
diff --git a/firmware/target/arm/sandisk/ata-c200_e200.c b/firmware/target/arm/sandisk/ata-c200_e200.c index c1c0cb3e8c..747cb17ca1 100644 --- a/firmware/target/arm/sandisk/ata-c200_e200.c +++ b/firmware/target/arm/sandisk/ata-c200_e200.c | |||
@@ -198,7 +198,7 @@ static bool sd_poll_status(unsigned int trigger, long timeout) | |||
198 | if (TIME_AFTER(time, next_yield)) | 198 | if (TIME_AFTER(time, next_yield)) |
199 | { | 199 | { |
200 | long ty = USEC_TIMER; | 200 | long ty = USEC_TIMER; |
201 | priority_yield(); | 201 | yield(); |
202 | timeout += USEC_TIMER - ty; | 202 | timeout += USEC_TIMER - ty; |
203 | next_yield = ty + MIN_YIELD_PERIOD; | 203 | next_yield = ty + MIN_YIELD_PERIOD; |
204 | } | 204 | } |
@@ -317,7 +317,7 @@ static int sd_wait_for_state(unsigned int state, int id) | |||
317 | us = USEC_TIMER; | 317 | us = USEC_TIMER; |
318 | if (TIME_AFTER(us, next_yield)) | 318 | if (TIME_AFTER(us, next_yield)) |
319 | { | 319 | { |
320 | priority_yield(); | 320 | yield(); |
321 | timeout += USEC_TIMER - us; | 321 | timeout += USEC_TIMER - us; |
322 | next_yield = us + MIN_YIELD_PERIOD; | 322 | next_yield = us + MIN_YIELD_PERIOD; |
323 | } | 323 | } |