asm("wbinvd\n");
 }
 
-void __attribute__ ((regparm(0))) generate_gpf(void);
-
-/* segment 0x70 is an arbitrary segment which does not exist */
-asm(".globl generate_gpf\n"
-       ".hidden generate_gpf\n"
-       ".type generate_gpf, @function\n"
-       "generate_gpf:\n"
-       "ljmp   $0x70, $0x47114711\n");
-
 __weak void reset_cpu(ulong addr)
 {
-       printf("Resetting using x86 Triple Fault\n");
-       set_vector(13, generate_gpf);   /* general protection fault handler */
-       set_vector(8, generate_gpf);    /* double fault handler */
-       generate_gpf();                 /* start the show */
+       /* Do a hard reset through the chipset's reset control register */
+       outb(SYS_RST | RST_CPU, PORT_RESET);
+       for (;;)
+               cpu_hlt();
+}
+
+void x86_full_reset(void)
+{
+       outb(FULL_RST | SYS_RST | RST_CPU, PORT_RESET);
 }
 
 int dcache_status(void)
 
 
 #ifndef __ASSEMBLY__
 
+/*
+ * This register is documented in (for example) the Intel Atom Processor E3800
+ * Product Family Datasheet in "PCU - Power Management Controller (PMC)".
+ *
+ * RST_CNT: Reset Control Register (RST_CNT) Offset cf9.
+ *
+ * The naming follows Intel's naming.
+ */
 #define PORT_RESET             0xcf9
 
+enum {
+       SYS_RST         = 1 << 1,       /* 0 for soft reset, 1 for hard reset */
+       RST_CPU         = 1 << 2,       /* initiate reset */
+       FULL_RST        = 1 << 3,       /* full power cycle */
+};
+
+/**
+ * x86_full_reset() - reset everything: perform a full power cycle
+ */
+void x86_full_reset(void);
+
 static inline __attribute__((always_inline)) void cpu_hlt(void)
 {
        asm("hlt");