32
32
#include "qapi/error.h"
33
33
#include "qemu/error-report.h"
34
34
#include "qemu/timer.h"
35
+ #include "hw/acpi/aml-build.h"
35
36
#include "hw/irq.h"
36
37
#include "hw/isa/isa.h"
37
38
#include "hw/qdev-properties.h"
@@ -2753,8 +2754,8 @@ FloppyDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i)
2753
2754
return isa -> state .drives [i ].drive ;
2754
2755
}
2755
2756
2756
- void isa_fdc_get_drive_max_chs (FloppyDriveType type ,
2757
- uint8_t * maxc , uint8_t * maxh , uint8_t * maxs )
2757
+ static void isa_fdc_get_drive_max_chs (FloppyDriveType type , uint8_t * maxc ,
2758
+ uint8_t * maxh , uint8_t * maxs )
2758
2759
{
2759
2760
const FDFormat * fdf ;
2760
2761
@@ -2776,6 +2777,110 @@ void isa_fdc_get_drive_max_chs(FloppyDriveType type,
2776
2777
(* maxc )-- ;
2777
2778
}
2778
2779
2780
+ static Aml * build_fdinfo_aml (int idx , FloppyDriveType type )
2781
+ {
2782
+ Aml * dev , * fdi ;
2783
+ uint8_t maxc , maxh , maxs ;
2784
+
2785
+ isa_fdc_get_drive_max_chs (type , & maxc , & maxh , & maxs );
2786
+
2787
+ dev = aml_device ("FLP%c" , 'A' + idx );
2788
+
2789
+ aml_append (dev , aml_name_decl ("_ADR" , aml_int (idx )));
2790
+
2791
+ fdi = aml_package (16 );
2792
+ aml_append (fdi , aml_int (idx )); /* Drive Number */
2793
+ aml_append (fdi ,
2794
+ aml_int (cmos_get_fd_drive_type (type ))); /* Device Type */
2795
+ /*
2796
+ * the values below are the limits of the drive, and are thus independent
2797
+ * of the inserted media
2798
+ */
2799
+ aml_append (fdi , aml_int (maxc )); /* Maximum Cylinder Number */
2800
+ aml_append (fdi , aml_int (maxs )); /* Maximum Sector Number */
2801
+ aml_append (fdi , aml_int (maxh )); /* Maximum Head Number */
2802
+ /*
2803
+ * SeaBIOS returns the below values for int 0x13 func 0x08 regardless of
2804
+ * the drive type, so shall we
2805
+ */
2806
+ aml_append (fdi , aml_int (0xAF )); /* disk_specify_1 */
2807
+ aml_append (fdi , aml_int (0x02 )); /* disk_specify_2 */
2808
+ aml_append (fdi , aml_int (0x25 )); /* disk_motor_wait */
2809
+ aml_append (fdi , aml_int (0x02 )); /* disk_sector_siz */
2810
+ aml_append (fdi , aml_int (0x12 )); /* disk_eot */
2811
+ aml_append (fdi , aml_int (0x1B )); /* disk_rw_gap */
2812
+ aml_append (fdi , aml_int (0xFF )); /* disk_dtl */
2813
+ aml_append (fdi , aml_int (0x6C )); /* disk_formt_gap */
2814
+ aml_append (fdi , aml_int (0xF6 )); /* disk_fill */
2815
+ aml_append (fdi , aml_int (0x0F )); /* disk_head_sttl */
2816
+ aml_append (fdi , aml_int (0x08 )); /* disk_motor_strt */
2817
+
2818
+ aml_append (dev , aml_name_decl ("_FDI" , fdi ));
2819
+ return dev ;
2820
+ }
2821
+
2822
+ int cmos_get_fd_drive_type (FloppyDriveType fd0 )
2823
+ {
2824
+ int val ;
2825
+
2826
+ switch (fd0 ) {
2827
+ case FLOPPY_DRIVE_TYPE_144 :
2828
+ /* 1.44 Mb 3"5 drive */
2829
+ val = 4 ;
2830
+ break ;
2831
+ case FLOPPY_DRIVE_TYPE_288 :
2832
+ /* 2.88 Mb 3"5 drive */
2833
+ val = 5 ;
2834
+ break ;
2835
+ case FLOPPY_DRIVE_TYPE_120 :
2836
+ /* 1.2 Mb 5"5 drive */
2837
+ val = 2 ;
2838
+ break ;
2839
+ case FLOPPY_DRIVE_TYPE_NONE :
2840
+ default :
2841
+ val = 0 ;
2842
+ break ;
2843
+ }
2844
+ return val ;
2845
+ }
2846
+
2847
+ static void fdc_isa_build_aml (ISADevice * isadev , Aml * scope )
2848
+ {
2849
+ Aml * dev ;
2850
+ Aml * crs ;
2851
+ int i ;
2852
+
2853
+ #define ACPI_FDE_MAX_FD 4
2854
+ uint32_t fde_buf [5 ] = {
2855
+ 0 , 0 , 0 , 0 , /* presence of floppy drives #0 - #3 */
2856
+ cpu_to_le32 (2 ) /* tape presence (2 == never present) */
2857
+ };
2858
+
2859
+ crs = aml_resource_template ();
2860
+ aml_append (crs , aml_io (AML_DECODE16 , 0x03F2 , 0x03F2 , 0x00 , 0x04 ));
2861
+ aml_append (crs , aml_io (AML_DECODE16 , 0x03F7 , 0x03F7 , 0x00 , 0x01 ));
2862
+ aml_append (crs , aml_irq_no_flags (6 ));
2863
+ aml_append (crs ,
2864
+ aml_dma (AML_COMPATIBILITY , AML_NOTBUSMASTER , AML_TRANSFER8 , 2 ));
2865
+
2866
+ dev = aml_device ("FDC0" );
2867
+ aml_append (dev , aml_name_decl ("_HID" , aml_eisaid ("PNP0700" )));
2868
+ aml_append (dev , aml_name_decl ("_CRS" , crs ));
2869
+
2870
+ for (i = 0 ; i < MIN (MAX_FD , ACPI_FDE_MAX_FD ); i ++ ) {
2871
+ FloppyDriveType type = isa_fdc_get_drive_type (isadev , i );
2872
+
2873
+ if (type < FLOPPY_DRIVE_TYPE_NONE ) {
2874
+ fde_buf [i ] = cpu_to_le32 (1 ); /* drive present */
2875
+ aml_append (dev , build_fdinfo_aml (i , type ));
2876
+ }
2877
+ }
2878
+ aml_append (dev , aml_name_decl ("_FDE" ,
2879
+ aml_buffer (sizeof (fde_buf ), (uint8_t * )fde_buf )));
2880
+
2881
+ aml_append (scope , dev );
2882
+ }
2883
+
2779
2884
static const VMStateDescription vmstate_isa_fdc = {
2780
2885
.name = "fdc" ,
2781
2886
.version_id = 2 ,
@@ -2809,11 +2914,13 @@ static Property isa_fdc_properties[] = {
2809
2914
static void isabus_fdc_class_init (ObjectClass * klass , void * data )
2810
2915
{
2811
2916
DeviceClass * dc = DEVICE_CLASS (klass );
2917
+ ISADeviceClass * isa = ISA_DEVICE_CLASS (klass );
2812
2918
2813
2919
dc -> realize = isabus_fdc_realize ;
2814
2920
dc -> fw_name = "fdc" ;
2815
2921
dc -> reset = fdctrl_external_reset_isa ;
2816
2922
dc -> vmsd = & vmstate_isa_fdc ;
2923
+ isa -> build_aml = fdc_isa_build_aml ;
2817
2924
device_class_set_props (dc , isa_fdc_properties );
2818
2925
set_bit (DEVICE_CATEGORY_STORAGE , dc -> categories );
2819
2926
}
0 commit comments