Browse Source

Working code to call the PXE stack from within the ISR.

tags/v0.9.3
Michael Brown 17 years ago
parent
commit
027fed72c1
2 changed files with 92 additions and 19 deletions
  1. 70
    0
      src/arch/i386/drivers/net/undiisr.S
  2. 22
    19
      src/arch/i386/drivers/net/undinet.c

+ 70
- 0
src/arch/i386/drivers/net/undiisr.S View File

1
+#define PXENV_UNDI_ISR 0x0014
2
+#define PXENV_UNDI_ISR_IN_START 1
3
+#define PXENV_UNDI_ISR_OUT_OURS 0
4
+#define PXENV_UNDI_ISR_OUT_NOT_OURS 1
5
+
6
+#define IRQ_PIC_CUTOFF 8
7
+#define ICR_EOI_NON_SPECIFIC 0x20
8
+#define PIC1_ICR 0x20
9
+#define PIC2_ICR 0xa0
10
+	
11
+	.text
12
+	.arch i386
13
+	.section ".text16", "ax", @progbits
14
+	.section ".data16", "aw", @progbits
15
+	.code16
16
+
17
+	.section ".text16"
18
+	.globl undiisr
19
+undiisr:
20
+	
21
+	/* Preserve registers */
22
+	pushw	%ds
23
+	pushw	%es
24
+	pusha
25
+	
26
+	/* Issue UNDI API call */
27
+	movw	%cs:rm_ds, %ax
28
+	movw	%ax, %ds
29
+	movw	%ax, %es
30
+	movw	$undinet_params, %di
31
+	movw	$PXENV_UNDI_ISR, %bx
32
+	movw	$PXENV_UNDI_ISR_IN_START, funcflag
33
+	pushw	%es
34
+	pushw	%di
35
+	pushw	%bx
36
+	lcall	*undinet_entry_point
37
+	addw	$6, %sp
38
+	cmpw	$PXENV_UNDI_ISR_OUT_OURS, funcflag
39
+	jne	chain
40
+	
41
+ack:	/* Record interrupt occurence */
42
+	incb	undiisr_trigger_count
43
+	/* Send EOI */
44
+	movb	$ICR_EOI_NON_SPECIFIC, %al
45
+	cmpb	$IRQ_PIC_CUTOFF, undiisr_irq
46
+	jb	1f
47
+	outb	%al, $PIC2_ICR
48
+1:	outb	%al, $PIC1_ICR
49
+	jmp	exit
50
+	
51
+chain:	/* Chain to next handler */
52
+	pushfw
53
+	lcall	*undiisr_next_handler
54
+	
55
+exit:	/* Restore registers and return */
56
+	popa
57
+	popw	%es
58
+	popw	%ds
59
+	iret
60
+
61
+	.section ".data16"
62
+undinet_params:
63
+status:			.word	0
64
+funcflag:		.word	0
65
+bufferlength:		.word	0
66
+framelength:		.word	0
67
+frameheaderlength:	.word	0
68
+frame:			.word	0, 0
69
+prottype:		.byte	0
70
+pkttype:		.byte	0

+ 22
- 19
src/arch/i386/drivers/net/undinet.c View File

146
  * Used as the indirection vector for all UNDI API calls.  Resides in
146
  * Used as the indirection vector for all UNDI API calls.  Resides in
147
  * base memory.
147
  * base memory.
148
  */
148
  */
149
-static SEGOFF16_t __data16 ( undinet_entry_point );
149
+SEGOFF16_t __data16 ( undinet_entry_point );
150
 #define undinet_entry_point __use_data16 ( undinet_entry_point )
150
 #define undinet_entry_point __use_data16 ( undinet_entry_point )
151
 
151
 
152
 /**
152
 /**
245
 /**
245
 /**
246
  * UNDI interrupt service routine
246
  * UNDI interrupt service routine
247
  *
247
  *
248
- * The UNDI ISR simply increments a counter (@c trigger_count) and
249
- * exits.
248
+ * The UNDI ISR increments a counter (@c trigger_count) and exits.
250
  */
249
  */
251
-extern void undinet_isr ( void );
250
+extern void undiisr ( void );
252
 
251
 
253
-/** Dummy chain vector */
254
-static struct segoff prev_handler[ IRQ_MAX + 1 ];
252
+/** IRQ number */
253
+uint8_t __data16 ( undiisr_irq );
254
+#define undiisr_irq __use_data16 ( undiisr_irq )
255
+
256
+/** IRQ chain vector */
257
+struct segoff __data16 ( undiisr_next_handler );
258
+#define undiisr_next_handler __use_data16 ( undiisr_next_handler )
255
 
259
 
256
 /** IRQ trigger count */
260
 /** IRQ trigger count */
257
-static volatile uint8_t __text16 ( trigger_count ) = 0;
258
-#define trigger_count __use_text16 ( trigger_count )
261
+volatile uint8_t __data16 ( undiisr_trigger_count ) = 0;
262
+#define undiisr_trigger_count __use_data16 ( undiisr_trigger_count )
259
 
263
 
260
 /** Last observed trigger count */
264
 /** Last observed trigger count */
261
 static unsigned int last_trigger_count = 0;
265
 static unsigned int last_trigger_count = 0;
275
 static void undinet_hook_isr ( unsigned int irq ) {
279
 static void undinet_hook_isr ( unsigned int irq ) {
276
 
280
 
277
 	assert ( irq <= IRQ_MAX );
281
 	assert ( irq <= IRQ_MAX );
282
+	assert ( undiisr_irq == 0 );
278
 
283
 
279
-	__asm__ __volatile__ ( TEXT16_CODE ( "\nundinet_isr:\n\t"
280
-					     "incb %%cs:%c0\n\t"
281
-					     "iret\n\t" )
282
-			       : : "p" ( & __from_text16 ( trigger_count ) ) );
283
-
284
+	undiisr_irq = irq;
284
 	hook_bios_interrupt ( IRQ_INT ( irq ),
285
 	hook_bios_interrupt ( IRQ_INT ( irq ),
285
-			      ( ( unsigned int ) undinet_isr ),
286
-			      &prev_handler[irq] );
287
-
286
+			      ( ( unsigned int ) undiisr ),
287
+			      &undiisr_next_handler );
288
 }
288
 }
289
 
289
 
290
 /**
290
 /**
297
 	assert ( irq <= IRQ_MAX );
297
 	assert ( irq <= IRQ_MAX );
298
 
298
 
299
 	unhook_bios_interrupt ( IRQ_INT ( irq ),
299
 	unhook_bios_interrupt ( IRQ_INT ( irq ),
300
-				( ( unsigned int ) undinet_isr ),
301
-				&prev_handler[irq] );
300
+				( ( unsigned int ) undiisr ),
301
+				&undiisr_next_handler );
302
+	undiisr_irq = 0;
302
 }
303
 }
303
 
304
 
304
 /**
305
 /**
310
 	unsigned int this_trigger_count;
311
 	unsigned int this_trigger_count;
311
 
312
 
312
 	/* Read trigger_count.  Do this only once; it is volatile */
313
 	/* Read trigger_count.  Do this only once; it is volatile */
313
-	this_trigger_count = trigger_count;
314
+	this_trigger_count = undiisr_trigger_count;
314
 
315
 
315
 	if ( this_trigger_count == last_trigger_count ) {
316
 	if ( this_trigger_count == last_trigger_count ) {
316
 		/* Not triggered */
317
 		/* Not triggered */
424
 		if ( ! undinet_isr_triggered() )
425
 		if ( ! undinet_isr_triggered() )
425
 			return;
426
 			return;
426
 
427
 
428
+#if 0
427
 		/* See if this was our interrupt */
429
 		/* See if this was our interrupt */
428
 		memset ( &undi_isr, 0, sizeof ( undi_isr ) );
430
 		memset ( &undi_isr, 0, sizeof ( undi_isr ) );
429
 		undi_isr.FuncFlag = PXENV_UNDI_ISR_IN_START;
431
 		undi_isr.FuncFlag = PXENV_UNDI_ISR_IN_START;
443
 		/* If this wasn't our interrupt, exit now */
445
 		/* If this wasn't our interrupt, exit now */
444
 		if ( undi_isr.FuncFlag != PXENV_UNDI_ISR_OUT_OURS )
446
 		if ( undi_isr.FuncFlag != PXENV_UNDI_ISR_OUT_OURS )
445
 			return;
447
 			return;
448
+#endif
446
 		
449
 		
447
 		/* Start ISR processing */
450
 		/* Start ISR processing */
448
 		undinic->isr_processing = 1;
451
 		undinic->isr_processing = 1;

Loading…
Cancel
Save