Kaynağa Gözat

Added remaining bus functions.

tags/v0.9.3
Michael Brown 19 yıl önce
ebeveyn
işleme
e3bb65c17f
1 değiştirilmiş dosya ile 121 ekleme ve 12 silme
  1. 121
    12
      src/arch/i386/drivers/bus/bios_disks.c

+ 121
- 12
src/arch/i386/drivers/bus/bios_disks.c Dosyayı Görüntüle

@@ -1,18 +1,25 @@
1 1
 #include "realmode.h"
2
+#include "isa_ids.h"
3
+#include "bios_disks.h"
2 4
 
3 5
 #define CF ( 1 << 0 )
6
+#define BIOS_DISK_NONE 0
4 7
 
5
-struct disk_sector {
6
-	char data[512];
7
-};
8
+/*
9
+ * Ensure that there is sufficient space in the shared dev_bus
10
+ * structure for a struct bios_disk_device.
11
+ *
12
+ */
13
+DEV_BUS( struct bios_disk_device, bios_disk_dev );
14
+static char bios_disk_magic[0]; /* guaranteed unique symbol */
8 15
 
9 16
 /*
10 17
  * Reset the disk system using INT 13,0.  Forces both hard disks and
11 18
  * floppy disks to seek back to track 0.
12 19
  *
13 20
  */
14
-static void disk_init ( void ) {
15
-	REAL_EXEC ( rm_disk_init,
21
+void bios_disk_init ( void ) {
22
+	REAL_EXEC ( rm_bios_disk_init,
16 23
 		    "sti\n\t"
17 24
 		    "xorw %%ax,%%ax\n\t"
18 25
 		    "movb $0x80,%%dl\n\t"
@@ -28,16 +35,19 @@ static void disk_init ( void ) {
28 35
 /*
29 36
  * Read a single sector from a disk using INT 13,2.
30 37
  *
31
- * Returns the BIOS status code (%ah) - 0 indicates success
38
+ * Returns the BIOS status code (%ah) - 0 indicates success.
32 39
  *
33 40
  */
34
-static unsigned int pcbios_disk_read ( int drive, int cylinder, int head,
35
-				       int sector, struct disk_sector *buf ) {
41
+unsigned int bios_disk_read_once ( struct bios_disk_device *bios_disk,
42
+				   unsigned int cylinder,
43
+				   unsigned int head,
44
+				   unsigned int sector,
45
+				   struct bios_disk_sector *buf ) {
36 46
 	uint16_t basemem_buf, status, flags;
37 47
 	int discard_c, discard_d;
38 48
 
39 49
 	basemem_buf = BASEMEM_PARAMETER_INIT ( *buf );
40
-	REAL_EXEC ( rm_pcbios_disk_read,
50
+	REAL_EXEC ( rm_bios_disk_read,
41 51
 		    "sti\n\t"
42 52
 		    "movw $0x0201, %%ax\n\t" /* Read a single sector */
43 53
 		    "int $0x13\n\t"
@@ -46,14 +56,113 @@ static unsigned int pcbios_disk_read ( int drive, int cylinder, int head,
46 56
 		    "cli\n\t",
47 57
 		    4,
48 58
 		    OUT_CONSTRAINTS ( "=a" ( status ), "=b" ( flags ),
49
-				      "=c" ( discard_c ), "=d" ( discard_d ) ),
59
+				      "=c" ( discard_c ),
60
+				      "=d" ( discard_d ) ),
50 61
 		    IN_CONSTRAINTS ( "c" ( ( ( cylinder & 0xff ) << 8 ) |
51 62
 					   ( ( cylinder >> 8 ) & 0x3 ) |
52 63
 					   sector ),
53
-				     "d" ( ( head << 8 ) | drive ),
64
+				     "d" ( ( head << 8 ) | bios_disk->drive ),
54 65
 				     "b" ( basemem_buf ) ),
55 66
 		    CLOBBER ( "ebp", "esi", "edi" ) );
56 67
 	BASEMEM_PARAMETER_DONE ( *buf );
57 68
 
58
-	return ( flags & CF ) ? ( status >> 8 ) : 0;
69
+	return ( flags & CF ) ? ( status >> 8 ) : 0; 
70
+}
71
+
72
+/*
73
+ * Fill in parameters for a BIOS disk device based on drive number
74
+ *
75
+ */
76
+static int fill_bios_disk_device ( struct bios_disk_device *bios_disk ) {
77
+	uint16_t type, flags;
78
+       
79
+	REAL_EXEC ( rm_bios_disk_exists,
80
+		    "sti\n\t"
81
+		    "movb $0x15, %%ah\n\t"
82
+		    "int $0x13\n\t"
83
+		    "pushfw\n\t"
84
+		    "popw %%dx\n\t"
85
+		    "cli\n\t",
86
+		    2,
87
+		    OUT_CONSTRAINTS ( "=a" ( type ), "=d" ( flags ) ),
88
+		    IN_CONSTRAINTS ( "d" ( bios_disk->drive ) ),
89
+		    CLOBBER ( "ebx", "ecx", "esi", "edi", "ebp" ) );
90
+
91
+	if ( ( flags & CF ) ||
92
+	     ( ( type >> 8 ) == BIOS_DISK_NONE ) )
93
+		return 0;
94
+
95
+	DBG ( "BIOS disk found valid drive %hhx\n", bios_disk->drive );
96
+	return 1;
97
+}
98
+
99
+/*
100
+ * Find a BIOS disk device matching the specified driver
101
+ *
102
+ */
103
+int find_bios_disk_device ( struct bios_disk_device *bios_disk,
104
+			    struct bios_disk_driver *driver ) {
105
+
106
+	/* Initialise struct bios_disk if it's the first time it's been used.
107
+	 */
108
+	if ( bios_disk->magic != bios_disk_magic ) {
109
+		memset ( bios_disk, 0, sizeof ( *bios_disk ) );
110
+		bios_disk->magic = bios_disk_magic;
111
+	}
112
+
113
+	/* Iterate through all possible BIOS drives, starting where we
114
+	 * left off
115
+	 */
116
+	DBG ( "BIOS disk searching for device matching driver %s\n",
117
+	      driver->name );
118
+	do {
119
+		/* If we've already used this device, skip it */
120
+		if ( bios_disk->already_tried ) {
121
+			bios_disk->already_tried = 0;
122
+			continue;
123
+		}
124
+
125
+		/* Fill in device parameters */
126
+		if ( ! fill_bios_disk_device ( bios_disk ) ) {
127
+			continue;
128
+		}
129
+
130
+		/* Compare against driver's valid ID range */
131
+		if ( ( bios_disk->drive >= driver->min_drive ) &&
132
+		     ( bios_disk->drive <= driver->max_drive ) ) {
133
+			driver->fill_drive_name ( bios_disk->drive,
134
+						  bios_disk->name );
135
+			DBG ( "BIOS_DISK found drive %hhx (\"%s\") "
136
+			      "matching driver %s\n",
137
+			      bios_disk->drive, bios_disk->name,
138
+			      driver->name );
139
+			bios_disk->already_tried = 1;
140
+			return 1;
141
+		}
142
+	} while ( ++bios_disk->drive );
143
+
144
+	/* No device found */
145
+	DBG ( "BIOS disk found no device matching driver %s\n", driver->name );
146
+	return 0;
147
+}
148
+
149
+/*
150
+ * Find the next MCA device that can be used to boot using the
151
+ * specified driver.
152
+ *
153
+ */
154
+int find_bios_disk_boot_device ( struct dev *dev,
155
+				 struct bios_disk_driver *driver ) {
156
+	struct bios_disk_device *bios_disk
157
+		= ( struct bios_disk_device * ) dev->bus;
158
+
159
+	if ( ! find_bios_disk_device ( bios_disk, driver ) )
160
+		return 0;
161
+
162
+	dev->name = bios_disk->name;
163
+	dev->devid.bus_type = ISA_BUS_TYPE;
164
+	dev->devid.vendor_id = ISA_VENDOR ( 'D', 'S', 'K' );
165
+	dev->devid.device_id = bios_disk->drive;
166
+
167
+	return 1;
59 168
 }

Loading…
İptal
Kaydet