summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/Makefile2
-rw-r--r--firmware/ata.c242
-rw-r--r--firmware/ata.h32
-rw-r--r--firmware/fat.c2
-rw-r--r--firmware/kernel.c35
-rw-r--r--firmware/kernel.h36
6 files changed, 348 insertions, 1 deletions
diff --git a/firmware/Makefile b/firmware/Makefile
index 636f48094a..22f342a259 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -27,6 +27,8 @@ AFLAGS += -small -relax
27SRC := $(wildcard *.c) 27SRC := $(wildcard *.c)
28OBJS := $(SRC:%.c=%.o) 28OBJS := $(SRC:%.c=%.o)
29 29
30OBJS := button.o chartables.o lcd.o led.o serial.o system.o ata.o kernel.o
31
30%.o: %.s 32%.o: %.s
31 $(CC) -o $@ $(CFLAGS) $(INCLUDES) $(DEFS) -c $< 33 $(CC) -o $@ $(CFLAGS) $(INCLUDES) $(DEFS) -c $<
32 34
diff --git a/firmware/ata.c b/firmware/ata.c
new file mode 100644
index 0000000000..460808a217
--- /dev/null
+++ b/firmware/ata.c
@@ -0,0 +1,242 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Alan Korr
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 "ata.h"
20#include "kernel.h"
21#include "led.h"
22
23#define ATA_DATA (*((volatile unsigned short*)0x06104100))
24#define ATA_ERROR (*((volatile unsigned char*)0x06100101))
25#define ATA_FEATURE ATA_ERROR
26#define ATA_NSECTOR (*((volatile unsigned char*)0x06100102))
27#define ATA_SECTOR (*((volatile unsigned char*)0x06100103))
28#define ATA_LCYL (*((volatile unsigned char*)0x06100104))
29#define ATA_HCYL (*((volatile unsigned char*)0x06100105))
30#define ATA_SELECT (*((volatile unsigned char*)0x06100106))
31#define ATA_COMMAND (*((volatile unsigned char*)0x06100107))
32#define ATA_STATUS ATA_COMMAND
33#define ATA_CONTROL (*((volatile unsigned char*)0x06100306))
34
35#define SELECT_LBA 0x40
36
37#define STATUS_BSY 0x80
38#define STATUS_RDY 0x40
39#define STATUS_DRQ 0x08
40#define STATUS_ERR 0x01
41
42#define CONTROL_nIEN 0x02
43#define CONTROL_SRST 0x04
44
45#define CMD_READ_SECTORS 0x20
46#define CMD_WRITE_SECTORS 0x30
47#define CMD_STANDBY_IMMEDIATE 0xE0
48#define CMD_STANDBY 0xE2
49#define CMD_SLEEP 0xE6
50#define CMD_SECURITY_FREEZE_LOCK 0xF5
51
52static int wait_for_bsy(void)
53{
54 char timeout = current_tick + HZ;
55 while (TIME_BEFORE(current_tick, timeout) && (ATA_STATUS & STATUS_BSY))
56 yield();
57
58 if (TIME_BEFORE(current_tick, timeout))
59 return 1;
60 else
61 return 0; /* timeout */
62}
63
64static int wait_for_rdy(void)
65{
66 if (!wait_for_bsy())
67 return 0;
68 return ATA_STATUS & STATUS_RDY;
69}
70
71static int wait_for_start_of_transfer(void)
72{
73 if (!wait_for_bsy())
74 return 0;
75 return (ATA_STATUS & (STATUS_RDY|STATUS_DRQ)) == (STATUS_RDY|STATUS_DRQ);
76}
77
78static int wait_for_end_of_transfer(void)
79{
80 if (!wait_for_bsy())
81 return 0;
82 return (ATA_STATUS & (STATUS_RDY|STATUS_DRQ)) == STATUS_RDY;
83}
84
85int ata_read_sectors(unsigned long start,
86 unsigned char count,
87 unsigned short* buf)
88{
89 int i;
90
91 if (!wait_for_rdy())
92 return 0;
93
94 led_turn_on();
95
96 ATA_NSECTOR = count;
97 ATA_SECTOR = start & 0xff;
98 ATA_LCYL = (start >> 8) & 0xff;
99 ATA_HCYL = (start >> 16) & 0xff;
100 ATA_SELECT = ((start >> 24) & 0xf) | SELECT_LBA;
101 ATA_COMMAND = CMD_READ_SECTORS;
102
103 for (i=0; i<count; i++) {
104 int j;
105 if (!wait_for_start_of_transfer())
106 return 0;
107
108 for (j=0; j<256; j++)
109 buf[j] = SWAB16(ATA_DATA);
110 }
111
112 led_turn_off();
113
114 return wait_for_end_of_transfer();
115}
116
117int ata_write_sectors(unsigned long start,
118 unsigned char count,
119 unsigned short* buf)
120{
121 int i;
122
123 if (!wait_for_rdy())
124 return 0;
125
126 led_turn_on ();
127
128 ATA_NSECTOR = count;
129 ATA_SECTOR = start & 0xff;
130 ATA_LCYL = (start >> 8) & 0xff;
131 ATA_HCYL = (start >> 16) & 0xff;
132 ATA_SELECT = ((start >> 24) & 0xf) | SELECT_LBA;
133 ATA_COMMAND = CMD_WRITE_SECTORS;
134
135 for (i=0; i<count; i++) {
136 int j;
137 if (!wait_for_start_of_transfer())
138 return 0;
139
140 for (j=0; j<256; j++)
141 ATA_DATA = SWAB16(buf[j]);
142 }
143
144 led_turn_off ();
145
146 return wait_for_end_of_transfer();
147}
148
149static int check_registers(void)
150{
151 if ( ATA_STATUS & STATUS_BSY )
152 return 0;
153
154 ATA_NSECTOR = 0xa5;
155 ATA_SECTOR = 0x5a;
156 ATA_LCYL = 0xaa;
157 ATA_HCYL = 0x55;
158
159 if ((ATA_NSECTOR == 0xa5) &&
160 (ATA_SECTOR == 0x5a) &&
161 (ATA_LCYL == 0xaa) &&
162 (ATA_HCYL == 0x55))
163 return 1;
164 else
165 return 0;
166}
167
168static int check_harddisk(void)
169{
170 if (!wait_for_rdy())
171 return 0;
172
173 if ((ATA_NSECTOR == 1) &&
174 (ATA_SECTOR == 1) &&
175 (ATA_LCYL == 0) &&
176 (ATA_HCYL == 0) &&
177 (ATA_SELECT == 0))
178 return 1;
179 else
180 return 0;
181}
182
183static int freeze_lock(void)
184{
185 if (!wait_for_rdy())
186 return -1;
187
188 ATA_COMMAND = CMD_SECURITY_FREEZE_LOCK;
189
190 if (!wait_for_rdy())
191 return -1;
192
193 return 0;
194}
195
196int ata_hard_reset(void)
197{
198 clear_bit(1,PADR);
199 sleep(HZ/500);
200
201 set_bit(1,PADR);
202 sleep(HZ/500);
203
204 return wait_for_rdy();
205}
206
207int ata_soft_reset(void)
208{
209 ATA_SELECT = SELECT_LBA;
210 ATA_CONTROL = CONTROL_nIEN|CONTROL_SRST;
211 sleep(HZ/20000); /* >= 5us */
212
213 ATA_CONTROL = CONTROL_nIEN;
214 sleep(HZ/400); /* >2ms */
215
216 return wait_for_rdy();
217}
218
219int ata_init(void)
220{
221 led_turn_off();
222
223 /* activate ATA */
224 PADR |= 0x80;
225
226 if (!ata_hard_reset())
227 return -1;
228
229 if (!check_registers())
230 return -2;
231
232 if (!check_harddisk())
233 return -3;
234
235 if (!freeze_lock())
236 return -4;
237
238 ATA_SELECT = SELECT_LBA;
239 ATA_CONTROL = CONTROL_nIEN;
240
241 return 0;
242}
diff --git a/firmware/ata.h b/firmware/ata.h
new file mode 100644
index 0000000000..de94803b3b
--- /dev/null
+++ b/firmware/ata.h
@@ -0,0 +1,32 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Alan Korr
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#ifndef __ATA_H__
20#define __ATA_H__
21
22extern int ata_hard_reset(void);
23extern int ata_soft_reset(void);
24extern int ata_init(void);
25extern int ata_read_sectors(unsigned long start,
26 unsigned char count,
27 unsigned short* buf);
28extern int ata_write_sectors(unsigned long start,
29 unsigned char count,
30 unsigned short* buf);
31
32#endif
diff --git a/firmware/fat.c b/firmware/fat.c
index bd6ec78426..58f4f36bac 100644
--- a/firmware/fat.c
+++ b/firmware/fat.c
@@ -96,12 +96,12 @@ struct disk_info di;
96extern int yyparse(void); 96extern int yyparse(void);
97 97
98 98
99#ifdef TEST_FAT
99void prompt(void) 100void prompt(void)
100{ 101{
101 printf("C:%s>", current_directory); 102 printf("C:%s>", current_directory);
102} 103}
103 104
104#ifdef TEST_FAT
105int main(int argc, char *argv[]) 105int main(int argc, char *argv[])
106{ 106{
107 struct bpb bpb; 107 struct bpb bpb;
diff --git a/firmware/kernel.c b/firmware/kernel.c
new file mode 100644
index 0000000000..012ff94c73
--- /dev/null
+++ b/firmware/kernel.c
@@ -0,0 +1,35 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Björn Stenberg
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 "kernel.h"
20
21long current_tick = 0;
22
23void sleep(int ticks)
24{
25 int timeout = current_tick + ticks;
26
27 /* always yield at least once */
28 do {
29 yield();
30 } while (TIME_BEFORE( current_tick, timeout ));
31}
32
33void yield(void)
34{
35}
diff --git a/firmware/kernel.h b/firmware/kernel.h
new file mode 100644
index 0000000000..60e8ad6db1
--- /dev/null
+++ b/firmware/kernel.h
@@ -0,0 +1,36 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Björn Stenberg
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#ifndef _KERNEL_H_
20#define _KERNEL_H_
21
22/* wrap-safe macros for tick comparison */
23#define TIME_AFTER(a,b) ((long)(b) - (long)(a) < 0)
24#define TIME_BEFORE(a,b) TIME_AFTER(b,a)
25
26#define HZ 100 /* number of ticks per second */
27
28/* global tick variable */
29extern long current_tick;
30
31/* kernel functions */
32extern void yield(void);
33extern void sleep(int ticks);
34
35
36#endif