feat: better rtc framework which aims to remove single rtc restrictions.
authorMinep <lunaixsky@qq.com>
Fri, 25 Aug 2023 22:17:18 +0000 (23:17 +0100)
committerMinep <lunaixsky@qq.com>
Fri, 25 Aug 2023 22:17:18 +0000 (23:17 +0100)
feat: user mode api for timer/rtc through fs mapping.
feat: interrupt handlers now have the option to accept customized payload.
refactor: creare a new device class of pseudo device, hope that it will clear things
refactor: move ps2 keyboard driver out of kernel code base.
fix: pcache is now abandon the use of valloc api, as the access is unaligned when allocating page size buffer.
fix: pcached write/read should use direct file i/o and must not failed with ENOMEM when buffer allocation failed.
chore: group the device file ops for better clarity

40 files changed:
lunaix-os/arch/i386/arch.c
lunaix-os/arch/i386/exceptions/i386_isrm.c
lunaix-os/hal/char/ps2kbd.c [moved from lunaix-os/kernel/peripheral/ps2kbd.c with 87% similarity]
lunaix-os/hal/rng/rngx86.c [new file with mode: 0644]
lunaix-os/hal/rtc/hwrtc.c
lunaix-os/hal/rtc/mc146818a.c
lunaix-os/hal/timer/apic_timer.c
lunaix-os/hal/timer/hwtimer.c
lunaix-os/includes/hal/apic_timer.h
lunaix-os/includes/hal/hwrtc.h
lunaix-os/includes/hal/hwtimer.h
lunaix-os/includes/hal/rnd.h [deleted file]
lunaix-os/includes/lunaix/device.h
lunaix-os/includes/lunaix/input.h
lunaix-os/includes/lunaix/isrm.h
lunaix-os/includes/lunaix/mm/cake.h
lunaix-os/includes/lunaix/peripheral/ps2kbd.h [deleted file]
lunaix-os/includes/usr/lunaix/ioctl_defs.h
lunaix-os/kernel/block/blkpart_gpt.c
lunaix-os/kernel/block/block.c
lunaix-os/kernel/device/builtin/devbuiltin.c [deleted file]
lunaix-os/kernel/device/builtin/devrand.c [deleted file]
lunaix-os/kernel/device/devfs.c
lunaix-os/kernel/device/device.c
lunaix-os/kernel/device/input.c
lunaix-os/kernel/device/pseudo/devnull.c [moved from lunaix-os/kernel/device/builtin/devnull.c with 66% similarity]
lunaix-os/kernel/device/pseudo/devpseudo.c [new file with mode: 0644]
lunaix-os/kernel/fs/iso9660/directory.c
lunaix-os/kernel/fs/iso9660/file.c
lunaix-os/kernel/fs/iso9660/inode.c
lunaix-os/kernel/fs/iso9660/mount.c
lunaix-os/kernel/fs/pcache.c
lunaix-os/kernel/fs/probe_boot.c
lunaix-os/kernel/kinit.c
lunaix-os/kernel/mm/cake.c
lunaix-os/kernel/mm/valloc.c
lunaix-os/kernel/proc0.c
lunaix-os/kernel/time/clock.c
lunaix-os/kernel/tty/lxconsole.c
lunaix-os/link/linker.ld

index afdc88c545244422965b662816a14150e081cb34..3de802df8b71c687ff577780ed14173399f1ddc9 100644 (file)
@@ -29,10 +29,10 @@ arch_preinit()
     isrm_bindiv(LUNAIX_SYS_CALL, syscall_hndlr);
 }
 
     isrm_bindiv(LUNAIX_SYS_CALL, syscall_hndlr);
 }
 
-struct hwtimer_context*
+struct hwtimer*
 hwtimer_choose()
 {
 hwtimer_choose()
 {
-    struct hwtimer_context* timer;
+    struct hwtimer* timer;
 
     timer = apic_hwtimer_context();
     if (timer->supported(timer)) {
 
     timer = apic_hwtimer_context();
     if (timer->supported(timer)) {
@@ -42,12 +42,4 @@ hwtimer_choose()
     // TODO select alternatives...
 
     panick("no timer to use.");
     // TODO select alternatives...
 
     panick("no timer to use.");
-}
-
-struct hwrtc*
-hwrtc_choose()
-{
-    struct hwrtc* rtc = mc146818a_rtc_context();
-
-    return rtc;
 }
\ No newline at end of file
 }
\ No newline at end of file
index 1d5950ef37e1a4c12d023cf41c6722b29656a5b0..2aabc39214711f8443c340301cc72ece00c0e53d 100644 (file)
@@ -12,6 +12,7 @@
 
 static char iv_bmp[(IV_EX_END - IV_BASE_END) / 8];
 static isr_cb handlers[TOTAL_IV];
 
 static char iv_bmp[(IV_EX_END - IV_BASE_END) / 8];
 static isr_cb handlers[TOTAL_IV];
+static ptr_t ivhand_payload[TOTAL_IV];
 
 extern void
 intr_routine_fallback(const isr_param* param);
 
 extern void
 intr_routine_fallback(const isr_param* param);
@@ -117,4 +118,20 @@ isrm_get(int iv)
     assert(iv < 256);
 
     return handlers[iv];
     assert(iv < 256);
 
     return handlers[iv];
+}
+
+ptr_t
+isrm_get_payload(int iv)
+{
+    assert(iv < 256);
+
+    return ivhand_payload[iv];
+}
+
+void
+isrm_set_payload(int iv, ptr_t payload)
+{
+    assert(iv < 256);
+
+    ivhand_payload[iv] = payload;
 }
\ No newline at end of file
 }
\ No newline at end of file
similarity index 87%
rename from lunaix-os/kernel/peripheral/ps2kbd.c
rename to lunaix-os/hal/char/ps2kbd.c
index 8ba1b91e6d5f89258d8dda5a3d4211db9f079637..47c866d09ada47b39c664db04705f7c5c758c9b4 100644 (file)
 #include <lunaix/clock.h>
 #include <lunaix/clock.h>
+#include <lunaix/ds/mutex.h>
 #include <lunaix/input.h>
 #include <lunaix/isrm.h>
 #include <lunaix/input.h>
 #include <lunaix/isrm.h>
-#include <lunaix/peripheral/ps2kbd.h>
+#include <lunaix/keyboard.h>
 #include <lunaix/syslog.h>
 #include <lunaix/timer.h>
 
 #include <hal/intc.h>
 #include <lunaix/syslog.h>
 #include <lunaix/timer.h>
 
 #include <hal/intc.h>
-#include <sys/cpu.h>
 
 #include <klibc/string.h>
 
 
 #include <klibc/string.h>
 
+#include <sys/cpu.h>
 #include <sys/interrupts.h>
 #include <sys/port_io.h>
 
 #include <sys/interrupts.h>
 #include <sys/port_io.h>
 
+#define PS2_PORT_ENC_DATA 0x60
+#define PS2_PORT_ENC_CMDREG 0x60
+#define PS2_PORT_CTRL_STATUS 0x64
+#define PS2_PORT_CTRL_CMDREG 0x64
+
+#define PS2_STATUS_OFULL 0x1
+#define PS2_STATUS_IFULL 0x2
+
+#define PS2_RESULT_ACK 0xfa
+#define PS2_RESULT_NAK 0xfe // resend
+#define PS2_RESULT_ECHO 0xee
+#define PS2_RESULT_TEST_OK 0x55
+
+// PS/2 keyboard device related commands
+#define PS2_KBD_CMD_SETLED 0xed
+#define PS2_KBD_CMD_ECHO 0xee
+#define PS2_KBD_CMD_SCANCODE_SET 0xf0
+#define PS2_KBD_CMD_IDENTIFY 0xf2
+#define PS2_KBD_CMD_SCAN_ENABLE 0xf4
+#define PS2_KBD_CMD_SCAN_DISABLE 0xf5
+
+// PS/2 *controller* related commands
+#define PS2_CMD_PORT1_DISABLE 0xad
+#define PS2_CMD_PORT1_ENABLE 0xae
+#define PS2_CMD_PORT2_DISABLE 0xa7
+#define PS2_CMD_PORT2_ENABLE 0xa8
+#define PS2_CMD_SELFTEST 0xaa
+#define PS2_CMD_SELFTEST_PORT1 0xab
+
+#define PS2_CMD_READ_CFG 0x20
+#define PS2_CMD_WRITE_CFG 0x60
+
+#define PS2_CFG_P1INT 0x1
+#define PS2_CFG_P2INT 0x2
+#define PS2_CFG_TRANSLATION 0x40
+
+#define PS2_DELAY 1000
+
+#define PS2_CMD_QUEUE_SIZE 8
+
+#define PS2_NO_ARG 0xff00
+
+struct ps2_cmd
+{
+    char cmd;
+    char arg;
+};
+
+struct ps2_kbd_state
+{
+    volatile char state;
+    volatile char masked;
+    volatile kbd_kstate_t key_state;
+    kbd_keycode_t* translation_table;
+};
+
+struct ps2_cmd_queue
+{
+    struct ps2_cmd cmd_queue[PS2_CMD_QUEUE_SIZE];
+    int queue_ptr;
+    int queue_len;
+    mutex_t mutex;
+};
+
+/**
+ * @brief 向PS/2控制器的控制端口(0x64)发送指令并等待返回代码。
+ * 注意,对于没有返回代码的命令请使用`ps2_post_cmd`,否则会造成死锁。
+ * 通过调用该方法向控制器发送指令,请区别 ps2_issue_dev_cmd
+ *
+ * @param cmd
+ * @param args
+ */
+static u8_t
+ps2_issue_cmd(char cmd, u16_t arg);
+
+/**
+ * @brief 向PS/2控制器的编码器端口(0x60)发送指令并等待返回代码。
+ * 注意,对于没有返回代码的命令请使用`ps2_post_cmd`,否则会造成死锁。
+ * 通过调用该方法向PS/2设备发送指令,请区别 ps2_issue_cmd
+ *
+ * @param cmd
+ * @param args
+ */
+static u8_t
+ps2_issue_dev_cmd(char cmd, u16_t arg);
+
+/**
+ * @brief 向PS/2控制器发送指令,不等待返回代码。
+ *
+ * @param port 端口号
+ * @param cmd
+ * @param args
+ * @return char
+ */
+static void
+ps2_post_cmd(u8_t port, char cmd, u16_t arg);
+
+static void
+ps2_device_post_cmd(char cmd, char arg);
+
+static void
+ps2_kbd_init();
+
+static void
+ps2_process_cmd(void* arg);
+
 #define PS2_DEV_CMD_MAX_ATTEMPTS 5
 
 LOG_MODULE("i8042");
 #define PS2_DEV_CMD_MAX_ATTEMPTS 5
 
 LOG_MODULE("i8042");
@@ -82,13 +189,13 @@ static struct input_device* kbd_idev;
 #define KBD_ENABLE_SPIRQ_FIX2
 // #define KBD_DBGLOG
 
 #define KBD_ENABLE_SPIRQ_FIX2
 // #define KBD_DBGLOG
 
-void
+static void
 intr_ps2_kbd_handler(const isr_param* param);
 
 static u8_t
 ps2_issue_cmd_wretry(char cmd, u16_t arg);
 
 intr_ps2_kbd_handler(const isr_param* param);
 
 static u8_t
 ps2_issue_cmd_wretry(char cmd, u16_t arg);
 
-void
+static void
 ps2_device_post_cmd(char cmd, char arg)
 {
     mutex_lock(&cmd_q.mutex);
 ps2_device_post_cmd(char cmd, char arg)
 {
     mutex_lock(&cmd_q.mutex);
@@ -215,8 +322,9 @@ ps2_kbd_init()
 
     cpu_enable_interrupt();
 }
 
     cpu_enable_interrupt();
 }
+EXPORT_INPUT_DEV(i8042_keyboard, ps2_kbd_init);
 
 
-void
+static void
 ps2_process_cmd(void* arg)
 {
     /*
 ps2_process_cmd(void* arg)
 {
     /*
@@ -255,7 +363,7 @@ ps2_process_cmd(void* arg)
     cmd_q.queue_len--;
 }
 
     cmd_q.queue_len--;
 }
 
-void
+static void
 kbd_buffer_key_event(kbd_keycode_t key, u8_t scancode, kbd_kstate_t state)
 {
     /*
 kbd_buffer_key_event(kbd_keycode_t key, u8_t scancode, kbd_kstate_t state)
 {
     /*
@@ -299,7 +407,7 @@ kbd_buffer_key_event(kbd_keycode_t key, u8_t scancode, kbd_kstate_t state)
     }
 }
 
     }
 }
 
-void
+static void
 intr_ps2_kbd_handler(const isr_param* param)
 {
 
 intr_ps2_kbd_handler(const isr_param* param)
 {
 
diff --git a/lunaix-os/hal/rng/rngx86.c b/lunaix-os/hal/rng/rngx86.c
new file mode 100644 (file)
index 0000000..aea9b69
--- /dev/null
@@ -0,0 +1,38 @@
+#include <lunaix/device.h>
+#include <lunaix/mm/page.h>
+
+static inline void
+rng_fill(void* data, size_t len)
+{
+    asm volatile("1:\n"
+                 "rdrand %%eax\n"
+                 "movl %%eax, (%0)\n"
+                 "addl $4, %%eax\n"
+                 "subl $4, %1\n"
+                 "jnz 1b" ::"r"((ptr_t)data),
+                 "r"((len & ~0x3))
+                 : "%eax");
+}
+
+static int
+__rand_rd_pg(struct device* dev, void* buf, size_t offset)
+{
+    rng_fill(buf, PG_SIZE);
+    return PG_SIZE;
+}
+
+static int
+__rand_rd(struct device* dev, void* buf, size_t offset, size_t len)
+{
+    rng_fill(buf, len);
+    return len;
+}
+
+void
+pdev_randdev_init()
+{
+    struct device* devrand = device_addseq(NULL, NULL, "rand");
+    devrand->ops.read = __rand_rd;
+    devrand->ops.read_page = __rand_rd_pg;
+}
+EXPORT_PSEUDODEV(randdev, pdev_randdev_init);
\ No newline at end of file
index 8da6e22ae105d92ab1bd85b22de21b0292be0371..c3fc1977fdb806bbd63ea33b87b42ccb7e901c87 100644 (file)
 #include <hal/hwrtc.h>
 
 #include <hal/hwrtc.h>
 
-const struct hwrtc* current_rtc;
+#include <lunaix/fs/twifs.h>
+#include <lunaix/fs/twimap.h>
+#include <lunaix/mm/valloc.h>
+#include <lunaix/status.h>
+
+#include <usr/lunaix/ioctl_defs.h>
+
+const struct hwrtc* primary_rtc;
+static int rtc_count = 0;
+
+DEFINE_LLIST(rtcs);
 
 void
 hwrtc_init()
 {
 
 void
 hwrtc_init()
 {
-    current_rtc = hwrtc_choose();
-
-    current_rtc->init(current_rtc);
+    ptr_t init;
+    int index;
+    ldga_foreach(rtcdev, ptr_t, index, init)
+    {
+        ((void (*)())init)();
+    }
 }
 
 void
 hwrtc_walltime(datetime_t* dt)
 {
 }
 
 void
 hwrtc_walltime(datetime_t* dt)
 {
-    current_rtc->get_walltime(current_rtc, dt);
-}
\ No newline at end of file
+    primary_rtc->get_walltime(primary_rtc, dt);
+}
+
+static int
+hwrtc_ioctl(struct device* dev, u32_t req, va_list args)
+{
+    struct hwrtc* rtc = (struct hwrtc*)dev->underlay;
+    switch (req) {
+        case RTCIO_IMSK:
+            rtc->set_mask(rtc);
+            break;
+        case RTCIO_IUNMSK:
+            rtc->cls_mask(rtc);
+            break;
+        case RTCIO_SETDT:
+            datetime_t* dt = va_arg(args, datetime_t*);
+            rtc->set_walltime(rtc, dt);
+            break;
+        case RTCIO_SETFREQ:
+            ticks_t* freq = va_arg(args, ticks_t*);
+
+            if (!freq) {
+                return EINVAL;
+            }
+            if (*freq) {
+                return rtc->chfreq(rtc, *freq);
+            }
+
+            *freq = rtc->base_freq;
+
+            break;
+        default:
+            return EINVAL;
+    }
+
+    return 0;
+}
+
+static int
+hwrtc_read(struct device* dev, void* buf, size_t offset, size_t len)
+{
+    struct hwrtc* rtc = (struct hwrtc*)dev->underlay;
+    *((ticks_t*)buf) = rtc->get_counts(rtc);
+
+    return sizeof(ticks_t);
+}
+
+struct hwrtc*
+hwrtc_alloc_new(char* name)
+{
+    struct hwrtc* rtc_instance = valloc(sizeof(struct hwrtc));
+
+    if (!rtc_instance) {
+        return NULL;
+    }
+
+    llist_append(&rtcs, &rtc_instance->rtc_list);
+
+    if (!primary_rtc) {
+        primary_rtc = rtc_instance;
+    }
+
+    rtc_instance->name = name;
+    struct device* rtcdev =
+      device_addsys(NULL, rtc_instance, "rtc%d", rtc_count);
+
+    rtcdev->ops.exec_cmd = hwrtc_ioctl;
+    rtcdev->ops.read = hwrtc_read;
+
+    rtc_instance->rtc_dev = rtcdev;
+
+    rtc_count++;
+
+    return rtc_instance;
+}
+
+static void
+__hwrtc_readinfo(struct twimap* mapping)
+{
+    struct hwrtc* rtc = twimap_data(mapping, struct hwrtc*);
+    twimap_printf(mapping, "device: %s\n", rtc->name);
+    twimap_printf(mapping, "frequency: %dHz\n", rtc->base_freq);
+    twimap_printf(mapping, "ticks count: %d\n", rtc->get_counts(rtc));
+    twimap_printf(
+      mapping, "ticking: %s\n", (rtc->state & RTC_STATE_MASKED) ? "no" : "yes");
+
+    datetime_t dt;
+    rtc->get_walltime(rtc, &dt);
+
+    twimap_printf(
+      mapping, "recorded date: %d/%d/%d\n", dt.year, dt.month, dt.day);
+    twimap_printf(
+      mapping, "recorded time: %d:%d:%d\n", dt.hour, dt.minute, dt.second);
+    twimap_printf(mapping, "recorded weekday: %d\n", dt.weekday);
+}
+
+static void
+hwrtc_twifs_export(struct hwrtc* rtc)
+{
+    const char* name = rtc->rtc_dev->name.value;
+    struct twimap* rtc_mapping = twifs_mapping(NULL, rtc, name);
+    rtc_mapping->read = __hwrtc_readinfo;
+}
+
+static void
+hwrtc_twifs_export_all()
+{
+    struct hwrtc *pos, *next;
+    llist_for_each(pos, next, &rtcs, rtc_list)
+    {
+        hwrtc_twifs_export(pos);
+    }
+}
+EXPORT_TWIFS_PLUGIN(rtc_fsexport, hwrtc_twifs_export_all);
\ No newline at end of file
index 98ea807c37e41053cf2b3eee49822e1520427f23..1a507653192df1d5a5d40cdba38a89b3a6718955 100644 (file)
@@ -11,6 +11,8 @@
  */
 
 #include <lunaix/isrm.h>
  */
 
 #include <lunaix/isrm.h>
+#include <lunaix/mm/valloc.h>
+#include <lunaix/status.h>
 
 #include <hal/rtc/mc146818a.h>
 
 
 #include <hal/rtc/mc146818a.h>
 
 #define RTC_REG_C 0xC
 #define RTC_REG_D 0xD
 
 #define RTC_REG_C 0xC
 #define RTC_REG_D 0xD
 
+#define RTC_SET 0x80
+#define RTC_BIN (1 << 2)
+#define RTC_HOURFORM24 (1 << 1)
+
 #define RTC_BIN_ENCODED(reg) (reg & 0x04)
 #define RTC_24HRS_ENCODED(reg) (reg & 0x02)
 
 #define RTC_BIN_ENCODED(reg) (reg & 0x04)
 #define RTC_24HRS_ENCODED(reg) (reg & 0x02)
 
@@ -52,8 +58,7 @@ struct mc146818
 {
     struct hwrtc* rtc_context;
     u32_t rtc_iv;
 {
     struct hwrtc* rtc_context;
     u32_t rtc_iv;
-    int ticking;
-    void (*on_tick_cb)(const struct hwrtc*);
+    u32_t tick_counts;
 };
 
 #define rtc_state(data) ((struct mc146818*)(data))
 };
 
 #define rtc_state(data) ((struct mc146818*)(data))
@@ -72,28 +77,22 @@ rtc_write_reg(u8_t reg_selector, u8_t val)
     port_wrbyte(RTC_TARGET_PORT, val);
 }
 
     port_wrbyte(RTC_TARGET_PORT, val);
 }
 
-static u8_t
-bcd2dec(u8_t bcd)
-{
-    return ((bcd & 0xF0) >> 1) + ((bcd & 0xF0) >> 3) + (bcd & 0xf);
-}
-
 static void
 rtc_enable_timer()
 {
 static void
 rtc_enable_timer()
 {
-    u8_t regB = rtc_read_reg(RTC_REG_B | WITH_NMI_DISABLED);
-    rtc_write_reg(RTC_REG_B | WITH_NMI_DISABLED, regB | RTC_TIMER_ON);
+    u8_t regB = rtc_read_reg(RTC_REG_B);
+    rtc_write_reg(RTC_REG_B, regB | RTC_TIMER_ON);
 }
 
 static void
 rtc_disable_timer()
 {
 }
 
 static void
 rtc_disable_timer()
 {
-    u8_t regB = rtc_read_reg(RTC_REG_B | WITH_NMI_DISABLED);
-    rtc_write_reg(RTC_REG_B | WITH_NMI_DISABLED, regB & ~RTC_TIMER_ON);
+    u8_t regB = rtc_read_reg(RTC_REG_B);
+    rtc_write_reg(RTC_REG_B, regB & ~RTC_TIMER_ON);
 }
 
 static void
 }
 
 static void
-clock_walltime(struct hwrtc* rtc, datetime_t* datetime)
+rtc_getwalltime(struct hwrtc* rtc, datetime_t* datetime)
 {
     datetime_t current;
 
 {
     datetime_t current;
 
@@ -111,24 +110,26 @@ clock_walltime(struct hwrtc* rtc, datetime_t* datetime)
         datetime->second = rtc_read_reg(RTC_REG_SEC);
     } while (!datatime_eq(datetime, &current));
 
         datetime->second = rtc_read_reg(RTC_REG_SEC);
     } while (!datatime_eq(datetime, &current));
 
-    u8_t regbv = rtc_read_reg(RTC_REG_B);
+    datetime->year += RTC_CURRENT_CENTRY * 100;
+}
 
 
-    // Convert from bcd to binary when needed
-    if (!RTC_BIN_ENCODED(regbv)) {
-        datetime->year = bcd2dec(datetime->year);
-        datetime->month = bcd2dec(datetime->month);
-        datetime->day = bcd2dec(datetime->day);
-        datetime->hour = bcd2dec(datetime->hour);
-        datetime->minute = bcd2dec(datetime->minute);
-        datetime->second = bcd2dec(datetime->second);
-    }
+static void
+rtc_setwalltime(struct hwrtc* rtc, datetime_t* datetime)
+{
+    u8_t reg = rtc_read_reg(RTC_REG_B);
+    reg = reg & ~RTC_SET;
 
 
-    // To 24 hour format
-    if (!RTC_24HRS_ENCODED(regbv) && (datetime->hour >> 7)) {
-        datetime->hour = 12 + (datetime->hour & 0x80);
-    }
+    rtc_write_reg(RTC_REG_B, reg | RTC_SET);
 
 
-    datetime->year += RTC_CURRENT_CENTRY * 100;
+    rtc_write_reg(RTC_REG_YRS, datetime->year - RTC_CURRENT_CENTRY * 100);
+    rtc_write_reg(RTC_REG_MTH, datetime->month);
+    rtc_write_reg(RTC_REG_DAY, datetime->day);
+    rtc_write_reg(RTC_REG_WDY, datetime->weekday);
+    rtc_write_reg(RTC_REG_HRS, datetime->hour);
+    rtc_write_reg(RTC_REG_MIN, datetime->minute);
+    rtc_write_reg(RTC_REG_SEC, datetime->second);
+
+    rtc_write_reg(RTC_REG_B, reg & ~RTC_SET);
 }
 
 static int
 }
 
 static int
@@ -142,78 +143,74 @@ mc146818_check_support(struct hwrtc* rtc)
 }
 
 static void
 }
 
 static void
-rtc_init(struct hwrtc* rtc)
+__rtc_tick(const isr_param* param)
 {
 {
-    u8_t regA = rtc_read_reg(RTC_REG_A | WITH_NMI_DISABLED);
-    regA = (regA & ~0x7f) | RTC_FREQUENCY_1024HZ | RTC_DIVIDER_33KHZ;
-    rtc_write_reg(RTC_REG_A | WITH_NMI_DISABLED, regA);
+    struct mc146818* state =
+      (struct mc146818*)isrm_get_payload(param->execp->vector);
 
 
-    rtc_state(rtc->data)->rtc_context = rtc;
+    state->tick_counts++;
 
 
-    // Make sure the rtc timer is disabled by default
-    rtc_disable_timer();
+    (void)rtc_read_reg(RTC_REG_C);
 }
 
 }
 
-static struct mc146818 rtc_state = { .ticking = 0 };
-
 static void
 static void
-__rtc_tick(const isr_param* param)
+rtc_set_mask(struct hwrtc* rtc)
 {
 {
-    rtc_state.on_tick_cb(rtc_state.rtc_context);
-
-    (void)rtc_read_reg(RTC_REG_C);
+    rtc->state = RTC_STATE_MASKED;
+    rtc_disable_timer();
 }
 
 static void
 }
 
 static void
-rtc_do_ticking(struct hwrtc* rtc, void (*on_tick)())
+rtc_cls_mask(struct hwrtc* rtc)
 {
 {
-    if (!on_tick || rtc_state(rtc->data)->ticking) {
-        return;
-    }
-
     struct mc146818* state = rtc_state(rtc->data);
     struct mc146818* state = rtc_state(rtc->data);
-    state->ticking = 1;
-    state->on_tick_cb = on_tick;
-
-    /* We realise that using rtc to tick something has an extremely rare use
-     * case (e.g., calibrating some timer). Therefore, we will release this
-     * allocated IV when rtc ticking is no longer required to save IV
-     * resources.
-     */
-    state->rtc_iv = isrm_bindirq(PC_AT_IRQ_RTC, __rtc_tick);
 
 
+    rtc->state = 0;
+    state->tick_counts = 0;
     rtc_enable_timer();
 }
 
     rtc_enable_timer();
 }
 
-static void
-rtc_end_ticking(struct hwrtc* rtc)
+static int
+rtc_chfreq(struct hwrtc* rtc, int freq)
 {
 {
-    if (!rtc_state(rtc->data)->ticking) {
-        return;
-    }
+    return ENOTSUP;
+}
 
 
-    rtc_disable_timer();
+static int
+rtc_getcnt(struct hwrtc* rtc)
+{
+    struct mc146818* state = rtc_state(rtc->data);
+    return state->tick_counts;
+}
 
 
-    // do some delay, ensure there is no more interrupt from rtc before we
-    // release isr
-    port_delay(1000);
+static void
+rtc_init()
+{
+    u8_t reg = rtc_read_reg(RTC_REG_A);
+    reg = (reg & ~0x7f) | RTC_FREQUENCY_1024HZ | RTC_DIVIDER_33KHZ;
+    rtc_write_reg(RTC_REG_A, reg);
 
 
-    isrm_ivfree(rtc_state(rtc->data)->rtc_iv);
+    reg = RTC_BIN | RTC_HOURFORM24;
+    rtc_write_reg(RTC_REG_B, reg);
 
 
-    rtc_state(rtc->data)->ticking = 0;
-}
+    // Make sure the rtc timer is disabled by default
+    rtc_disable_timer();
 
 
-static struct hwrtc hwrtc_mc146818a = { .name = "mc146818a",
-                                        .data = &rtc_state,
-                                        .init = rtc_init,
-                                        .base_freq = RTC_TIMER_BASE_FREQUENCY,
-                                        .supported = mc146818_check_support,
-                                        .get_walltime = clock_walltime,
-                                        .do_ticking = rtc_do_ticking,
-                                        .end_ticking = rtc_end_ticking };
-
-struct hwrtc*
-mc146818a_rtc_context()
-{
-    return &hwrtc_mc146818a;
+    struct hwrtc* rtc = hwrtc_alloc_new("mc146818");
+    struct mc146818* state = valloc(sizeof(struct mc146818));
+
+    state->rtc_context = rtc;
+    state->rtc_iv = isrm_bindirq(PC_AT_IRQ_RTC, __rtc_tick);
+    isrm_set_payload(state->rtc_iv, (ptr_t)state);
+
+    rtc->state = RTC_STATE_MASKED;
+    rtc->data = state;
+    rtc->base_freq = RTC_TIMER_BASE_FREQUENCY;
+    rtc->get_walltime = rtc_getwalltime;
+    rtc->set_walltime = rtc_setwalltime;
+    rtc->set_mask = rtc_set_mask;
+    rtc->cls_mask = rtc_cls_mask;
+    rtc->get_counts = rtc_getcnt;
+    rtc->chfreq = rtc_chfreq;
 }
 }
+EXPORT_RTC_DEVICE(mc146818, rtc_init);
\ No newline at end of file
index 2d3dad54344e37bd91d1d6ba3def5dd0569c82c8..15b3e827ef2f14ad064f7432ac49224527ebde22 100644 (file)
 LOG_MODULE("APIC_TIMER")
 
 #define LVT_ENTRY_TIMER(vector, mode) (LVT_DELIVERY_FIXED | mode | vector)
 LOG_MODULE("APIC_TIMER")
 
 #define LVT_ENTRY_TIMER(vector, mode) (LVT_DELIVERY_FIXED | mode | vector)
-#define APIC_CALIBRATION_CONST 0x100000
+#define APIC_BASETICKS 0x100000
 
 // Don't optimize them! Took me an half hour to figure that out...
 
 
 // Don't optimize them! Took me an half hour to figure that out...
 
-static volatile u32_t rtc_counter = 0;
 static volatile u8_t apic_timer_done = 0;
 static volatile ticks_t base_freq = 0;
 static volatile ticks_t systicks = 0;
 
 static timer_tick_cb tick_cb = NULL;
 
 static volatile u8_t apic_timer_done = 0;
 static volatile ticks_t base_freq = 0;
 static volatile ticks_t systicks = 0;
 
 static timer_tick_cb tick_cb = NULL;
 
-static void
-__rtc_on_tick_cb(struct hwrtc* param)
-{
-    rtc_counter++;
-}
-
 static void
 temp_intr_routine_apic_timer(const isr_param* param)
 {
 static void
 temp_intr_routine_apic_timer(const isr_param* param)
 {
-    base_freq = APIC_CALIBRATION_CONST / rtc_counter * current_rtc->base_freq;
     apic_timer_done = 1;
 }
 
     apic_timer_done = 1;
 }
 
@@ -47,7 +39,7 @@ apic_timer_tick_isr(const isr_param* param)
 }
 
 static int
 }
 
 static int
-apic_timer_check(struct hwtimer_context* hwt)
+apic_timer_check(struct hwtimer* hwt)
 {
     // TODO check whether apic timer is supported
     return 1;
 {
     // TODO check whether apic timer is supported
     return 1;
@@ -66,9 +58,7 @@ apic_get_base_freq()
 }
 
 void
 }
 
 void
-apic_timer_init(struct hwtimer_context* timer,
-                u32_t hertz,
-                timer_tick_cb timer_cb)
+apic_timer_init(struct hwtimer* timer, u32_t hertz, timer_tick_cb timer_cb)
 {
     ticks_t frequency = hertz;
     tick_cb = timer_cb;
 {
     ticks_t frequency = hertz;
     tick_cb = timer_cb;
@@ -123,21 +113,23 @@ apic_timer_init(struct hwtimer_context* timer,
     }
 #endif
 
     }
 #endif
 
-    rtc_counter = 0;
     apic_timer_done = 0;
 
     apic_timer_done = 0;
 
-    current_rtc->do_ticking(current_rtc, __rtc_on_tick_cb);
-    apic_write_reg(APIC_TIMER_ICR, APIC_CALIBRATION_CONST); // start APIC timer
+    primary_rtc->cls_mask(primary_rtc);
+    apic_write_reg(APIC_TIMER_ICR, APIC_BASETICKS); // start APIC timer
 
     // enable interrupt, just for our RTC start ticking!
     cpu_enable_interrupt();
 
     wait_until(apic_timer_done);
 
 
     // enable interrupt, just for our RTC start ticking!
     cpu_enable_interrupt();
 
     wait_until(apic_timer_done);
 
-    current_rtc->end_ticking(current_rtc);
-
     cpu_disable_interrupt();
 
     cpu_disable_interrupt();
 
+    primary_rtc->set_mask(primary_rtc);
+
+    base_freq = primary_rtc->get_counts(primary_rtc);
+    base_freq = APIC_BASETICKS / base_freq * primary_rtc->base_freq;
+
     assert_msg(base_freq, "Fail to initialize timer (NOFREQ)");
 
     kprintf(KINFO "hw: %u Hz; os: %u Hz\n", base_freq, frequency);
     assert_msg(base_freq, "Fail to initialize timer (NOFREQ)");
 
     kprintf(KINFO "hw: %u Hz; os: %u Hz\n", base_freq, frequency);
@@ -155,13 +147,13 @@ apic_timer_init(struct hwtimer_context* timer,
     apic_write_reg(APIC_TIMER_ICR, tphz);
 }
 
     apic_write_reg(APIC_TIMER_ICR, tphz);
 }
 
-struct hwtimer_context*
+struct hwtimer*
 apic_hwtimer_context()
 {
 apic_hwtimer_context()
 {
-    static struct hwtimer_context apic_hwt = { .name = "apic_timer",
-                                               .init = apic_timer_init,
-                                               .supported = apic_timer_check,
-                                               .systicks = apic_get_systicks };
+    static struct hwtimer apic_hwt = { .name = "apic_timer",
+                                       .init = apic_timer_init,
+                                       .supported = apic_timer_check,
+                                       .systicks = apic_get_systicks };
 
     return &apic_hwt;
 }
 
     return &apic_hwt;
 }
index bd6477a6173077c287ff93632ce222a2358ed01a..3a79ca1a7ec6d773521e8f8b7ff321b04526d406 100644 (file)
@@ -1,18 +1,9 @@
 #include <hal/hwtimer.h>
 #include <lunaix/spike.h>
 
 #include <hal/hwtimer.h>
 #include <lunaix/spike.h>
 
-struct hwtimer_context* current_timer;
+#include <usr/lunaix/ioctl_defs.h>
 
 
-void
-hwtimer_init(u32_t hertz, void* tick_callback)
-{
-    struct hwtimer_context* hwt_ctx = hwtimer_choose();
-
-    hwt_ctx->init(hwt_ctx, hertz, tick_callback);
-    hwt_ctx->running_freq = hertz;
-
-    current_timer = hwt_ctx;
-}
+struct hwtimer* current_timer;
 
 ticks_t
 hwtimer_base_frequency()
 
 ticks_t
 hwtimer_base_frequency()
@@ -37,4 +28,34 @@ hwtimer_to_ticks(u32_t value, int unit)
     ticks_t freq_ms = current_timer->running_freq / 1000;
 
     return freq_ms * value;
     ticks_t freq_ms = current_timer->running_freq / 1000;
 
     return freq_ms * value;
+}
+
+static int
+__hwtimer_ioctl(struct device* dev, u32_t req, va_list args)
+{
+    struct hwtimer* hwt = (struct hwtimer*)dev->underlay;
+    switch (req) {
+        case TIMERIO_GETINFO:
+            // TODO
+            break;
+
+        default:
+            break;
+    }
+    return 0;
+}
+
+void
+hwtimer_init(u32_t hertz, void* tick_callback)
+{
+    struct hwtimer* hwt_ctx = hwtimer_choose();
+
+    hwt_ctx->init(hwt_ctx, hertz, tick_callback);
+    hwt_ctx->running_freq = hertz;
+
+    current_timer = hwt_ctx;
+
+    struct device* timerdev = device_addsys(NULL, hwt_ctx, hwt_ctx->name);
+
+    timerdev->ops.exec_cmd = __hwtimer_ioctl;
 }
\ No newline at end of file
 }
\ No newline at end of file
index a076354ee23a7dcc922d04f980c9f2143612262a..186149b6f15c8d7d0969b24a1afad5714562fef9 100644 (file)
@@ -3,6 +3,6 @@
 
 #include <hal/hwtimer.h>
 
 
 #include <hal/hwtimer.h>
 
-struct hwtimer_context* apic_hwtimer_context();
+struct hwtimer* apic_hwtimer_context();
 
 #endif /* __LUNAIX_APIC_TIMER_H */
 
 #endif /* __LUNAIX_APIC_TIMER_H */
index b43a2ff9304b21ec7f7994dfe24d2c76a78425d8..fcd4d48a5f2ddccc6599fc51463b1e4304e5f898 100644 (file)
@@ -1,31 +1,41 @@
 #ifndef __LUNAIX_HWRTC_H
 #define __LUNAIX_HWRTC_H
 
 #ifndef __LUNAIX_HWRTC_H
 #define __LUNAIX_HWRTC_H
 
+#include <lunaix/device.h>
+#include <lunaix/ds/ldga.h>
+#include <lunaix/ds/llist.h>
 #include <lunaix/time.h>
 
 #include <lunaix/time.h>
 
+#define RTC_STATE_MASKED 0x1
+
+#define EXPORT_RTC_DEVICE(id, init_fn)                                         \
+    export_ldga_el(rtcdev, id, ptr_t, init_fn)
+
 struct hwrtc
 {
 struct hwrtc
 {
+    struct llist_header rtc_list;
+    struct device* rtc_dev;
+
     char* name;
     void* data;
     char* name;
     void* data;
-
     ticks_t base_freq;
     ticks_t base_freq;
-
-    int (*supported)(struct hwrtc*);
-    void (*init)(struct hwrtc*);
+    int state;
 
     void (*get_walltime)(struct hwrtc*, datetime_t*);
 
     void (*get_walltime)(struct hwrtc*, datetime_t*);
-
-    void (*do_ticking)(struct hwrtc*, void (*on_tick)());
-    void (*end_ticking)(struct hwrtc*);
+    void (*set_walltime)(struct hwrtc*, datetime_t*);
+    void (*set_mask)(struct hwrtc*);
+    void (*cls_mask)(struct hwrtc*);
+    int (*get_counts)(struct hwrtc*);
+    int (*chfreq)(struct hwrtc*, int);
 };
 
 };
 
-extern const struct hwrtc* current_rtc;
+extern const struct hwrtc* primary_rtc;
 
 void
 hwrtc_init();
 
 struct hwrtc*
 
 void
 hwrtc_init();
 
 struct hwrtc*
-hwrtc_choose();
+hwrtc_alloc_new(char* driver_id);
 
 void
 hwrtc_walltime(datetime_t* dt);
 
 void
 hwrtc_walltime(datetime_t* dt);
index bf0595d7df0a177fdab5562e862cfea20f762860..83ff92c8bc9c3bc75162edb913009071db437ebf 100644 (file)
@@ -1,29 +1,32 @@
 #ifndef __LUNAIX_HWTIMER_H
 #define __LUNAIX_HWTIMER_H
 
 #ifndef __LUNAIX_HWTIMER_H
 #define __LUNAIX_HWTIMER_H
 
+#include <lunaix/device.h>
 #include <lunaix/time.h>
 #include <lunaix/types.h>
 
 typedef void (*timer_tick_cb)();
 
 #include <lunaix/time.h>
 #include <lunaix/types.h>
 
 typedef void (*timer_tick_cb)();
 
-struct hwtimer_context
+struct hwtimer
 {
     char* name;
     void* data;
 
 {
     char* name;
     void* data;
 
-    int (*supported)(struct hwtimer_context*);
-    void (*init)(struct hwtimer_context*, u32_t hertz, timer_tick_cb);
+    struct device* timer_dev;
+
+    int (*supported)(struct hwtimer*);
+    void (*init)(struct hwtimer*, u32_t hertz, timer_tick_cb);
     ticks_t (*systicks)();
     ticks_t base_freq;
     ticks_t running_freq;
 };
 
     ticks_t (*systicks)();
     ticks_t base_freq;
     ticks_t running_freq;
 };
 
-extern struct hwtimer_context* current_timer;
+extern struct hwtimer* current_timer;
 
 void
 hwtimer_init(u32_t hertz, void* tick_callback);
 
 
 void
 hwtimer_init(u32_t hertz, void* tick_callback);
 
-struct hwtimer_context*
+struct hwtimer*
 hwtimer_choose();
 
 ticks_t
 hwtimer_choose();
 
 ticks_t
diff --git a/lunaix-os/includes/hal/rnd.h b/lunaix-os/includes/hal/rnd.h
deleted file mode 100644 (file)
index 1b4a8e3..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef __LUNAIX_RND_H
-#define __LUNAIX_RND_H
-
-#include <lunaix/types.h>
-
-static inline void
-rnd_fill(void* data, size_t len)
-{
-    asm volatile("1:\n"
-                 "rdrand %%eax\n"
-                 "movl %%eax, (%0)\n"
-                 "addl $4, %%eax\n"
-                 "subl $4, %1\n"
-                 "jnz 1b" ::"r"((ptr_t)data),
-                 "r"((len & ~0x3))
-                 : "%eax");
-}
-
-int
-rnd_is_supported();
-
-#endif /* __LUNAIX_RND_H */
index ee56b1da9d9a19592fa0274b5de5c733e87fea32..2634d81dcd076b22f752c1a981decbbb76c35034 100644 (file)
@@ -4,9 +4,18 @@
 #define DEVICE_NAME_SIZE 32
 
 #include <lunaix/ds/hstr.h>
 #define DEVICE_NAME_SIZE 32
 
 #include <lunaix/ds/hstr.h>
+#include <lunaix/ds/ldga.h>
 #include <lunaix/ds/llist.h>
 #include <lunaix/ds/llist.h>
+#include <lunaix/ds/semaphore.h>
 #include <lunaix/types.h>
 
 #include <lunaix/types.h>
 
+/**
+ * @brief Export pseudo device
+ *
+ */
+#define EXPORT_PSEUDODEV(id, init_fn)                                          \
+    export_ldga_el(pseudo_dev, id, ptr_t, init_fn)
+
 #define DEV_STRUCT_MAGIC 0x5645444c
 
 #define DEV_MSKIF 0x00000003
 #define DEV_STRUCT_MAGIC 0x5645444c
 
 #define DEV_MSKIF 0x00000003
@@ -14,6 +23,7 @@
 #define DEV_IFVOL 0x0 // volumetric (block) device
 #define DEV_IFSEQ 0x1 // sequential (character) device
 #define DEV_IFCAT 0x2 // a device category (as device groupping)
 #define DEV_IFVOL 0x0 // volumetric (block) device
 #define DEV_IFSEQ 0x1 // sequential (character) device
 #define DEV_IFCAT 0x2 // a device category (as device groupping)
+#define DEV_IFSYS 0x3 // a system device
 
 typedef unsigned int dev_t;
 
 
 typedef unsigned int dev_t;
 
@@ -23,16 +33,22 @@ struct device
     struct llist_header siblings;
     struct llist_header children;
     struct device* parent;
     struct llist_header siblings;
     struct llist_header children;
     struct device* parent;
+    // TODO investigate event polling
+
     struct hstr name;
     dev_t dev_id;
     int dev_type;
     char name_val[DEVICE_NAME_SIZE];
     void* underlay;
     struct hstr name;
     dev_t dev_id;
     int dev_type;
     char name_val[DEVICE_NAME_SIZE];
     void* underlay;
-    int (*read)(struct device* dev, void* buf, size_t offset, size_t len);
-    int (*write)(struct device* dev, void* buf, size_t offset, size_t len);
-    int (*read_page)(struct device* dev, void* buf, size_t offset);
-    int (*write_page)(struct device* dev, void* buf, size_t offset);
-    int (*exec_cmd)(struct device* dev, u32_t req, va_list args);
+
+    struct
+    {
+        int (*read)(struct device* dev, void* buf, size_t offset, size_t len);
+        int (*write)(struct device* dev, void* buf, size_t offset, size_t len);
+        int (*read_page)(struct device* dev, void* buf, size_t offset);
+        int (*write_page)(struct device* dev, void* buf, size_t offset);
+        int (*exec_cmd)(struct device* dev, u32_t req, va_list args);
+    } ops;
 };
 
 struct device*
 };
 
 struct device*
@@ -42,6 +58,9 @@ device_add(struct device* parent,
            u32_t type,
            va_list args);
 
            u32_t type,
            va_list args);
 
+struct device*
+device_addsys(struct device* parent, void* underlay, char* name_fmt, ...);
+
 struct device*
 device_addseq(struct device* parent, void* underlay, char* name_fmt, ...);
 
 struct device*
 device_addseq(struct device* parent, void* underlay, char* name_fmt, ...);
 
@@ -67,6 +86,6 @@ struct device*
 device_getbyoffset(struct device* root_dev, int pos);
 
 void
 device_getbyoffset(struct device* root_dev, int pos);
 
 void
-device_init_builtin();
+device_install_pseudo();
 
 #endif /* __LUNAIX_DEVICE_H */
 
 #endif /* __LUNAIX_DEVICE_H */
index 76eee9ed33a804690e8338c9f282c88194e6a1dc..9f7008f450247a5050e866bf2ff459248f1e2219 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <lunaix/clock.h>
 #include <lunaix/device.h>
 
 #include <lunaix/clock.h>
 #include <lunaix/device.h>
+#include <lunaix/ds/ldga.h>
 #include <lunaix/ds/llist.h>
 #include <lunaix/ds/waitq.h>
 #include <lunaix/types.h>
 #include <lunaix/ds/llist.h>
 #include <lunaix/ds/waitq.h>
 #include <lunaix/types.h>
@@ -19,6 +20,9 @@
 // vector (e.g. mice wheel scroll, mice maneuver)
 #define PKT_VECTOR 0x3
 
 // vector (e.g. mice wheel scroll, mice maneuver)
 #define PKT_VECTOR 0x3
 
+#define EXPORT_INPUT_DEV(id, init_fn)                                          \
+    export_ldga_el(inputdev, id, ptr_t, init_fn)
+
 struct input_evt_pkt
 {
     u32_t pkt_type;   // packet type
 struct input_evt_pkt
 {
     u32_t pkt_type;   // packet type
index 6dd4a6f09cb0f132a2d48a1cb2ae314b2d2802ff..e9f80b0027371be29e63577edad9c574ea849e81 100644 (file)
@@ -69,4 +69,10 @@ isrm_bindiv(int iv, isr_cb handler);
 isr_cb
 isrm_get(int iv);
 
 isr_cb
 isrm_get(int iv);
 
+ptr_t
+isrm_get_payload(int iv);
+
+void
+isrm_set_payload(int iv, ptr_t);
+
 #endif /* __LUNAIX_ISRM_H */
 #endif /* __LUNAIX_ISRM_H */
index 18d67e0bf3659bae32488122ef6c930aa88d8fc8..e05a6b2ab79d6cf37489cb07df41c00ad972670e 100644 (file)
@@ -5,7 +5,7 @@
 
 #define PILE_NAME_MAXLEN 20
 
 
 #define PILE_NAME_MAXLEN 20
 
-#define PILE_CACHELINE 1
+#define PILE_ALIGN_CACHE 1
 
 struct cake_pile;
 
 
 struct cake_pile;
 
diff --git a/lunaix-os/includes/lunaix/peripheral/ps2kbd.h b/lunaix-os/includes/lunaix/peripheral/ps2kbd.h
deleted file mode 100644 (file)
index a6f2c63..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-#ifndef __LUNAIX_PS2KBD_H
-#define __LUNAIX_PS2KBD_H
-
-#include <lunaix/ds/mutex.h>
-#include <lunaix/keyboard.h>
-
-#define PS2_PORT_ENC_DATA 0x60
-#define PS2_PORT_ENC_CMDREG 0x60
-#define PS2_PORT_CTRL_STATUS 0x64
-#define PS2_PORT_CTRL_CMDREG 0x64
-
-#define PS2_STATUS_OFULL 0x1
-#define PS2_STATUS_IFULL 0x2
-
-#define PS2_RESULT_ACK 0xfa
-#define PS2_RESULT_NAK 0xfe // resend
-#define PS2_RESULT_ECHO 0xee
-#define PS2_RESULT_TEST_OK 0x55
-
-// PS/2 keyboard device related commands
-#define PS2_KBD_CMD_SETLED 0xed
-#define PS2_KBD_CMD_ECHO 0xee
-#define PS2_KBD_CMD_SCANCODE_SET 0xf0
-#define PS2_KBD_CMD_IDENTIFY 0xf2
-#define PS2_KBD_CMD_SCAN_ENABLE 0xf4
-#define PS2_KBD_CMD_SCAN_DISABLE 0xf5
-
-// PS/2 *controller* related commands
-#define PS2_CMD_PORT1_DISABLE 0xad
-#define PS2_CMD_PORT1_ENABLE 0xae
-#define PS2_CMD_PORT2_DISABLE 0xa7
-#define PS2_CMD_PORT2_ENABLE 0xa8
-#define PS2_CMD_SELFTEST 0xaa
-#define PS2_CMD_SELFTEST_PORT1 0xab
-
-#define PS2_CMD_READ_CFG 0x20
-#define PS2_CMD_WRITE_CFG 0x60
-
-#define PS2_CFG_P1INT 0x1
-#define PS2_CFG_P2INT 0x2
-#define PS2_CFG_TRANSLATION 0x40
-
-#define PS2_DELAY 1000
-
-#define PS2_CMD_QUEUE_SIZE 8
-
-#define PS2_NO_ARG 0xff00
-
-struct ps2_cmd
-{
-    char cmd;
-    char arg;
-};
-
-struct ps2_kbd_state
-{
-    volatile char state;
-    volatile char masked;
-    volatile kbd_kstate_t key_state;
-    kbd_keycode_t* translation_table;
-};
-
-struct ps2_cmd_queue
-{
-    struct ps2_cmd cmd_queue[PS2_CMD_QUEUE_SIZE];
-    int queue_ptr;
-    int queue_len;
-    mutex_t mutex;
-};
-
-/**
- * @brief 向PS/2控制器的控制端口(0x64)发送指令并等待返回代码。
- * 注意,对于没有返回代码的命令请使用`ps2_post_cmd`,否则会造成死锁。
- * 通过调用该方法向控制器发送指令,请区别 ps2_issue_dev_cmd
- *
- * @param cmd
- * @param args
- */
-static u8_t
-ps2_issue_cmd(char cmd, u16_t arg);
-
-/**
- * @brief 向PS/2控制器的编码器端口(0x60)发送指令并等待返回代码。
- * 注意,对于没有返回代码的命令请使用`ps2_post_cmd`,否则会造成死锁。
- * 通过调用该方法向PS/2设备发送指令,请区别 ps2_issue_cmd
- *
- * @param cmd
- * @param args
- */
-static u8_t
-ps2_issue_dev_cmd(char cmd, u16_t arg);
-
-/**
- * @brief 向PS/2控制器发送指令,不等待返回代码。
- *
- * @param port 端口号
- * @param cmd
- * @param args
- * @return char
- */
-static void
-ps2_post_cmd(u8_t port, char cmd, u16_t arg);
-
-void
-ps2_device_post_cmd(char cmd, char arg);
-
-void
-ps2_kbd_init();
-
-void
-ps2_process_cmd(void* arg);
-
-#endif /* __LUNAIX_PS2KBD_H */
index 7be48e79356e86a9c00fe4b40c3265e960045618..9ca8cad3f648564379a0d820895f91fc38ad40d2 100644 (file)
 #define TIOCCLSBUF IOREQ(2, 0)
 #define TIOCFLUSH IOREQ(3, 0)
 
 #define TIOCCLSBUF IOREQ(2, 0)
 #define TIOCFLUSH IOREQ(3, 0)
 
+#define RTCIO_IUNMSK IOREQ(1, 0)
+#define RTCIO_IMSK IOREQ(2, 0)
+#define RTCIO_SETFREQ IOREQ(3, 1)
+#define RTCIO_GETINFO IOREQ(4, 1)
+#define RTCIO_SETDT IOREQ(5, 1)
+
+#define TIMERIO_GETINFO IOREQ(1, 0)
+
 #endif /* __LUNAIX_IOCTL_DEFS_H */
 #endif /* __LUNAIX_IOCTL_DEFS_H */
index 0bc977df9ea901f4801ca66cd120a9f6e3665a8a..3eee27727008917155ab72366fa70dd1e1ac2115 100644 (file)
@@ -31,7 +31,7 @@ blkpart_parse(struct device* master, struct gpt_header* header)
 
     for (size_t i = 0; i < header->ents_len; i++) {
         if (!(i % ENT_PER_BLK)) {
 
     for (size_t i = 0; i < header->ents_len; i++) {
         if (!(i % ENT_PER_BLK)) {
-            errno = master->read(
+            errno = master->ops.read(
               master, ents_parial, LBA2OFF(ent_lba++), GPT_BLKSIZE);
             if (errno < 0) {
                 goto done;
               master, ents_parial, LBA2OFF(ent_lba++), GPT_BLKSIZE);
             if (errno < 0) {
                 goto done;
@@ -70,7 +70,8 @@ blkpart_probegpt(struct device* master)
     int errno;
     struct gpt_header* gpt_hdr = (struct gpt_header*)valloc(GPT_BLKSIZE);
 
     int errno;
     struct gpt_header* gpt_hdr = (struct gpt_header*)valloc(GPT_BLKSIZE);
 
-    if ((errno = master->read(master, gpt_hdr, LBA2OFF(1), LBA2OFF(1))) < 0) {
+    if ((errno = master->ops.read(master, gpt_hdr, LBA2OFF(1), LBA2OFF(1))) <
+        0) {
         goto done;
     }
 
         goto done;
     }
 
index c4e29e191e0b0df376fc0ed0767998e2ff8ca439..460e94bf3c4690394b4bf2240113ace6ae5a5397 100644 (file)
@@ -320,10 +320,10 @@ __block_register(struct block_dev* bdev)
 
     struct device* dev =
       device_addvol(blk_parent_dev, bdev, "sd%c", 'a' + free_slot);
 
     struct device* dev =
       device_addvol(blk_parent_dev, bdev, "sd%c", 'a' + free_slot);
-    dev->write = __block_write;
-    dev->write_page = __block_write_page;
-    dev->read = __block_read;
-    dev->read_page = __block_read_page;
+    dev->ops.write = __block_write;
+    dev->ops.write_page = __block_write_page;
+    dev->ops.read = __block_read;
+    dev->ops.read_page = __block_read_page;
 
     bdev->dev = dev;
     strcpy(bdev->bdev_id, dev->name_val);
 
     bdev->dev = dev;
     strcpy(bdev->bdev_id, dev->name_val);
@@ -343,10 +343,10 @@ blk_mount_part(struct block_dev* bdev,
 
     struct device* dev =
       device_addvol(NULL, pbdev, "%sp%d", bdev->bdev_id, index + 1);
 
     struct device* dev =
       device_addvol(NULL, pbdev, "%sp%d", bdev->bdev_id, index + 1);
-    dev->write = __block_write;
-    dev->write_page = __block_write_page;
-    dev->read = __block_read;
-    dev->read_page = __block_read_page;
+    dev->ops.write = __block_write;
+    dev->ops.write_page = __block_write_page;
+    dev->ops.read = __block_read;
+    dev->ops.read_page = __block_read_page;
 
     pbdev->start_lba = start_lba;
     pbdev->end_lba = end_lba;
 
     pbdev->start_lba = start_lba;
     pbdev->end_lba = end_lba;
diff --git a/lunaix-os/kernel/device/builtin/devbuiltin.c b/lunaix-os/kernel/device/builtin/devbuiltin.c
deleted file mode 100644 (file)
index 5c7b9b1..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <lunaix/device.h>
-
-extern void
-devbuiltin_init_rand();
-
-extern void
-devbuiltin_init_null();
-
-void
-device_init_builtin()
-{
-    devbuiltin_init_null();
-    devbuiltin_init_rand();
-}
\ No newline at end of file
diff --git a/lunaix-os/kernel/device/builtin/devrand.c b/lunaix-os/kernel/device/builtin/devrand.c
deleted file mode 100644 (file)
index bce0f3a..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#include <hal/rnd.h>
-#include <lunaix/device.h>
-#include <lunaix/mm/page.h>
-#include <lunaix/syslog.h>
-
-LOG_MODULE("rand")
-
-int
-__rand_rd_pg(struct device* dev, void* buf, size_t offset)
-{
-    // rnd_fill(buf, PG_SIZE);
-    return PG_SIZE;
-}
-
-int
-__rand_rd(struct device* dev, void* buf, size_t offset, size_t len)
-{
-    // rnd_fill(buf, len);
-    return len;
-}
-
-void
-devbuiltin_init_rand()
-{
-    // TODO rnd device need better abstraction
-    if (1) {
-        kprintf(KWARN "not supported.\n");
-        return;
-    }
-    struct device* devrand = device_addseq(NULL, NULL, "rand");
-    devrand->read = __rand_rd;
-    devrand->read_page = __rand_rd_pg;
-}
\ No newline at end of file
index fdb8b4720d9b705282954e4003b653d6ce0c92a3..2951456ce54a681bf8c9149a878390ee5da3c170 100644 (file)
@@ -15,11 +15,11 @@ devfs_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
 
     struct device* dev = (struct device*)inode->data;
 
 
     struct device* dev = (struct device*)inode->data;
 
-    if (!dev->read) {
+    if (!dev->ops.read) {
         return ENOTSUP;
     }
 
         return ENOTSUP;
     }
 
-    return dev->read(dev, buffer, fpos, len);
+    return dev->ops.read(dev, buffer, fpos, len);
 }
 
 int
 }
 
 int
@@ -29,11 +29,11 @@ devfs_write(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
 
     struct device* dev = (struct device*)inode->data;
 
 
     struct device* dev = (struct device*)inode->data;
 
-    if (!dev->write) {
+    if (!dev->ops.write) {
         return ENOTSUP;
     }
 
         return ENOTSUP;
     }
 
-    return dev->write(dev, buffer, fpos, len);
+    return dev->ops.write(dev, buffer, fpos, len);
 }
 
 int
 }
 
 int
@@ -43,11 +43,11 @@ devfs_read_page(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
 
     struct device* dev = (struct device*)inode->data;
 
 
     struct device* dev = (struct device*)inode->data;
 
-    if (!dev->read_page) {
+    if (!dev->ops.read_page) {
         return ENOTSUP;
     }
 
         return ENOTSUP;
     }
 
-    return dev->read_page(dev, buffer, fpos);
+    return dev->ops.read_page(dev, buffer, fpos);
 }
 
 int
 }
 
 int
@@ -57,11 +57,11 @@ devfs_write_page(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
 
     struct device* dev = (struct device*)inode->data;
 
 
     struct device* dev = (struct device*)inode->data;
 
-    if (!dev->read_page) {
+    if (!dev->ops.read_page) {
         return ENOTSUP;
     }
 
         return ENOTSUP;
     }
 
-    return dev->read_page(dev, buffer, fpos);
+    return dev->ops.read_page(dev, buffer, fpos);
 }
 
 int
 }
 
 int
index 3647f10a87f778395cb4efba6f4080b622cd0f63..979b461b86184a8c1bcdfa18f3ce0f0505f094a1 100644 (file)
@@ -44,6 +44,19 @@ device_add(struct device* parent,
     return dev;
 }
 
     return dev;
 }
 
+struct device*
+device_addsys(struct device* parent, void* underlay, char* name_fmt, ...)
+{
+    va_list args;
+    va_start(args, name_fmt);
+
+    struct device* dev =
+      device_add(parent, underlay, name_fmt, DEV_IFSEQ, args);
+
+    va_end(args);
+    return dev;
+}
+
 struct device*
 device_addseq(struct device* parent, void* underlay, char* name_fmt, ...)
 {
 struct device*
 device_addseq(struct device* parent, void* underlay, char* name_fmt, ...)
 {
@@ -157,12 +170,12 @@ __DEFINE_LXSYSCALL3(int, ioctl, int, fd, int, req, va_list, args)
         goto done;
     }
 
         goto done;
     }
 
-    if (!dev->exec_cmd) {
-        errno = EINVAL;
+    if (!dev->ops.exec_cmd) {
+        errno = ENOTSUP;
         goto done;
     }
 
         goto done;
     }
 
-    errno = dev->exec_cmd(dev, req, args);
+    errno = dev->ops.exec_cmd(dev, req, args);
 
 done:
     return DO_STATUS_OR_RETURN(errno);
 
 done:
     return DO_STATUS_OR_RETURN(errno);
index bf4c157039399af5124d2e579e6cd846418c45f7..0680fefebe7be56c4992f3a6dc06945325825902 100644 (file)
@@ -15,6 +15,13 @@ void
 input_init()
 {
     input_devcat = device_addcat(NULL, "input");
 input_init()
 {
     input_devcat = device_addcat(NULL, "input");
+
+    int i;
+    ptr_t input_dev_init;
+    ldga_foreach(inputdev, ptr_t, i, input_dev_init)
+    {
+        ((void (*)())input_dev_init)();
+    }
 }
 
 void
 }
 
 void
@@ -84,8 +91,8 @@ input_add_device(char* name_fmt, ...)
       device_add(input_devcat, idev, name_fmt, DEV_IFSEQ, args);
 
     idev->dev_if = dev;
       device_add(input_devcat, idev, name_fmt, DEV_IFSEQ, args);
 
     idev->dev_if = dev;
-    dev->read = __input_dev_read;
-    dev->read_page = __input_dev_read_pg;
+    dev->ops.read = __input_dev_read;
+    dev->ops.read_page = __input_dev_read_pg;
 
     va_end(args);
 
 
     va_end(args);
 
similarity index 66%
rename from lunaix-os/kernel/device/builtin/devnull.c
rename to lunaix-os/kernel/device/pseudo/devnull.c
index 6f0b4a064fc8d25ed1a9c018e0241816e941aff0..3e82bba9c5e8afd5cb52e16798b2bfcda607feec 100644 (file)
@@ -1,28 +1,28 @@
 #include <lunaix/device.h>
 #include <lunaix/mm/page.h>
 
 #include <lunaix/device.h>
 #include <lunaix/mm/page.h>
 
-int
+static int
 __null_wr_pg(struct device* dev, void* buf, size_t offset)
 {
     // do nothing
     return PG_SIZE;
 }
 
 __null_wr_pg(struct device* dev, void* buf, size_t offset)
 {
     // do nothing
     return PG_SIZE;
 }
 
-int
+static int
 __null_wr(struct device* dev, void* buf, size_t offset, size_t len)
 {
     // do nothing
     return len;
 }
 
 __null_wr(struct device* dev, void* buf, size_t offset, size_t len)
 {
     // do nothing
     return len;
 }
 
-int
+static int
 __null_rd_pg(struct device* dev, void* buf, size_t offset)
 {
     // do nothing
     return 0;
 }
 
 __null_rd_pg(struct device* dev, void* buf, size_t offset)
 {
     // do nothing
     return 0;
 }
 
-int
+static int
 __null_rd(struct device* dev, void* buf, size_t offset, size_t len)
 {
     // do nothing
 __null_rd(struct device* dev, void* buf, size_t offset, size_t len)
 {
     // do nothing
@@ -30,11 +30,12 @@ __null_rd(struct device* dev, void* buf, size_t offset, size_t len)
 }
 
 void
 }
 
 void
-devbuiltin_init_null()
+pdev_nulldev_init()
 {
     struct device* devnull = device_addseq(NULL, NULL, "null");
 {
     struct device* devnull = device_addseq(NULL, NULL, "null");
-    devnull->write_page = __null_wr_pg;
-    devnull->write = __null_wr;
-    devnull->read_page = __null_rd_pg;
-    devnull->read = __null_rd;
-}
\ No newline at end of file
+    devnull->ops.write_page = __null_wr_pg;
+    devnull->ops.write = __null_wr;
+    devnull->ops.read_page = __null_rd_pg;
+    devnull->ops.read = __null_rd;
+}
+EXPORT_PSEUDODEV(nulldev, pdev_nulldev_init);
\ No newline at end of file
diff --git a/lunaix-os/kernel/device/pseudo/devpseudo.c b/lunaix-os/kernel/device/pseudo/devpseudo.c
new file mode 100644 (file)
index 0000000..45ee4a4
--- /dev/null
@@ -0,0 +1,18 @@
+#include <lunaix/device.h>
+
+extern void
+devbuiltin_init_rand();
+
+extern void
+devbuiltin_init_null();
+
+void
+device_install_pseudo()
+{
+    ptr_t pdev_init_fn;
+    int index;
+    ldga_foreach(pseudo_dev, ptr_t, index, pdev_init_fn)
+    {
+        ((void (*)())pdev_init_fn)();
+    }
+}
\ No newline at end of file
index 5a06fc8b39eab5308d975ee4565359e0d0a6e530..770cd50c078c93b73bb063243fb8dc51a3bbeff8 100644 (file)
@@ -88,7 +88,8 @@ iso9660_setup_dnode(struct v_dnode* dnode, struct v_inode* inode)
     do {
         if (blk_offset >= ISO9660_BLKSZ - sizeof(struct iso_drecord)) {
             current_pos += ISO9660_BLKSZ;
     do {
         if (blk_offset >= ISO9660_BLKSZ - sizeof(struct iso_drecord)) {
             current_pos += ISO9660_BLKSZ;
-            errno = dev->read(dev, records, blk + current_pos, ISO9660_BLKSZ);
+            errno =
+              dev->ops.read(dev, records, blk + current_pos, ISO9660_BLKSZ);
             if (errno < 0) {
                 errno = EIO;
                 goto done;
             if (errno < 0) {
                 errno = EIO;
                 goto done;
index 34d3b47fcf7cfffa091e4791dc53dc9b5a29a9c3..f07f56036258fa14568af053a78ffd458480dcdb 100644 (file)
@@ -54,7 +54,7 @@ iso9660_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
     int errno = 0;
     while (fu_to_read) {
         for (; sec < isoino->fu_size && i < len; sec++) {
     int errno = 0;
     while (fu_to_read) {
         for (; sec < isoino->fu_size && i < len; sec++) {
-            errno = bdev->read(
+            errno = bdev->ops.read(
               bdev, rd_buffer, true_offset * ISO9660_BLKSZ, ISO9660_BLKSZ);
 
             if (errno < 0) {
               bdev, rd_buffer, true_offset * ISO9660_BLKSZ, ISO9660_BLKSZ);
 
             if (errno < 0) {
index fa3337b88f5d993f9d4dc3e6907b4d1f1ed3ba69..3b53b5c31dd49c2961c8e84a6919a72fa2c451a7 100644 (file)
@@ -76,8 +76,8 @@ iso9660_fill_inode(struct v_inode* inode, struct iso_drecache* dir, int ino)
     if (dir->xattr_len) {
         struct iso_xattr* xattr = (struct iso_xattr*)valloc(ISO9660_BLKSZ);
         // Only bring in single FU, as we only care about the attributes.
     if (dir->xattr_len) {
         struct iso_xattr* xattr = (struct iso_xattr*)valloc(ISO9660_BLKSZ);
         // Only bring in single FU, as we only care about the attributes.
-        errno =
-          dev->read(dev, xattr, ISO9660_BLKSZ * inode->lb_addr, ISO9660_BLKSZ);
+        errno = dev->ops.read(
+          dev, xattr, ISO9660_BLKSZ * inode->lb_addr, ISO9660_BLKSZ);
         if (errno < 0) {
             return EIO;
         }
         if (errno < 0) {
             return EIO;
         }
index 724128f592c292cf389b17390831bff05201e631..19895609567b4647c1ea204e1ae21883b41465cd 100644 (file)
@@ -27,7 +27,7 @@ iso9660_mount(struct v_superblock* vsb, struct v_dnode* mount_point)
     u32_t lba = 16;
     int errno = 0;
     do {
     u32_t lba = 16;
     int errno = 0;
     do {
-        errno = dev->read(dev, vdesc, ISO9660_BLKSZ * lba, ISO9660_BLKSZ);
+        errno = dev->ops.read(dev, vdesc, ISO9660_BLKSZ * lba, ISO9660_BLKSZ);
         if (errno < 0) {
             errno = EIO;
             goto done;
         if (errno < 0) {
             errno = EIO;
             goto done;
index d3e871eadc9e0ae831c3673e96d2366b2cedbca7..f1969bd524473f225a9beffa0c3b6d411f8053ea 100644 (file)
@@ -19,22 +19,50 @@ __pcache_try_evict(struct lru_node* obj)
     return 1;
 }
 
     return 1;
 }
 
+static void
+pcache_free_page(void* va)
+{
+    ptr_t pa = vmm_del_mapping(VMS_SELF, (ptr_t)va);
+    pmm_free_page(KERNEL_PID, pa);
+}
+
+static void*
+pcache_alloc_page()
+{
+    int i = 0;
+    ptr_t pp = pmm_alloc_page(KERNEL_PID, 0), va = 0;
+
+    if (!pp) {
+        return NULL;
+    }
+
+    if (!(va = (ptr_t)vmap(pp, PG_SIZE, PG_PREM_RW, 0))) {
+        pmm_free_page(KERNEL_PID, pp);
+        return NULL;
+    }
+
+    return (void*)va;
+}
+
 void
 pcache_init(struct pcache* pcache)
 {
     btrie_init(&pcache->tree, PG_SIZE_BITS);
     llist_init_head(&pcache->dirty);
     llist_init_head(&pcache->pages);
 void
 pcache_init(struct pcache* pcache)
 {
     btrie_init(&pcache->tree, PG_SIZE_BITS);
     llist_init_head(&pcache->dirty);
     llist_init_head(&pcache->pages);
+
     pcache_zone = lru_new_zone(__pcache_try_evict);
 }
 
 void
 pcache_release_page(struct pcache* pcache, struct pcache_pg* page)
 {
     pcache_zone = lru_new_zone(__pcache_try_evict);
 }
 
 void
 pcache_release_page(struct pcache* pcache, struct pcache_pg* page)
 {
-    vfree(page->pg);
+    pcache_free_page(page->pg);
 
     llist_delete(&page->pg_list);
 
 
     llist_delete(&page->pg_list);
 
+    btrie_remove(&pcache->tree, page->fpos);
+
     vfree(page);
 
     pcache->n_pages--;
     vfree(page);
 
     pcache->n_pages--;
@@ -44,7 +72,7 @@ struct pcache_pg*
 pcache_new_page(struct pcache* pcache, u32_t index)
 {
     struct pcache_pg* ppg = vzalloc(sizeof(struct pcache_pg));
 pcache_new_page(struct pcache* pcache, u32_t index)
 {
     struct pcache_pg* ppg = vzalloc(sizeof(struct pcache_pg));
-    void* pg = valloc(PG_SIZE);
+    void* pg = pcache_alloc_page();
 
     if (!ppg || !pg) {
         lru_evict_one(pcache_zone);
 
     if (!ppg || !pg) {
         lru_evict_one(pcache_zone);
@@ -52,7 +80,7 @@ pcache_new_page(struct pcache* pcache, u32_t index)
             return NULL;
         }
 
             return NULL;
         }
 
-        if (!pg && !(pg = valloc(PG_SIZE))) {
+        if (!pg && !(pg = pcache_alloc_page())) {
             return NULL;
         }
     }
             return NULL;
         }
     }
@@ -100,27 +128,33 @@ pcache_get_page(struct pcache* pcache,
 int
 pcache_write(struct v_inode* inode, void* data, u32_t len, u32_t fpos)
 {
 int
 pcache_write(struct v_inode* inode, void* data, u32_t len, u32_t fpos)
 {
+    int errno = 0;
     u32_t pg_off, buf_off = 0;
     struct pcache* pcache = inode->pg_cache;
     struct pcache_pg* pg;
 
     while (buf_off < len) {
     u32_t pg_off, buf_off = 0;
     struct pcache* pcache = inode->pg_cache;
     struct pcache_pg* pg;
 
     while (buf_off < len) {
+        u32_t wr_bytes = MIN(PG_SIZE - pg_off, len - buf_off);
+
         pcache_get_page(pcache, fpos, &pg_off, &pg);
         pcache_get_page(pcache, fpos, &pg_off, &pg);
-        if (!pg) {
-            return ENOMEM;
-        }
 
 
-        u32_t wr_bytes = MIN(PG_SIZE - pg_off, len - buf_off);
-        memcpy(pg->pg + pg_off, (data + buf_off), wr_bytes);
+        if (!pg) {
+            errno = inode->default_fops->write(inode, data, wr_bytes, fpos);
+            if (errno < 0) {
+                break;
+            }
+        } else {
+            memcpy(pg->pg + pg_off, (data + buf_off), wr_bytes);
+            pcache_set_dirty(pcache, pg);
 
 
-        pcache_set_dirty(pcache, pg);
+            pg->len = pg_off + wr_bytes;
+        }
 
 
-        pg->len = pg_off + wr_bytes;
         buf_off += wr_bytes;
         fpos += wr_bytes;
     }
 
         buf_off += wr_bytes;
         fpos += wr_bytes;
     }
 
-    return buf_off;
+    return errno < 0 ? errno : (int)buf_off;
 }
 
 int
 }
 
 int
@@ -132,23 +166,28 @@ pcache_read(struct v_inode* inode, void* data, u32_t len, u32_t fpos)
     struct pcache_pg* pg;
 
     while (buf_off < len) {
     struct pcache_pg* pg;
 
     while (buf_off < len) {
-        if (pcache_get_page(pcache, fpos, &pg_off, &pg)) {
-
-            if (!pg) {
-                return ENOMEM;
-            }
-
+        int new_page = pcache_get_page(pcache, fpos, &pg_off, &pg);
+        if (new_page) {
             // Filling up the page
             errno =
               inode->default_fops->read_page(inode, pg->pg, PG_SIZE, pg->fpos);
             // Filling up the page
             errno =
               inode->default_fops->read_page(inode, pg->pg, PG_SIZE, pg->fpos);
-            if (errno >= 0 && errno < PG_SIZE) {
+
+            if (errno < 0) {
+                break;
+            }
+            if (errno < PG_SIZE) {
                 // EOF
                 len = MIN(len, buf_off + errno);
                 // EOF
                 len = MIN(len, buf_off + errno);
-            } else if (errno < 0) {
-                break;
             }
             }
+
             pg->len = errno;
             pg->len = errno;
+        } else if (!pg) {
+            errno = inode->default_fops->read_page(
+              inode, (data + buf_off), len - buf_off, pg->fpos);
+            buf_off = len;
+            break;
         }
         }
+
         u32_t rd_bytes = MIN(pg->len - pg_off, len - buf_off);
 
         if (!rd_bytes)
         u32_t rd_bytes = MIN(pg->len - pg_off, len - buf_off);
 
         if (!rd_bytes)
index 69af61e5ea65aff0371225140f1e2cd0c99f98a1..4f38c6ac90cc2d93c250c7171db3e708de5e8e19 100644 (file)
@@ -21,7 +21,7 @@ probe_boot_medium()
     llist_for_each(pos, n, &block_cat->children, siblings)
     {
         int errno =
     llist_for_each(pos, n, &block_cat->children, siblings)
     {
         int errno =
-          pos->read(pos, (void*)volp, ISO9660_READ_OFF, ISO9660_BLKSZ);
+          pos->ops.read(pos, (void*)volp, ISO9660_READ_OFF, ISO9660_BLKSZ);
         if (errno < 0) {
             kprintf(KWARN "can not probe %x:%s (%d)\n",
                     pos->dev_id,
         if (errno < 0) {
             kprintf(KWARN "can not probe %x:%s (%d)\n",
                     pos->dev_id,
index 6b6e5e48193d99d5abc2f772b15fdd519e74081e..046054472f7b97d74005ca846c0efa5c41e30085 100644 (file)
@@ -64,7 +64,6 @@ kernel_bootstrap(struct boot_handoff* bhctx)
     /* Let's get fs online as soon as possible, as things rely on them */
     vfs_init();
     fsm_init();
     /* Let's get fs online as soon as possible, as things rely on them */
     vfs_init();
     fsm_init();
-    input_init();
 
     /* Get intc online, this is the cornerstone when initing devices */
     intc_init();
 
     /* Get intc online, this is the cornerstone when initing devices */
     intc_init();
@@ -73,6 +72,7 @@ kernel_bootstrap(struct boot_handoff* bhctx)
     clock_init();
     timer_init();
 
     clock_init();
     timer_init();
 
+    input_init();
     block_init();
 
     /* the bare metal are now happy, let's get software over with */
     block_init();
 
     /* the bare metal are now happy, let's get software over with */
@@ -89,7 +89,7 @@ kernel_bootstrap(struct boot_handoff* bhctx)
     vfs_mount("/task", "taskfs", NULL, MNT_RO);
 
     lxconsole_spawn_ttydev();
     vfs_mount("/task", "taskfs", NULL, MNT_RO);
 
     lxconsole_spawn_ttydev();
-    device_init_builtin();
+    device_install_pseudo();
 
     /* Finish up bootstrapping sequence, we are ready to spawn the root process
      * and start geting into uspace
 
     /* Finish up bootstrapping sequence, we are ready to spawn the root process
      * and start geting into uspace
index 0e8f3341c5b8a95a23e47ba7925015aa1d0ab8b5..2a70ab76d823f7d09d6d62cbc08bc6e70f70372b 100644 (file)
@@ -77,7 +77,7 @@ __init_pile(struct cake_pile* pile,
     unsigned int offset = sizeof(long);
 
     // 默认每块儿蛋糕对齐到地址总线宽度
     unsigned int offset = sizeof(long);
 
     // 默认每块儿蛋糕对齐到地址总线宽度
-    if ((options & PILE_CACHELINE)) {
+    if ((options & PILE_ALIGN_CACHE)) {
         // 对齐到128字节缓存行大小,主要用于DMA
         offset = CACHE_LINE_SIZE;
     }
         // 对齐到128字节缓存行大小,主要用于DMA
         offset = CACHE_LINE_SIZE;
     }
index b7557ae0e8ab9b1e88b427ff6ec0d50dcb66a36f..58e57b9b7e41bff86b60ec489730420db296f538 100644 (file)
@@ -31,7 +31,7 @@ valloc_init()
     for (size_t i = 0; i < CLASS_LEN(piles_names_dma); i++) {
         int size = 1 << (i + 7);
         piles_dma[i] = cake_new_pile(
     for (size_t i = 0; i < CLASS_LEN(piles_names_dma); i++) {
         int size = 1 << (i + 7);
         piles_dma[i] = cake_new_pile(
-          piles_names_dma[i], size, size > 1024 ? 4 : 1, PILE_CACHELINE);
+          piles_names_dma[i], size, size > 1024 ? 4 : 1, PILE_ALIGN_CACHE);
     }
 }
 
     }
 }
 
index 3c7b2254484a871e184530cf7e1853fd94a7b129..c7501af0e733c0769a23cd95fd2267d0dbfe9bd5 100644 (file)
@@ -10,7 +10,6 @@
 #include <lunaix/mm/pmm.h>
 #include <lunaix/mm/valloc.h>
 #include <lunaix/mm/vmm.h>
 #include <lunaix/mm/pmm.h>
 #include <lunaix/mm/valloc.h>
 #include <lunaix/mm/vmm.h>
-#include <lunaix/peripheral/ps2kbd.h>
 #include <lunaix/peripheral/serial.h>
 #include <lunaix/spike.h>
 #include <lunaix/syscall.h>
 #include <lunaix/peripheral/serial.h>
 #include <lunaix/spike.h>
 #include <lunaix/syscall.h>
@@ -111,9 +110,6 @@ init_platform()
     serial_init();
     sdbg_init();
 
     serial_init();
     sdbg_init();
 
-    // FIXME ps2 kbd is a device, must not be here
-    ps2_kbd_init();
-
     // console
     console_start_flushing();
     console_flush();
     // console
     console_start_flushing();
     console_flush();
index 2dc4e8153359fc91c3137db86021b1bd86b457ee..be6b21ba3c61ed3a442345b7e32233f828d81498 100644 (file)
@@ -75,5 +75,5 @@ clock_systime()
 void
 clock_walltime(datetime_t* datetime)
 {
 void
 clock_walltime(datetime_t* datetime)
 {
-    current_rtc->get_walltime(current_rtc, datetime);
+    primary_rtc->get_walltime(primary_rtc, datetime);
 }
\ No newline at end of file
 }
\ No newline at end of file
index 67961b52def89799344dcf4b689e1307d4a7f65b..8d0747dda601c905c67a8ff4c863705ddd22a944 100644 (file)
@@ -150,11 +150,11 @@ void
 lxconsole_spawn_ttydev()
 {
     struct device* tty_dev = device_addseq(NULL, &lx_console, "tty");
 lxconsole_spawn_ttydev()
 {
     struct device* tty_dev = device_addseq(NULL, &lx_console, "tty");
-    tty_dev->write = __tty_write;
-    tty_dev->write_page = __tty_write_pg;
-    tty_dev->read = __tty_read;
-    tty_dev->read_page = __tty_read_pg;
-    tty_dev->exec_cmd = __tty_exec_cmd;
+    tty_dev->ops.write = __tty_write;
+    tty_dev->ops.write_page = __tty_write_pg;
+    tty_dev->ops.read = __tty_read;
+    tty_dev->ops.read_page = __tty_read_pg;
+    tty_dev->ops.exec_cmd = __tty_exec_cmd;
 
     waitq_init(&lx_reader);
     input_add_listener(__lxconsole_listener);
 
     waitq_init(&lx_reader);
     input_add_listener(__lxconsole_listener);
index f2510aa5194872677889770b26b1fcbc5c0c551c..52ce3eb6c2d9147951751f3c9a4bfc37d7f045d0 100644 (file)
@@ -80,11 +80,31 @@ SECTIONS {
 
         . = ALIGN(8);
 
 
         . = ALIGN(8);
 
-        PROVIDE(__lga_platdev_db_start = .);
+        PROVIDE(__lga_rtcdev_start = .);
         
         
-        KEEP(*(.lga.platdev_db));
+        KEEP(*(.lga.rtcdev));
 
 
-        PROVIDE(__lga_platdev_db_end = .);
+        PROVIDE(__lga_rtcdev_end = .);
+
+        /* ---- */
+
+        . = ALIGN(8);
+
+        PROVIDE(__lga_inputdev_start = .);
+        
+        KEEP(*(.lga.inputdev));
+
+        PROVIDE(__lga_inputdev_end = .);
+
+        /* ---- */
+
+        . = ALIGN(8);
+
+        PROVIDE(__lga_pseudo_dev_start = .);
+        
+        KEEP(*(.lga.pseudo_dev));
+
+        PROVIDE(__lga_pseudo_dev_end = .);
     }
 
     .bss BLOCK(4K) : AT ( ADDR(.bss) - 0xC0000000 ) {
     }
 
     .bss BLOCK(4K) : AT ( ADDR(.bss) - 0xC0000000 ) {