Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1.  
  2. #include <syscall.h>
  3. #include <linux/delay.h>
  4. #include <linux/ktime.h>
  5. #include <linux/acpi.h>
  6. #include <linux/dmi.h>
  7.  
  8.  
  9. #define PREFIX          "ACPI: "
  10.  
  11. int sbf_port __initdata = -1;
  12.  
  13. static bool acpi_os_initialized;
  14.  
  15.  
  16. u32  __attribute__((externally_visible)) drvEntry(int action, char *cmdline)
  17. {
  18.     int result;
  19.  
  20.     if(action != 1)
  21.         return 0;
  22.  
  23.     if( !dbg_open("/tmp0/1/acpi.log") )
  24.     {
  25.         printk("Can't open /tmp0/1/acpi.log\nExit\n");
  26.         return 0;
  27.     }
  28.  
  29.     dmi_scan_machine();
  30.  
  31.     acpi_boot_table_init();
  32.  
  33.     early_acpi_boot_init();
  34.  
  35.     acpi_noirq_set();
  36.  
  37.     acpi_early_init();
  38.  
  39.  
  40. //    if (acpi_disabled) {
  41. //            printk(KERN_INFO PREFIX "Interpreter disabled.\n");
  42. //            return -ENODEV;
  43. //    }
  44.  
  45. //    init_acpi_device_notify();
  46. //    result = acpi_bus_init();
  47. //    if (result) {
  48. //            disable_acpi();
  49. //            return result;
  50. //    }
  51.  
  52. //    pci_mmcfg_late_init();
  53. //    acpi_scan_init();
  54. //    acpi_ec_init();
  55. //    acpi_debugfs_init();
  56. //    acpi_sleep_proc_init();
  57. //    acpi_wakeup_device_init();
  58.  
  59.     dbgprintf("module loaded\n");
  60.  
  61.  
  62.     return 0;
  63.  
  64. };
  65.  
  66.  
  67. #define PREFIX          "ACPI: "
  68.  
  69. u32 IMPORT  AcpiGetRootPtr(void)__asm__("AcpiGetRootPtr");
  70.  
  71. acpi_physical_address __init acpi_os_get_root_pointer(void)
  72. {
  73.     return AcpiGetRootPtr();
  74. }
  75.  
  76. void* acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
  77. {
  78.     return (void *)MapIoMem((addr_t)phys, size, PG_SW);
  79.  
  80. }
  81.  
  82. void acpi_os_unmap_memory(void *virt, acpi_size size)
  83. {
  84.     u32 ptr = (u32)virt;
  85.     ptr &= 0xFFFFF000;
  86.  
  87.     return FreeKernelSpace((void*)ptr);
  88. }
  89.  
  90. void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
  91. {
  92.     acpi_os_unmap_memory(virt, size);
  93. }
  94.  
  95.  
  96. int acpi_os_map_generic_address(struct acpi_generic_address *gas)
  97. {
  98.     addr_t addr;
  99.     void *virt;
  100.  
  101.     if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
  102.         return 0;
  103.  
  104.     addr = (addr_t)gas->address;
  105.  
  106.     if (!addr || !gas->bit_width)
  107.         return -EINVAL;
  108.  
  109.     virt = (void *)MapIoMem(addr, gas->bit_width / 8, PG_SW);
  110.     if (!virt)
  111.         return -EIO;
  112.  
  113.     return 0;
  114. }
  115.  
  116.  
  117. void acpi_os_printf(const char *fmt, ...)
  118. {
  119.     va_list args;
  120.     va_start(args, fmt);
  121.     acpi_os_vprintf(fmt, args);
  122.     va_end(args);
  123. }
  124.  
  125. void acpi_os_vprintf(const char *fmt, va_list args)
  126. {
  127.     static char buffer[512];
  128.  
  129.     vsprintf(buffer, fmt, args);
  130.  
  131. #ifdef ENABLE_DEBUGGER
  132.     if (acpi_in_debugger) {
  133.         kdb_printf("%s", buffer);
  134.     } else {
  135.             printk("%s", buffer);
  136.     }
  137. #else
  138.     printk("%s", buffer);
  139. #endif
  140. }
  141.  
  142.  
  143. static void acpi_table_taint(struct acpi_table_header *table)
  144. {
  145.      pr_warn(PREFIX
  146.              "Override [%4.4s-%8.8s], this is unsafe: tainting kernel\n",
  147.              table->signature, table->oem_table_id);
  148.      add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE);
  149. }
  150.  
  151.  
  152.  
  153.  
  154. acpi_status
  155. acpi_os_table_override(struct acpi_table_header * existing_table,
  156.                        struct acpi_table_header ** new_table)
  157. {
  158.     if (!existing_table || !new_table)
  159.         return AE_BAD_PARAMETER;
  160.  
  161.     *new_table = NULL;
  162.  
  163. #ifdef CONFIG_ACPI_CUSTOM_DSDT
  164.     if (strncmp(existing_table->signature, "DSDT", 4) == 0)
  165.         *new_table = (struct acpi_table_header *)AmlCode;
  166. #endif
  167.     if (*new_table != NULL)
  168.         acpi_table_taint(existing_table);
  169.     return AE_OK;
  170. }
  171.  
  172. acpi_status
  173. acpi_os_physical_table_override(struct acpi_table_header *existing_table,
  174.                                 acpi_physical_address *address,
  175.                                 u32 *table_length)
  176. {
  177. #ifndef CONFIG_ACPI_INITRD_TABLE_OVERRIDE
  178.         *table_length = 0;
  179.         *address = 0;
  180.         return AE_OK;
  181. #else
  182.         int table_offset = 0;
  183.         struct acpi_table_header *table;
  184.  
  185.         *table_length = 0;
  186.         *address = 0;
  187.  
  188.         if (!acpi_tables_addr)
  189.                 return AE_OK;
  190.  
  191.         do {
  192.                 if (table_offset + ACPI_HEADER_SIZE > all_tables_size) {
  193.                         WARN_ON(1);
  194.                         return AE_OK;
  195.                 }
  196.  
  197.                 table = acpi_os_map_memory(acpi_tables_addr + table_offset,
  198.                                            ACPI_HEADER_SIZE);
  199.  
  200.                 if (table_offset + table->length > all_tables_size) {
  201.                         acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
  202.                         WARN_ON(1);
  203.                         return AE_OK;
  204.                 }
  205.  
  206.                 table_offset += table->length;
  207.  
  208.                 if (memcmp(existing_table->signature, table->signature, 4)) {
  209.                         acpi_os_unmap_memory(table,
  210.                                      ACPI_HEADER_SIZE);
  211.                         continue;
  212.                 }
  213.  
  214.                 /* Only override tables with matching oem id */
  215.                 if (memcmp(table->oem_table_id, existing_table->oem_table_id,
  216.                            ACPI_OEM_TABLE_ID_SIZE)) {
  217.                         acpi_os_unmap_memory(table,
  218.                                      ACPI_HEADER_SIZE);
  219.                         continue;
  220.                 }
  221.  
  222.                 table_offset -= table->length;
  223.                 *table_length = table->length;
  224.                 acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
  225.                 *address = acpi_tables_addr + table_offset;
  226.                 break;
  227.         } while (table_offset + ACPI_HEADER_SIZE < all_tables_size);
  228.  
  229.         if (*address != 0)
  230.                 acpi_table_taint(existing_table);
  231.         return AE_OK;
  232. #endif
  233. }
  234.  
  235.  
  236. static struct osi_linux {
  237.         unsigned int    enable:1;
  238.         unsigned int    dmi:1;
  239.         unsigned int    cmdline:1;
  240.         unsigned int    default_disabling:1;
  241.  
  242. } osi_linux = {0, 0, 0, 0};
  243.  
  244. #define OSI_STRING_LENGTH_MAX 64        /* arbitrary */
  245. #define OSI_STRING_ENTRIES_MAX 16       /* arbitrary */
  246.  
  247. struct osi_setup_entry {
  248.     char string[OSI_STRING_LENGTH_MAX];
  249.     bool enable;
  250. };
  251.  
  252. static struct osi_setup_entry
  253.         osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = {
  254.     {"Module Device", true},
  255.     {"Processor Device", true},
  256.     {"3.0 _SCP Extensions", true},
  257.     {"Processor Aggregator Device", true},
  258. };
  259. void __init acpi_osi_setup(char *str)
  260. {
  261.         struct osi_setup_entry *osi;
  262.         bool enable = true;
  263.         int i;
  264.  
  265.         if (!acpi_gbl_create_osi_method)
  266.                 return;
  267.  
  268.         if (str == NULL || *str == '\0') {
  269.                 printk(KERN_INFO PREFIX "_OSI method disabled\n");
  270.                 acpi_gbl_create_osi_method = FALSE;
  271.                 return;
  272.         }
  273.  
  274.         if (*str == '!') {
  275.                 str++;
  276.                 if (*str == '\0') {
  277.                         osi_linux.default_disabling = 1;
  278.                         return;
  279.                 } else if (*str == '*') {
  280.                         acpi_update_interfaces(ACPI_DISABLE_ALL_STRINGS);
  281.                         for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
  282.                                 osi = &osi_setup_entries[i];
  283.                                 osi->enable = false;
  284.                         }
  285.                         return;
  286.                 }
  287.                 enable = false;
  288.         }
  289.  
  290.         for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
  291.                 osi = &osi_setup_entries[i];
  292.                 if (!strcmp(osi->string, str)) {
  293.                         osi->enable = enable;
  294.                         break;
  295.                 } else if (osi->string[0] == '\0') {
  296.                         osi->enable = enable;
  297.                         strncpy(osi->string, str, OSI_STRING_LENGTH_MAX);
  298.                         break;
  299.                 }
  300.         }
  301. }
  302.  
  303. static void __init set_osi_linux(unsigned int enable)
  304. {
  305.     if (osi_linux.enable != enable)
  306.         osi_linux.enable = enable;
  307.  
  308.     if (osi_linux.enable)
  309.         acpi_osi_setup("Linux");
  310.     else
  311.         acpi_osi_setup("!Linux");
  312.  
  313.     return;
  314. }
  315.  
  316. void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
  317. {
  318.     printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
  319.  
  320.     if (enable == -1)
  321.         return;
  322.  
  323.     osi_linux.dmi = 1;  /* DMI knows that this box asks OSI(Linux) */
  324.     set_osi_linux(enable);
  325.  
  326.     return;
  327. }
  328.  
  329. acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
  330. {
  331.     void *sem = (void*)handle;
  332.  
  333.     if (!acpi_os_initialized)
  334.         return AE_OK;
  335.  
  336.     if (!sem || (units < 1))
  337.         return AE_BAD_PARAMETER;
  338.  
  339.     if (units > 1)
  340.         return AE_SUPPORT;
  341.  
  342.     ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n",
  343.                       handle, units, timeout));
  344.  
  345.     return AE_OK;
  346. }
  347.  
  348. acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
  349. {
  350.     void *sem = (void*)handle;
  351.  
  352.     if (!acpi_os_initialized)
  353.             return AE_OK;
  354.  
  355.     if (!sem || (units < 1))
  356.             return AE_BAD_PARAMETER;
  357.  
  358.     if (units > 1)
  359.             return AE_SUPPORT;
  360.  
  361.     ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Signaling semaphore[%p|%d]\n", handle,
  362.                       units));
  363.  
  364. //    up(sem);
  365.  
  366.     return AE_OK;
  367. }
  368.  
  369.  
  370. acpi_status __init acpi_os_initialize(void)
  371. {
  372. //    acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1a_event_block);
  373. //    acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1b_event_block);
  374. //    acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe0_block);
  375. //    acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe1_block);
  376.     if (acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) {
  377.             /*
  378.              * Use acpi_os_map_generic_address to pre-map the reset
  379.              * register if it's in system memory.
  380.              */
  381.             int rv;
  382.  
  383.             rv = acpi_os_map_generic_address(&acpi_gbl_FADT.reset_register);
  384.             pr_debug(PREFIX "%s: map reset_reg status %d\n", __func__, rv);
  385.     }
  386.     acpi_os_initialized = true;
  387.  
  388.     return AE_OK;
  389. }
  390.  
  391. acpi_status __init acpi_os_initialize1(void)
  392. {
  393. //        kacpid_wq = alloc_workqueue("kacpid", 0, 1);
  394. //        kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1);
  395. //        kacpi_hotplug_wq = alloc_ordered_workqueue("kacpi_hotplug", 0);
  396. //        BUG_ON(!kacpid_wq);
  397. //        BUG_ON(!kacpi_notify_wq);
  398. //       BUG_ON(!kacpi_hotplug_wq);
  399. //        acpi_install_interface_handler(acpi_osi_handler);
  400. //        acpi_osi_setup_late();
  401.         return AE_OK;
  402. }
  403.  
  404.  
  405. acpi_status acpi_os_delete_semaphore(acpi_handle handle)
  406. {
  407. //        void *sem = (void*)handle;
  408.  
  409. //        if (!sem)
  410. //            return AE_BAD_PARAMETER;
  411.  
  412. //        kfree(sem);
  413. //        sem = NULL;
  414.  
  415.         return AE_OK;
  416. }
  417.  
  418. acpi_status acpi_os_create_semaphore(u32 max_units,
  419.                          u32 initial_units, acpi_handle * out_handle)
  420. {
  421.     *out_handle = (acpi_handle) 1;
  422.     return (AE_OK);
  423. }
  424.  
  425. acpi_status
  426. acpi_os_create_mutex(acpi_handle * handle)
  427. {
  428.     struct mutex *mtx = NULL;
  429.  
  430.     mtx = kzalloc(sizeof(struct mutex),0);
  431.  
  432.     if (!mtx)
  433.             return AE_NO_MEMORY;
  434.  
  435.     mutex_init(mtx);
  436.  
  437.     *handle = (acpi_handle *) mtx;
  438.  
  439.      return AE_OK;
  440. }
  441.  
  442. void acpi_os_release_mutex(acpi_mutex handle)
  443. {
  444.     struct mutex *mtx = (struct mutex*)handle;
  445.  
  446.     if (!acpi_os_initialized)
  447.         return;
  448.  
  449.     mutex_unlock(mtx);
  450. }
  451.  
  452. acpi_status acpi_os_acquire_mutex(acpi_mutex handle, u16 timeout)
  453. {
  454.     struct mutex *mtx = (struct mutex*)handle;
  455.  
  456.     if (!acpi_os_initialized)
  457.         return AE_OK;
  458.  
  459.     mutex_lock(mtx);
  460.  
  461.     return AE_OK;
  462. }
  463.  
  464. void acpi_os_delete_mutex(acpi_mutex handle)
  465. {
  466.     struct mutex *mtx = (struct mutex*)handle;
  467.  
  468.     kfree(mtx);
  469. };
  470.  
  471. acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock lockp)
  472. {
  473.     acpi_cpu_flags flags;
  474.     spin_lock_irqsave(lockp, flags);
  475.     return flags;
  476. }
  477.  
  478.  
  479. void acpi_os_release_lock(acpi_spinlock lockp, acpi_cpu_flags flags)
  480. {
  481.     spin_unlock_irqrestore(lockp, flags);
  482. }
  483.  
  484.  
  485. acpi_status acpi_os_signal(u32 function, void *info)
  486. {
  487.         switch (function) {
  488.         case ACPI_SIGNAL_FATAL:
  489.                 printk(KERN_ERR PREFIX "Fatal opcode executed\n");
  490.                 break;
  491.         case ACPI_SIGNAL_BREAKPOINT:
  492.                 /*
  493.                  * AML Breakpoint
  494.                  * ACPI spec. says to treat it as a NOP unless
  495.                  * you are debugging.  So if/when we integrate
  496.                  * AML debugger into the kernel debugger its
  497.                  * hook will go here.  But until then it is
  498.                  * not useful to print anything on breakpoints.
  499.                  */
  500.                 break;
  501.         default:
  502.                 break;
  503.         }
  504.  
  505.         return AE_OK;
  506. }
  507.  
  508. void acpi_os_sleep(u64 ms)
  509. {
  510.         msleep(ms);
  511. }
  512.  
  513. void acpi_os_stall(u32 us)
  514. {
  515.         while (us) {
  516.                 u32 delay = 1000;
  517.  
  518.                 if (delay > us)
  519.                         delay = us;
  520.                 udelay(delay);
  521. //                touch_nmi_watchdog();
  522.                 us -= delay;
  523.         }
  524. }
  525.  
  526. void msleep(unsigned int msecs)
  527. {
  528.     msecs /= 10;
  529.     if(!msecs) msecs = 1;
  530.  
  531.      __asm__ __volatile__ (
  532.      "call *__imp__Delay"
  533.      ::"b" (msecs));
  534.      __asm__ __volatile__ (
  535.      "":::"ebx");
  536.  
  537. };
  538.  
  539. acpi_status acpi_os_execute(acpi_execute_type type,
  540.                             acpi_osd_exec_callback function, void *context)
  541. {
  542.  
  543.     return AE_OK;
  544. }
  545.  
  546.  
  547. u64 acpi_os_get_timer(void)
  548. {
  549.     u64 time_ns = ktime_to_ns(ktime_get());
  550.     do_div(time_ns, 100);
  551.     return time_ns;
  552. }
  553.  
  554. ktime_t ktime_get(void)
  555. {
  556.     ktime_t t;
  557.  
  558.     t.tv64 = GetClockNs();
  559.  
  560.     return t;
  561. }
  562.  
  563. void __delay(unsigned long loops)
  564. {
  565.         asm volatile(
  566.                 "test %0,%0\n"
  567.                 "jz 3f\n"
  568.                 "jmp 1f\n"
  569.  
  570.                 ".align 16\n"
  571.                 "1: jmp 2f\n"
  572.  
  573.                 ".align 16\n"
  574.                 "2: dec %0\n"
  575.                 " jnz 2b\n"
  576.                 "3: dec %0\n"
  577.  
  578.                 : /* we don't need output */
  579.                 : "a" (loops)
  580.         );
  581. }
  582.  
  583.  
  584. inline void __const_udelay(unsigned long xloops)
  585. {
  586.         int d0;
  587.  
  588.         xloops *= 4;
  589.         asm("mull %%edx"
  590.                 : "=d" (xloops), "=&a" (d0)
  591.                 : "1" (xloops), ""
  592.                 (loops_per_jiffy * (HZ/4)));
  593.  
  594.         __delay(++xloops);
  595. }
  596.  
  597. void __udelay(unsigned long usecs)
  598. {
  599.         __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */
  600. }
  601.  
  602.  
  603. #define acpi_rev_override       false
  604.  
  605. #define ACPI_MAX_OVERRIDE_LEN 100
  606.  
  607. static char acpi_os_name[ACPI_MAX_OVERRIDE_LEN];
  608.  
  609.  
  610. acpi_status
  611. acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
  612.                             char **new_val)
  613. {
  614.         if (!init_val || !new_val)
  615.                 return AE_BAD_PARAMETER;
  616.  
  617.         *new_val = NULL;
  618.         if (!memcmp(init_val->name, "_OS_", 4) && strlen(acpi_os_name)) {
  619.                 printk(KERN_INFO PREFIX "Overriding _OS definition to '%s'\n",
  620.                        acpi_os_name);
  621.                 *new_val = acpi_os_name;
  622.         }
  623.  
  624.         if (!memcmp(init_val->name, "_REV", 4) && acpi_rev_override) {
  625.                 printk(KERN_INFO PREFIX "Overriding _REV return value to 5\n");
  626.                 *new_val = (char *)5;
  627.         }
  628.  
  629.         return AE_OK;
  630. }
  631.  
  632.