39
39
static uint32_t vuart_com_irq = CONFIG_COM_IRQ ;
40
40
static uint16_t vuart_com_base = CONFIG_COM_BASE ;
41
41
42
- #ifndef CONFIG_PARTITION_MODE
43
- static char vuart_rx_buf [RX_BUF_SIZE ];
44
- static char vuart_tx_buf [TX_BUF_SIZE ];
45
- #endif
46
-
47
42
#define vuart_lock_init (vu ) spinlock_init(&((vu)->lock))
48
43
#define vuart_lock (vu ) spinlock_obtain(&((vu)->lock))
49
44
#define vuart_unlock (vu ) spinlock_release(&((vu)->lock))
50
45
51
- #ifdef CONFIG_PARTITION_MODE
52
- uint16_t vuart_vmid = 0xFFFFU ;
53
- #endif
46
+ uint16_t console_vmid = ACRN_INVALID_VMID ;
54
47
55
48
static inline void fifo_reset (struct fifo * fifo )
56
49
{
@@ -92,13 +85,8 @@ static inline uint32_t fifo_numchars(const struct fifo *fifo)
92
85
93
86
static inline void vuart_fifo_init (struct acrn_vuart * vu )
94
87
{
95
- #ifdef CONFIG_PARTITION_MODE
96
88
vu -> txfifo .buf = vu -> vuart_tx_buf ;
97
89
vu -> rxfifo .buf = vu -> vuart_rx_buf ;
98
- #else
99
- vu -> txfifo .buf = vuart_tx_buf ;
100
- vu -> rxfifo .buf = vuart_rx_buf ;
101
- #endif
102
90
vu -> txfifo .size = TX_BUF_SIZE ;
103
91
vu -> rxfifo .size = RX_BUF_SIZE ;
104
92
fifo_reset (& (vu -> txfifo ));
@@ -125,9 +113,28 @@ static uint8_t vuart_intr_reason(const struct acrn_vuart *vu)
125
113
}
126
114
}
127
115
128
- struct acrn_vuart * vm_vuart (struct acrn_vm * vm )
116
+ struct acrn_vuart * find_vuart_by_port (struct acrn_vm * vm , uint16_t offset )
117
+ {
118
+ uint8_t i ;
119
+ struct acrn_vuart * vu , * ret_vu = NULL ;
120
+
121
+ /* TODO: support pci vuart find */
122
+ for (i = 0 ; i < MAX_VUART_NUM_PER_VM ; i ++ ) {
123
+ vu = & vm -> vuart [i ];
124
+ if (vu -> active == true && vu -> port_base == (offset & ~0x7U )) {
125
+ ret_vu = vu ;
126
+ break ;
127
+ }
128
+ }
129
+ return ret_vu ;
130
+ }
131
+
132
+ /*
133
+ * @post return != NULL
134
+ */
135
+ struct acrn_vuart * vm_console_vuart (struct acrn_vm * vm )
129
136
{
130
- return & ( vm -> vuart ) ;
137
+ return & vm -> vuart [ 0 ] ;
131
138
}
132
139
133
140
/*
@@ -141,7 +148,7 @@ static void vuart_toggle_intr(const struct acrn_vuart *vu)
141
148
uint32_t operation ;
142
149
143
150
intr_reason = vuart_intr_reason (vu );
144
- vioapic_get_rte (vu -> vm , vuart_com_irq , & rte );
151
+ vioapic_get_rte (vu -> vm , vu -> irq , & rte );
145
152
146
153
/* TODO:
147
154
* Here should assert vuart irq according to CONFIG_COM_IRQ polarity.
@@ -157,18 +164,18 @@ static void vuart_toggle_intr(const struct acrn_vuart *vu)
157
164
operation = (intr_reason != IIR_NOPEND ) ? GSI_SET_HIGH : GSI_SET_LOW ;
158
165
}
159
166
160
- vpic_set_irqline (vu -> vm , vuart_com_irq , operation );
161
- vioapic_set_irqline_lock (vu -> vm , vuart_com_irq , operation );
167
+ vpic_set_irqline (vu -> vm , vu -> irq , operation );
168
+ vioapic_set_irqline_lock (vu -> vm , vu -> irq , operation );
162
169
}
163
170
164
171
static bool vuart_write (struct acrn_vm * vm , uint16_t offset_arg ,
165
172
__unused size_t width , uint32_t value )
166
173
{
167
174
uint16_t offset = offset_arg ;
168
- struct acrn_vuart * vu = vm_vuart (vm );
175
+ struct acrn_vuart * vu = find_vuart_by_port (vm , offset );
169
176
uint8_t value_u8 = (uint8_t )value ;
170
177
171
- offset -= vu -> base ;
178
+ offset -= vu -> port_base ;
172
179
vuart_lock (vu );
173
180
/*
174
181
* Take care of the special case DLAB accesses first
@@ -253,10 +260,10 @@ static bool vuart_read(struct acrn_vm *vm, struct acrn_vcpu *vcpu, uint16_t offs
253
260
{
254
261
uint16_t offset = offset_arg ;
255
262
uint8_t iir , reg , intr_reason ;
256
- struct acrn_vuart * vu = vm_vuart (vm );
263
+ struct acrn_vuart * vu = find_vuart_by_port (vm , offset );
257
264
struct pio_request * pio_req = & vcpu -> req .reqs .pio ;
258
265
259
- offset -= vu -> base ;
266
+ offset -= vu -> port_base ;
260
267
vuart_lock (vu );
261
268
/*
262
269
* Take care of the special case DLAB accesses first
@@ -330,15 +337,33 @@ static bool vuart_read(struct acrn_vm *vm, struct acrn_vcpu *vcpu, uint16_t offs
330
337
return true;
331
338
}
332
339
333
- static void vuart_register_io_handler (struct acrn_vm * vm )
340
+ /*
341
+ * @pre: vuart_idx = 0 or 1
342
+ */
343
+ static bool vuart_register_io_handler (struct acrn_vm * vm , uint16_t port_base , uint32_t vuart_idx )
334
344
{
345
+ uint32_t pio_idx ;
346
+ bool ret = true;
347
+
335
348
struct vm_io_range range = {
336
349
.flags = IO_ATTR_RW ,
337
- .base = vuart_com_base ,
350
+ .base = port_base ,
338
351
.len = 8U
339
352
};
340
-
341
- register_pio_emulation_handler (vm , UART_PIO_IDX , & range , vuart_read , vuart_write );
353
+ switch (vuart_idx ) {
354
+ case 0 :
355
+ pio_idx = UART_PIO_IDX0 ;
356
+ break ;
357
+ case 1 :
358
+ pio_idx = UART_PIO_IDX1 ;
359
+ break ;
360
+ default :
361
+ printf ("Not support vuart index %d, will not register \n" );
362
+ ret = false;
363
+ }
364
+ if (ret )
365
+ register_pio_emulation_handler (vm , pio_idx , & range , vuart_read , vuart_write );
366
+ return ret ;
342
367
}
343
368
344
369
/**
@@ -367,7 +392,7 @@ void vuart_console_rx_chars(struct acrn_vuart *vu)
367
392
368
393
if (ch == GUEST_CONSOLE_TO_HV_SWITCH_KEY ) {
369
394
/* Switch the console */
370
- vu -> active = false ;
395
+ console_vmid = ACRN_INVALID_VMID ;
371
396
printf ("\r\n\r\n ---Entering ACRN SHELL---\r\n" );
372
397
}
373
398
if (ch != -1 ) {
@@ -381,46 +406,79 @@ void vuart_console_rx_chars(struct acrn_vuart *vu)
381
406
struct acrn_vuart * vuart_console_active (void )
382
407
{
383
408
struct acrn_vm * vm = NULL ;
409
+ struct acrn_vuart * vu = NULL ;
384
410
385
- #ifdef CONFIG_PARTITION_MODE
386
- if (vuart_vmid < CONFIG_MAX_VM_NUM ) {
387
- vm = get_vm_from_vmid (vuart_vmid );
411
+ if (console_vmid < CONFIG_MAX_VM_NUM ) {
412
+ vm = get_vm_from_vmid (console_vmid );
388
413
}
389
- #else
390
- vm = get_sos_vm ();
391
- #endif
392
414
393
415
if (is_valid_vm (vm )) {
394
- struct acrn_vuart * vu = vm_vuart (vm );
395
-
396
- if (vu -> active ) {
397
- return vu ;
398
- }
416
+ vu = vm_console_vuart (vm );
399
417
}
400
- return NULL ;
418
+ return ( vu && vu -> active ) ? vu : NULL ;
401
419
}
402
420
403
- void vuart_init (struct acrn_vm * vm )
421
+ static void vuart_setup (struct acrn_vm * vm ,
422
+ struct vuart_config * vu_config , uint16_t vuart_idx )
404
423
{
405
424
uint32_t divisor ;
406
- struct acrn_vuart * vu = vm_vuart ( vm ) ;
425
+ struct acrn_vuart * vu = & vm -> vuart [ vuart_idx ] ;
407
426
408
427
/* Set baud rate*/
409
- divisor = (UART_CLOCK_RATE / BAUD_9600 ) >> 4U ;
410
- vm -> vuart .dll = (uint8_t )divisor ;
411
- vm -> vuart .dlh = (uint8_t )(divisor >> 8U );
412
-
413
- vm -> vuart .active = false;
414
- vm -> vuart .base = vuart_com_base ;
415
- vm -> vuart .vm = vm ;
428
+ divisor = (UART_CLOCK_RATE / BAUD_115200 ) >> 4U ;
429
+ vu -> dll = (uint8_t )divisor ;
430
+ vu -> dlh = (uint8_t )(divisor >> 8U );
431
+ vu -> vm = vm ;
416
432
vuart_fifo_init (vu );
417
433
vuart_lock_init (vu );
418
- vuart_register_io_handler (vm );
434
+ if (vu_config -> type == VUART_LEGACY_PIO ) {
435
+ vu -> port_base = vu_config -> addr .port_base ;
436
+ vu -> irq = vu_config -> irq ;
437
+ if (vuart_register_io_handler (vm , vu -> port_base , vuart_idx )) {
438
+ vu -> active = true;
439
+ }
440
+ } else {
441
+ /*TODO: add pci vuart support here*/
442
+ printf ("PCI vuart is not support\n" );
443
+ }
444
+ }
445
+
446
+ bool is_vuart_intx (struct acrn_vm * vm , uint32_t intx_pin )
447
+ {
448
+ uint8_t i ;
449
+ bool ret = false;
450
+
451
+ for (i = 0 ; i < MAX_VUART_NUM_PER_VM ; i ++ )
452
+ if (vm -> vuart [i ].active && vm -> vuart [i ].irq == intx_pin )
453
+ ret = true;
454
+ return ret ;
455
+ }
456
+
457
+ void vuart_init (struct acrn_vm * vm , struct vuart_config * vu_config )
458
+ {
459
+ uint8_t i ;
460
+
461
+ for (i = 0 ; i < MAX_VUART_NUM_PER_VM ; i ++ ) {
462
+ vm -> vuart [i ].active = false;
463
+ /* This vuart is not exist */
464
+ if (vu_config [i ].type == VUART_LEGACY_PIO &&
465
+ vu_config [i ].addr .port_base == INVALID_COM_BASE )
466
+ continue ;
467
+ vuart_setup (vm , & vu_config [i ], i );
468
+ }
419
469
}
420
470
421
- bool hv_used_dbg_intx ( uint32_t intx_pin )
471
+ void vuart_deinit ( struct acrn_vm * vm )
422
472
{
423
- return is_dbg_uart_enabled () && (intx_pin == vuart_com_irq );
473
+ uint8_t i ;
474
+
475
+ /* reset console_vmid to switch back to hypervisor console */
476
+ if (console_vmid == vm -> vm_id )
477
+ console_vmid = ACRN_INVALID_VMID ;
478
+
479
+ for (i = 0 ; i < MAX_VUART_NUM_PER_VM ; i ++ ) {
480
+ vm -> vuart [i ].active = false;
481
+ }
424
482
}
425
483
426
484
/* vuart=ttySx@irqN, like vuart=ttyS1@irq6 head "vuart=ttyS" is parsed */
0 commit comments